webpack plugin

plugin是什么

plugin 是webpack的hooks,是充当发布订阅中的订阅者。是一个具有 apply 属性的 JavaScript 对象,apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问。plugin向第三方开发者提供了 webpack 引擎中完整的能力。开发者可以在 webpack 构建流程中引入自定义的行为。开发者可以监听webpack的特定生命周期,从而添加自己的行为eg
// test.js

const pluginName = 'ConsoleLogOnBuildWebpackPlugin';
class ConsoleLogOnBuildWebpackPlugin {
    apply(compiler) {
        compiler.hooks.run.tap(pluginName, compilation => {
            console.log("webpack 构建过程开始!");
        });
    }
}
module.exports = ConsoleLogOnBuildWebpackPlugin;

用法

// webpack.config.js
const ConsoleLogOnBuildWebpackPlugin = require('./test.js');

module.exports = {
  // ... configuration settings here ...
  plugins: [new ConsoleLogOnBuildWebpackPlugin()]
};

plugin的调用时机

const webpack = require("webpack");
const options = require("../webpack.config.js");

const compiler = webpack(options);
compiler.run(); // 启动代码编译

在源码的lib/webpack.js

// const compiler = webpack(options);
const webpack = (options, callback) => {
    // ...
    let compiler;
    if (Array.isArray(options)) {
        compiler = new MultiCompiler(
            Array.from(options).map(options => webpack(options))
        );
    } else if (typeof options === "object") {
        // ...
        if (options.plugins && Array.isArray(options.plugins)) {
            for (const plugin of options.plugins) {
        // 真正的调用plugin的地方 这样就会订阅成功,等真正发布的时候就会生效
                if (typeof plugin === "function") {
                    plugin.call(compiler, compiler);
                } else {
                    plugin.apply(compiler);
                }
            }
        }
        // ...
    } else {
        throw new Error("Invalid argument: options");
    }
    
    return compiler;
};

lib/Compiler.js中的Compiler类的run

// compiler.run();
class Compiler extends Tapable {
    constructor(context) {
        super();
        this.hooks = {
      ...
            /** @type {AsyncSeriesHook} */
            run: new AsyncSeriesHook(["compiler"]),
        ...
        };
  } 
    run(callback) {
        if (this.running) return callback(new ConcurrentCompilationError());

        const finalCallback = (err, stats) => {
            ...
        };

        const startTime = Date.now();

        this.running = true;

        const onCompiled = (err, compilation) => {
            ...
        };

        this.hooks.beforeRun.callAsync(this, err => {
            if (err) return finalCallback(err);
      // 真正调用run hooks的地方,也就是发布 由于我们在上面的test.js的插件中的apply中订阅了这个事件 compiler.hooks.run.tap  所以在这里订阅的回调函数在执行也就是回输出 "webpack 构建过程开始!"的字符串 回调函数可以获取到this也就是Compiler类的实例
            this.hooks.run.callAsync(this, err => {
                if (err) return finalCallback(err);

                this.readRecords(err => {
                    if (err) return finalCallback(err);

                    this.compile(onCompiled);
                });
            });
        });
    }
  ...
}

流程图

webpack-plugin.jpeg

参考

https://webpack.docschina.org/contribute/writing-a-plugin/

你可能感兴趣的:(webpack plugin)