说明
玩转 webpack 学习笔记
Tapable 是如何和 webpack 联系起来的?
可以看下面这段代码
if (Array.isArray(options)) {
compiler = new MultiCompiler(options.map(options => webpack(options)));
} else if (typeof options === "object") {
options = new WebpackOptionsDefaulter().process(options);
compiler = new Compiler(options.context);
compiler.options = options;
new NodeEnvironmentPlugin().apply(compiler);
if (options.plugins && Array.isArray(options.plugins)) {
for (const plugin of options.plugins) {
if (typeof plugin === "function") {
plugin.call(compiler, compiler);
} else {
plugin.apply(compiler);
}
}
}
compiler.hooks.environment.call();
compiler.hooks.afterEnvironment.call();
compiler.options = new WebpackOptionsApply().process(options, compiler);
}
- 插件需要一个 apply 方法,接收一个 compiler 参数
- 插件上做一些 hooks 的监听,触发了插件做一些操作
模拟 Compiler.js
const {
SyncHook,
AsyncSeriesHook
} = require('tapable');
module.exports = class Compiler {
constructor() {
this.hooks = {
accelerate: new SyncHook(["newspeed"]),
brake: new SyncHook(),
calculateRoutes: new AsyncSeriesHook(["source", "target", "routesList"]),
};
}
run() {
this.accelerate(10);
this.break();
this.calculateRoutes("Async", "hook", "kaimo demo");
}
accelerate(speed) {
this.hooks.accelerate.call(speed);
}
break() {
this.hooks.brake.call();
}
calculateRoutes() {
this.hooks.calculateRoutes.promise(...arguments).then(
() => { },
(err) => {
console.error(err);
}
);
}
};
插件 my-plugin.js
const Compiler = require('./Compiler')
class MyPlugin {
constructor() {
}
apply(compiler) {
compiler.hooks.brake.tap("WarningLampPlugin", () => console.log('WarningLampPlugin'));
compiler.hooks.accelerate.tap("LoggerPlugin", newSpeed => console.log(`Accelerating to ${newSpeed}`));
compiler.hooks.calculateRoutes.tapPromise("calculateRoutes tapAsync", (source, target,) => {
return new Promise((resolve,) => {
setTimeout(() => {
console.log(`tapPromise to ${source} ${target} ${routesList}`)
resolve();
}, 1000)
});
});
}
}
模拟插件执行
const myPlugin = new MyPlugin();
const options = {
plugins: [myPlugin]
}
const compiler = new Compiler();
for (const plugin of options.plugins) {
if (typeof plugin === "function") {
plugin.call(compiler, compiler);
} else {
plugin.apply(compiler);
}
}
compiler.run();
实战运行测试
我们根据上面的代码新建两个文件,添加上面代码
执行 node my-plugin.js
,结果如下