// 核心对象 Compiler 继承 Tapable
class Compiler extends Tapable {
//...
}
// 核心对象 Compilation 继承 Tapable
class Compilation extends Tapable {
//...
}
Tapable 是 Webpack 的核心模块,Tapable 是一个类似于 Node.js 的 EventEmitter 的库,Webpack 的所有工作流程都是通过 Tapable 来实现的。Tapable 本质上是提供了多种类型的事件绑定机制,根据不同的流程特点可以选择不同类型的 Hook 来使用。
Tapable 的核心实现在绑定事件阶段跟我们平时的自定义 JavaScript 事件绑定(例如 EventEmitter)没有太大区别,但是在事件触发执行的时候,会临时生成可以执行的函数代码片段。通过这种实现方式,Tapable 实现了强大的事件流程控制能力,也增加了如 waterfall/parallel 系列方法,实现了异步/并行等事件流的控制能力。
其实主要是控制钩子函数的发布与订阅,控制着 webpack 的插件系统。
Tapable 库暴露了很多 Hook (钩子)类,为插件提供挂载的钩子
const {
SyncHook, // 同步钩子
SyncBailHook, // 同步熔断钩子
SyncWaterfallHook, // 同步流水钩子
SyncLoopHook, // 同步循环钩子
AsyncParallelHook, // 异步并发钩子
AsyncParallelBailHook, // 异步并发熔断钩子
AsyncSeriesHook, // 异步串行钩子
AsyncSeriesBailHook, // 异步串行熔断钩子
AsyncSeriesWaterfallHook // 异步串行流水钩子
} = require('tapable')
Tapable hooks 类型
- Hook: 所有钩子的后缀
- Waterfall: 同步方法,但是它会传值给下一个函数
- Bail: 熔断:当函数有任何返回值,就会在当前执行函数停止
- Loop: 监听函数返回 true 表示继续循环,返回 undefine 表示结束循环
- Sync: 同步方法
- AsyncSeries: 异步串行钩子
- AsyncParallel: 异步并行执行钩子
Tapable 的使用
new Hook 新建钩子
Tapable 暴露出来的都是类方法,new 一个类方法获得我们需要的钩子
class 接受数组参数 options,非必传。类方法会根据参数,接受同样数量的参数。
const hook1 = new SyncHook(['arg1', 'arg2', 'arg3'])
钩子的绑定与执行
Tabpack 提供了 同步和异步 绑定钩子的方法,并且他们都有绑定事件和执行事件对应的方法。
Async
绑定:tapAsync/tapPromise/tap
执行:callAsync/promise
Sync
绑定:tap
执行:call
示例
const hook1 = new SyncHook(['arg1', 'arg2', 'arg3'])
hook1.tap('hook1', (arg1, arg2, arg3) => console.log(arg1, arg2, arg3))
hook1.call(1, 2, 3)