background

In previous articles, we looked at the packaging mechanism for WebPack and the Loader, which is used to transform certain types of modules, and the Plugin, which can be used to perform a wider range of tasks. Including: package optimization, resource management, injection of environment variables. Plug-ins are designed to solve other things that loader cannot implement. So it’s worth exploring the Plugin mechanism of WebPack.

What is the plugin

A number of events are broadcast during the life cycle of a Webpack run, and the Plugin can listen for these events and change the output when appropriate through the API provided by Webpack. Plugin is an extender that, based on an event-driven mechanism, listens on certain nodes in the WebPack packaging process to perform a wide range of tasks.

Basic plug-in architecture

A plug-in consists of:

  • A named JavaScript function.
  • Define the Apply method on its prototype.
  • Specify an event hook that touches the WebPack itself.
  • Manipulate instance specific data within webPack.
  • The callback provided by WebPack is called after the functionality is implemented.

The first step is to write a constructor (on which the Prototype object has the Apply method) that accepts a reference to the Webpack Compiler object and can be accessed in the callback function. Then there is the constructor, which receives the options passed in the configuration (this constructor can write or not write as needed).

class ReadmeWebpackPlugin {
    constructor(options) {
         console.log(options)
    }

    apply(compiler){
      
    }
}
module.exports = ReadmeWebpackPlugin;
Copy the code

Use of plug-ins: Add an instance to the plugins array in webpack.config.js

const ReadmetWebpackPlugin = require('./plugins/readme-webpack-plugin')
plugins:[
    new ReadmetWebpackPlugin({
      name:'hfj'})].Copy the code

Here you pass in a parameter that you can see printed out on the command line.

The compiler and compilation

The two most important resources in plug-in development are compiler and Compilation objects. Understanding their roles is an important first step in extending the WebPack engine.

Compiler can be understood as an instance of WebPack, which stores webPack configuration, packaging process, and a series of content. Compiler provides Compiler.hooks. When developing a plug-in for WebPack, you may need to know where each hook function is called, refer to the official documentation. Here you can see that there are many moments where we can make the plug-in do different things.

The Compilation module is used by the Compiler to create new compilations (or new builds). This instance holds the content of the package compilation.

Event hooks

When we decide to write something in the compiler with certain hooks, we find asynchronous hooks and synchronous hooks in the hooks, just to name a few:

When AsyncSeriesHook, we use tapAsync to tap the plugin. Note that we need to call callback, which will be passed to the function as the last argument.

In actual combat

Now I need to write a plugin myself and put a readme.txt in the dist directory after the Webpack is finished. The first thing you need to know is what kind of moment this is, yes, after the webpack is finished and before the resource is generated to the Output directory. By looking at the Complier hooks in the documentation. Very good! Emit has this hook! Also note that the emit is AsyncSeriesHook, so remember to use its tapAsync method and call back the function as mentioned above. The idea is already very clear, code up!

class ReadmeWebpackPlugin {
    apply(compiler){
        compiler.hooks.emit.tapAsync('ReadmeWebpackPlugin',( compilation,callback ) => {
            console.log(compilation.assets)
            compilation.assets['readme.txt'] = {
                source:function() {return 'readme'
                },
                size:function() {return 6
                }
            }
            callback()
        })
    }
}
module.exports = ReadmeWebpackPlugin;
Copy the code

Compilation. Assets is printed in the above code. What contents are stored in the assets property of Compilation, so we can add another file in the same way as adding key/value pairs. Use the:

//webpack.config.js ... Plugins :[new ReadmetWebpackPlugin()],Copy the code

Success:

Attached is the full address of the project

conclusion

If you read the source code for WebPack, you will find that a large portion of WebPack is written based on the plugin mechanism, so plugin is at the heart of Webapck. Fortunately, we now understand the Plugin mechanism of WebPack and can write our own plug-ins.

Pay attention to our