Teach you develop a webpack loader

In simple terms loader is to allow other types of files into a piece of code js code webpack can understand (function)

Out of the box, webpack only understands JavaScript files. Loaders allow webpack to process other types of files and converting them into valid modules that can be consumed by your application and added to the dependency graph.、

In your application, there are three ways to use the loader:
  • Configuration (recommended): Specifies the loader in webpack.config.js file.
  • Inline: loader explicitly specified in each import statement.
  • CLI: specify them in the shell command.

Configuration

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }

Inline

import Styles from 'style-loader!css-loader?modules!./styles.css';
Query parameter options may be passed, for example, key = value & foo = bar, or a JSON object, for example,?? { "Key": "value", "foo": "bar"}.

CLI

webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
.Jade file will use jade-loader, using a style-loader and css-loader for .css file.

 
So how do you write a webpack-loader it? Official Guide , the following will take you with a handwritten webpack-loader?
Requirements are as follows:
We write one pair txt file [name] to replace the 17, very simply as follows:
//src/loader.js
const {getOptions} = require('loader-utils')

module.exports = function (source){
    const options = getOptions(this);
    console.log(source);
    source = source.replace(/\[name\]/g, options.name);
    console.log(source);
    return `export default ${JSON.stringify(source)}`
}
//webpack.config.js配置

const path = require('path')

module.exports = {
    mode:'development',
    context: __dirname,
    entry: `./src/test.txt`,
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.txt'
    },
    module: {
        rules: [
            {
                test: /\.txt$/,
                use: [
                    {
                        loader: path.resolve(__dirname, './src/bar-loader.js'),
                        options: {
                            name: '18hahaha'
                        }
                    },
                    {
                        loader: path.resolve(__dirname, './src/loader.js'),
                        options: {
                            name: '17'
                        }
                    }
                ]
            }
        ]
    }
}
 

So how to write a loader for use with existing loader it?

Then write:
//src/bar-loader.js

const { getOptions } = require('loader-utils')

module.exports = function (source) {
    const options = getOptions(this);
    console.log(11111,source);
    source = source.replace(/17/g, options.name);
    console.log(11111, source);
    return `export default ${JSON.stringify(source)}`
}

 

//webpack.config.js
rules: [
            {
                test: /\.txt$/,
                use: [
                    {
                        loader: path.resolve(__dirname, './src/bar-loader.js'),
                        options: {
                            name: '18hahaha'
                        }
                    },
                    {
                        loader: path.resolve(__dirname, './src/loader.js'),
                        options: {
                            name: '17'
                        }
                    }
                ]
            }
        ]
May also be used in asynchronous mode (async mode)
Call this.async () to get this.callback () method, and then returns the processing result in null callback asynchronous call by callback.

module.exports = function(content) {
    var callback = this.async();
    if(!callback) return someSyncOperation(content);
    someAsyncOperation(content, function(err, result) {
        if(err) return callback(err);
        callback(null, result);
    });
};
So how do you write a loader unit test it? OK. Directly on the code
Write a compiler.js

 

import path from 'path'
import webpack from 'webpack'
import memoryfs from 'memory-fs'

export default (fixture, options = {}) => {
    const compiler = webpack({
        context: __dirname,
        entry: `./${fixture}`,
        output: {
            path: path.resolve(__dirname),
            filename: 'bundle.js'
        },
        module:{
            rules:[
                {
                    test: /\.txt$/,
                    use: {
                        loader: path.resolve(__dirname, '../loaders/loader.js'),
                        options: {
                            name: '17'
                        }
                    }
                }
            ]
        }
    })

    compiler.outputFileSystem = new memoryfs();
    return new Promise((resolve, reject) => {
        compiler.run((err, stats) => {
            if(err) reject(err)
            resolve(stats)
        })
    })
}
This can be tested

import compiler from './compiler.js';

test('Inserts name and outputs JavaScript', async () => {
    const stats = await compiler('example.txt');
    // console.log(stats.toJson());

    const output = stats.toJson().modules[0].source;

    expect(output).toBe(`export default "Hey 17!\\n"`);
});

  

Well, demo finished, the rest is prepared according to the demand.
The last offer Loader API , the official website of loaders .

 

  

 

  

  

Guess you like

Origin www.cnblogs.com/yiyi17/p/12161617.html