1. Tabable 用法
const {
SyncHook,
SyncBailHook,
SyncWaterfallHook,
SyncLoopHook,
AsyncParallelHook,
AsyncParallelBailHook,
AsyncSeriesHook,
AsyncSeriesBailHook,
AsyncSeriesWaterfallHook
} = require("tapable");
| Async | Sync | |
|---|---|---|
| 绑定 | tapAsync/tapPromise/tap | tap |
| 执行 | callAsync/promise | call |
const hook1 = new SyncHook(["arg1", "arg2", "arg3"]);
//绑定事件到webapck事件流
hook1.tap('hook1', (arg1, arg2, arg3) => console.log(arg1, arg2, arg3)) //1,2,3
//执行绑定的事件
hook1.call(1,2,3)
2. Tabable 用法demo
- 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');
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');
if (err) console.log(err)
});
}
}
module.exports = Compiler
- MyPlugin.js
const Compiler = require('./Compiler')
class MyPlugin{
constructor() {
}
apply(conpiler){//接受 compiler参数
conpiler.hooks.break.tap("WarningLampPlugin", () => console.log('WarningLampPlugin'));
conpiler.hooks.accelerate.tap("LoggerPlugin", newSpeed => console.log(`Accelerating to ${newSpeed}`));
conpiler.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 options = {
plugins: [myPlugin]
}
let compiler = new Compiler(options)
compiler.run()
3. webpack中用法
webpack是一个插件合集,由 tapable 控制各插件在 webpack 事件流上运行。主要依赖的是compilation的编译模块和封装。
Compiler
webpack 的入口文件其实就实例了Compiler并调用了run方法开启了编译,webpack的主要编译都按照下面的钩子调用顺序执行。
- Compiler:beforeRun 清除缓存
- Compiler:run 注册缓存数据钩子
- Compiler:beforeCompile
- Compiler:compile 开始编译
- Compiler:make 从入口分析依赖以及间接依赖模块,创建模块对象
- Compilation:buildModule 模块构建
- Compiler:normalModuleFactory 构建
- Compilation:seal 构建结果封装, 不可再更改
- Compiler:afterCompile 完成构建,缓存数据
- Compiler:emit 输出到dist目录
Compilation
一个 Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。
Compilation 对象也提供了很多事件回调供插件做扩展。
Compilation中比较重要的部分是assets 如果我们要借助webpack帮你生成文件,就要在assets上添加对应的文件信息。
compilation.getStats()能得到生产文件以及chunkhash的一些信息。
完整文章
撸一个webpack插件
欢迎关注我的前端自检清单,我和你一起成长