preface

Last time I wrote how to write a Webpack Loader, today I will talk about how to write a Webpack Plugin.

Webpack executes the process internally

A complete Webpack package looks something like this:

  • The command line parameters are merged and parsed with the WebPack configuration file to obtain the parameter object.
  • The parameter object is passed to the Webpack execution to get the Compiler object.
  • Execute the Compiler’s run method to start compiling. Each run Compilation generates a Compilation object.
  • The Compiler’s make method triggers the parsing of the entry file, and the Compilation’s buildModule method is called to create the main module object.
  • Generate an entry file AST(abstract syntax tree) and load dependent modules recursively through AST analysis.
  • After the analysis of all modules was completed, the Seal method of Compilation was executed to sort, optimize and encapsulate each chunk.
  • Finally, Compiler’s emitAssets method is executed to output the generated files to the directory of output.

The Plugin function

As I understand it, the purpose of the Webpack plug-in is to do something for us when The Webpack is running at a certain point.

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.

The official explanation:

Plug-ins provide third-party developers with the full capabilities of the WebPack engine. Using staged build callbacks, developers can introduce their own behavior into the WebPack build process.

Writing a Plugin

The webPack plug-in consists of:

  • A JS named function or a class (can think of our usual use of plug-ins isnew XXXPlugin()The way)
  • Define an apply method on the (prototype) of the plug-in class/function.
  • The Compilation object is fetched in the hook callback by passing in the Compiler in the Apply function and inserting the specified event hook
  • Compilation handles specific instance data within webPack
  • If the plug-in is asynchronous, the callback provided by WebPack is called after the plug-in logic is written

Let’s say we write a plugin that generates a copyrighted file.

The basic shape

function CopyrightWebpackPlugin() {}

CopyrightWebpackPlugin.prototype.apply = function (compiler) {}

module.exports = CopyrightWebpackPlugin
Copy the code

It can also be written as a class:

class CopyrightWebpackPlugin {
  apply(compiler) {
    console.log(compiler)
  }
}
 module.exports = CopyrightWebpackPlugin Copy the code

After webpack starts, the new CopyrightWebpackPlugin(Options) operation will be executed to initialize an instance object of CopyrightWebpackPlugin in the process of reading the configuration. After the Compiler object is initialized, the Apply method of the above instance object is called and passed in.

In the Apply method, compiler objects are used to listen for events broadcast during the WebPack lifecycle, and we can also manipulate webPack output through compiler objects.

The Compiler and Compilation

The two most important objects in plug-in development are compiler and compilation objects.

The Compiler object represents the complete Configuration of the WebPack environment and, after initializing the Compiler object, is passed in as its parameter by calling the Apply method of the plug-in instance. This object is created once when WebPack is started and contains all configuration information for the WebPack environment, including options, Loader, and plugin. When a plug-in is applied in a WebPack environment, the plug-in receives a reference to this Compiler object. You can use it to access the main webPack environment.

The compilation object is used as an argument to the plugin’s built-in event callbacks. A compilation object contains the current module resource, the compile-generated resource, the changing files, and the state information on which the trace depends. When Webpack is running in development mode, a new compilation is created each time a file change is detected. The compilation object also provides many event callbacks for plug-ins to extend. Compiler objects can also be read from the compilation.

coding

SRC /plugins/copyright-webpack-plugin.js

class CopyrightWebpackPlugin {
  apply(compiler) {
    Emit is an asynchronous serial hook that needs to be registered with tapAsync
    compiler.hooks.emit.tapAsync('CopyrightWebpackPlugin', (compilation, callback) => {
      // Register the asynchronous hook in callback mode
 const copyrightText = 'copyright reserved by JackySummer'  // compilation stores all the contents of this compilation  // All files to be generated are in its assets property  compilation.assets['copyright.txt'] = {  / / add copyright. TXT  source: function () {  return copyrightText  },  size: function () {  // File size  return copyrightText.length  },  }  callback() // Must be called  })  } }  module.exports = CopyrightWebpackPlugin Copy the code

Many objects in Webpack extend from the Tapable class. This class exposes the TAP, tapAsync, and tapPromise methods, which you can use to inject custom build steps that will be triggered at different times throughout the compilation process.

When you use the tapAsync method to access the plug-in, you call the callback function provided as the last argument.

In webpack. Config. Js

const path = require('path')
const CopyrightWebpackPlugin = require('./src/plugins/copyright-webpack-plugin')

module.exports = {
  mode: 'production'. entry: './src/index.js'. output: {  path: path.resolve(__dirname, 'dist'),  filename: '[name].js'. },  plugins: [new CopyrightWebpackPlugin()], } Copy the code

Execute the webpack command, and you’ll see the copyright. TXT file generated in the dist directory

To obtain this parameter, you can add a constructor to the plugin class:

 plugins: [
  new CopyrightWebpackPlugin({
    name: 'jacky'.  }),
].Copy the code

In the copyright – webpack – plugin. Js

class CopyrightWebpackPlugin {
  constructor(options = {}) {
    console.log('options', options) // options { name: 'jacky' }
  }
}
Copy the code

Reference article: Debunking the WebPack Plugin


  • Ps: Personal technical blog Github warehouse, if you feel good welcome star, give me a little encouragement to continue writing ~