webpack plugin
2022-07-06 本文已影响0人
冷暖自知_zjz
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<Compiler>} */
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);
});
});
});
}
...
}
流程图

参考