探索webpack源码(三)--- Tapable插件使用 20
上次说是准备探索Compiler.js
,但是我看了一下Compiler.js
里面最主要的也就是用的Tapable
,所以就先鸽大家一下了[手动笑哭]。
这里不得不先吐槽一下,之前学习Tapable
的时候,基本只有Tapable 0.2
的教学版本,而webpack4.x
用的又是Tapable 1.x
,学起来真的是有种学医救不了中国人的感觉…但是最近webpack中文文档
更新的很快,好像半个月就更新了3个版本webpack v4.2 -> webpack v4.5
,总算是开始维护自己的文档了。
不废话那么多了,进入主题吧。
Tapable
按照上一次我们说的Compiler.js
,这次我们还是过一下吧,不过只到定义类的那一行:
class Compiler extends Tapable {
// something code ...
}
好的,这里的Compiler
继承了Tapable
,然后再往上找一下就能发现一段引入代码:
const Tapable = require('tapable').tapable
今天探索就是讲这一部分,只是探索怎么使用而不是探索源码,因为tapable
体系特别复杂,没办法一次性讲清楚。
其实用法主要就只有以下三种:
针对于同步:
tap对应call
针对于异步:
tapSync对应promise
tapAsync对应callAsync
而使用方法基本就是这样,以同步为例:
const { SyncHook } = require('tapable');
const hook = new SyncHook();
hook.tap('my-hook', () => {
console.log('我的hook。')
});
hook.call();
// 我的hook
而需要给hook添加参数:
const { SyncHook } = require('tapable');
const hook = new SyncHook(['参数1', '参数2', '参数3']);
hook.tap('my-hook', (arg1, arg2, arg3) => {
console.log(arg1, arg2, arg3)
});
hook.call('小红', '小绿', '小蓝')
// 小红 小绿 小蓝
原本是没有打算写Async的,但是自己也经常忘记Async的用法,懒得老是去写代码测试,就在这里也补上吧。
const { AsyncSeriesHook } = require('tapable');
const hook1 = new AsyncSeriesHook(['arg']);
const hook2 = new AsyncSeriesHook(['arg']);
const hook3 = new AsyncSeriesHook(['arg']);
hook1.tapPromise('asyncHook', (arg) => {
console.log(arg)
return Promise.resolve();
})
hook1.promise('exec promise tap hook!').then(() => {
// then函数这里似乎无法接收从tapPromise的resolve传过来的内容。
// 所以then接收的匿名函数没有传参。
console.log('执行后续内容。')
});
// 打印:
// exec promise tap hook!
// 执行后续内容。
hook2.tapAsync('asyncHook', (arg) => {
console.log(arg);
})
hook2.callAsync('exec async tap hook!');
// 打印:
// exec async tap hook!
// 这里还有个隐藏技能,可能是我没去仔细tapable看源码的缘故吧
// 用tap绑定的AsyncSeriesHook,在callAsync的时候还会接收一个err-first格式的回调。
hook3.tap('asyncHook', (arg) => {
console.log(arg);
})
hook3.callAsync('exec tap hook!', err => { console.log(123) })
由于tapAsync比tapPromise简单,所以内容也比较少,但是他们似乎不可覆盖使用,也就是一个AsyncSeriesHook不能同时绑定async和promise,否则promise似乎会不生效,这里我没有仔细往下试,我想设计的人也不会想我们这么用的吧(笑哭)。
以上就是hook的使用方式,除了SyncHook和AsyncSeriesHook以外,还有以下的Hook:
name | desciption |
---|---|
SyncHook | 同步钩子 |
SyncBailHook | 同步保留钩子(有返回值) |
SyncWaterfallHook | 同步瀑布流钩子(执行完call以后,以最后一个返回值为准) |
SyncLoopHook | 暂时没见过 |
AsyncParallelHook | 异步并行钩子 |
AsyncParallelBailHook | 异步并行保留值钩子 |
AsyncSeriesHook | 异步串行钩子 |
AsyncSeriesBailHook | 异步串行保留值钩子 |
AsyncSeriesWaterfallHook | 异步串行瀑布流钩子 |
以上就是 Tapable
钩子的探索,这里只讲了同步调用的办法,异步的用法在开头也已经说了有对应的方法,接下来就可以开始讲Compiler.js
了。:)