webpack --- 自定义 webpack plugin
2019-10-17 09:56 *奋斗* 阅读(143) 评论(0) 收藏 举报[Compiler.js]:
const {
SyncHook,
AsyncParallelHook
} = require('tapable');
class Compiler {
constructor(options) {
this.hooks = {
accelerate: new SyncHook(["newSpeed"]),
break: new SyncHook(),
calculateRoutes: new AsyncParallelHook(["source", "target", "routesList"])
};
let plugins = options.plugins;
if (plugins && plugins.length > 0) {
plugins.forEach(plugin => plugin.apply(this));
}
}
run() {
console.time('cost'); // time start
this.accelerate('hello')
this.break()
this.calculateRoutes('i', 'like', 'tapable')
}
accelerate(param) {
this.hooks.accelerate.call(param);
}
break() {
this.hooks.break.call();
}
calculateRoutes() {
const args = Array.from(arguments)
this.hooks.calculateRoutes.callAsync(...args, err => {
console.timeEnd('cost'); // time end
if (err) console.log(err)
});
}
}
module.exports = Compiler;
[MyPlugin.js]:
const Compiler = require('./Compiler') //
class MyPlugin{
constructor() {
}
apply(compiler){//接受 compiler参数
compiler.hooks.break.tap("WarningLampPlugin", () => console.log('WarningLampPlugin'));
compiler.hooks.accelerate.tap("LoggerPlugin", newSpeed => console.log(`Accelerating to ${newSpeed}`));
compiler.hooks.calculateRoutes.tapAsync("calculateRoutes tapAsync", (source, target, routesList, callback) => {
setTimeout(() => {
console.log(`tapAsync to ${source}${target}${routesList}`)
callback();
}, 2000)
});
}
}
class MyPluginEx{
constructor() {
}
apply(compiler){ //接受 compiler参数
compiler.hooks.break.tap("WarningLampPlugin", () => console.log('WarningLampPlugin'));
compiler.hooks.accelerate.tap("LoggerPlugin", newSpeed => console.log(`Accelerating to ${newSpeed}`));
compiler.hooks.calculateRoutes.tapAsync("calculateRoutes tapAsync", (source, target, routesList, callback) => {
setTimeout(() => {
console.log(`tapAsync to ${source}${target}${routesList}`)
callback();
}, 2000)
});
}
}
//这里类似于webpack.config.js的plugins配置
//向 plugins 属性传入 new 实例
const myPlugin = new MyPlugin();
const myPluginEx = new MyPluginEx();
const options = {
plugins: [myPlugin, myPluginEx]
}
let compiler = new Compiler(options)
compiler.run();

个人总结:
1、Compiler.js 对 Webpack 进行了模拟。run( ) 中分别调用了不同的钩子函数(类似于生命周期钩子函数);
2、不同的钩子函数,在不同的插件初始化后,都可以对挂载的 handler 了进行依次执行,原理的理解可以参考组件的生命周期(不同时间段干不同的事情);
3、Compiler 可以同时初始化多个插件(插件数组,跟 webpack config 类似),实际上述代码可以在 vs code 中针对 MyPlugin.js 代码直接执行查看结果;
4、new SyncHook(["newSpeed"]) 中的 newSpeed 其实就是写在插件中的初始化钩子时的参数名,直接对应,有几个参数传递几个。
http://07lyt.com/2017/04/28/webpack%E6%B5%81%E7%A8%8B/ --- 图片来源
浙公网安备 33010602011771号