Graphic webpack — implementing loader

Time:2021-9-26

Graphic webpack -- implementing loader

Pay attention to the official account “Kite holder”, get learning resources.

The loader assumes the responsibility of the translator, which makes up for the problem that webpack can only understand JavaScript and JSON files, so it can handle other types of files. Therefore, the importance of loader to webpack is self-evident, so learning to build a loader is the only way to learn webpack. Before learning to write a loader, clarify the responsibilities of the loader:Its responsibilities are single and only one transformation needs to be completed。 Several key points in selecting loader development and implementing a loader will be described step by step below.

Graphic webpack -- implementing loader

1、 Loader classification

Loader is a commonjs style function. After receiving the input source, it can be processed synchronously or asynchronously, and then output the content.

Graphic webpack -- implementing loader

1.1 synchronous loader

Synchronous loader refers to the synchronized returned converted content., Because it is in a single threaded environment such as node.js, the conversion process will block the whole construction, and the construction is slow, which is not suitable for a time-consuming environment. For synchronous loaders, there are two main methods to return the converted content: return and this. Callback

  1. return<br/>

Use return to return the converted result directly.

module.exports = function(source, map, meta){
    // ...
    //Output is the processed result
    return output;
}
  1. this.callback<br/>

This method is more flexible than return. There are four main parameters:

this.callback(
  err: Error | null,
  content: string | Buffer,
  sourceMap?: SourceMap,
  meta?: any
);

(1) The first parameter is that the original content cannot be converted. Webpack will return an error< br/>
(2) The second parameter is the converted content (the output content)< br/>
(3) It refers to the source code mapped with the compiled code, which is convenient for debugging. In order to obtain the sourcemap in this loader, you need to configure the created webpack (taking JS as an example, Babel loader will convert the basic ES6 syntax to Es5, and you can open the source map through devtool):

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    'test loader ', // the loader is the loader built by yourself
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                '@babel/preset-env'
                            ]
                        }
                    }
                ]
            }
        ]
    },
    devtool: 'eval-source-map',
}

(4) It can be anything. If this parameter is output, it can be obtained and used in the next loader. For example, by sharing a common ast among loaders, the compilation time can be accelerated.

Use this.callback to return the result of passing multiple parameters.

module.exports = function(source, map, meta) {
    //Result output obtained after processing
    const output = dealOperation(source);
    this.callback(null, output, map, meta);
}

1.2 asynchronous loader

Synchronous loader is only suitable for scenarios with small amount of calculation and high speed. However, for scenarios with large amount of calculation and long time-consuming (such as network requests), using synchronous loader will block the whole construction process and slow down the construction speed. This problem can be avoided by using asynchronous loader. For asynchronous loaders, this. Async () can be used to obtain the callback function, and the function parameters are consistent with this. Callback parameters in synchronous loaders.

module.exports = function(content, map, meta) {
    //Get callback function
    const callback = this.async();
    //Simulate the asynchronous process with setTimeout
    setTimeout(() => {
        //Result output obtained after processing
    const output = dealOperation(source);
        callback(null, output, map, meta);
    }, 100)
}

2、 File type after conversion

By default, all resource files are UTF-8 encoded strings after conversion. However, for files such as pictures, which are in binary format after conversion, raw needs to be set in order for the loader to support receiving binary resources (take picture resources as an example)

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [
            {
                test: /\.(png|jpg|gif)$/,
                use: [
                    'url-loader',
                    'raw test loader', // own loader
                ]
            }
        ]
    }
}
// raw-test-loader.js
module.exports = function(source, map, meta) {
    //Process input resources
    const output = dealOperation(source);
    return output;
}
//This attribute tells webpack whether the loader needs binary data
module.exports.raw = true;

3、 Options options

In webpack configuration, the loader often has some options parameters. In order to obtain the options parameters in the loader written by yourself, the official recommends using the loader utils package, which can be used to obtain the parameters in the options, and then processed in the loader.

const loaderUtils = require('loader-utils');

module.exports = function (source, map, meta){
    //Get options
    const options = loaderUtils.getOptions(this);
    const output = dealOperation(source);
    
    return output;
}

4、 Cache

The conversion operation requires a lot of calculation and is very time-consuming. Each rebuild will make the construction process very slow. Webpack will cache the processing results of all loaders by default, that is, if the processing files and their related dependencies have not changed, they will use their cache (note that loaders should not have any external dependencies except those specified in this.adddependency). You can control whether it is cached through this.cacheable.

module.exports = function(source, map, meta) {
    //Close cache
    this.cacheable(false);
    return source;
}

5、 Implement a loader

This section is the actual operation of the loader. A loader for letter case conversion is written. Using this loader, the case conversion of letters in txt files can be realized. The contents of the loader and the related configuration of webpack.config.js are as follows (see for the detailed code)github(upper code)

// format-letters-loader.js
const loaderUtils = require('loader-utils');

const Lowercase2Uppercase = 'L2U';
const Uppercase2Lowercase = 'U2L';

module.exports = function (source, map, meta) {
    let output = '';
    //Get options
    const options = loaderUtils.getOptions(this);
    const { formatType } = options;
    switch(formatType) {
        case Lowercase2Uppercase: {
            output = source.toUpperCase();
            break;
        }
        case Uppercase2Lowercase: {
            output = source.toLowerCase();
            break;
        }
        default: {
            output = source;
        }
    }

    this.callback(null, output, map, meta);
};
// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [
            {
                exclude: /\.(css|js|html|png|jpg|gif)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'asset',
                        }
                    },
                    {
                        loader: 'format-letters-loader',
                        options: {
                            formatType: 'U2L'
                        }
                    },
                ]
            }
        ]
    },
    //Parsing the loader package is to set how the module is parsed
    resolveLoader: {
        Modules: ['. / node_modules','. / loader '], // tell webpack the directory to search when parsing the loader.
    },
}

Note: This article only plays a role in attracting jade. I hope you can give me more advice.

Relevant sections < br / >
Graphic webpack — Fundamentals
Graphic webpack — Optimization

Welcome to the official account (reply to “Webpack”, get the PDF version of Webpack, reply to “webpack04” get the mind map of this section).
Graphic webpack -- implementing loader

Recommended Today

Seven Python code review tools recommended

althoughPythonLanguage is one of the most flexible development languages at present, but developers often abuse its flexibility and even violate relevant standards. So PythoncodeThe following common quality problems often occur: Some unused modules have been imported Function is missing arguments in various calls The appropriate format indentation is missing Missing appropriate spaces before and after […]