1. // 核心对象 Compiler 继承 Tapable
  2. class Compiler extends Tapable {
  3. //...
  4. }
  5. // 核心对象 Compilation 继承 Tapable
  6. class Compilation extends Tapable {
  7. //...
  8. }

Tapable 是 Webpack 的核心模块,Tapable 是一个类似于 Node.js 的 EventEmitter 的库,Webpack 的所有工作流程都是通过 Tapable 来实现的。Tapable 本质上是提供了多种类型的事件绑定机制,根据不同的流程特点可以选择不同类型的 Hook 来使用。

Tapable 的核心实现在绑定事件阶段跟我们平时的自定义 JavaScript 事件绑定(例如 EventEmitter)没有太大区别,但是在事件触发执行的时候,会临时生成可以执行的函数代码片段。通过这种实现方式,Tapable 实现了强大的事件流程控制能力,也增加了如 waterfall/parallel 系列方法,实现了异步/并行等事件流的控制能力。

其实主要是控制钩子函数的发布与订阅,控制着 webpack 的插件系统。

Tapable 库暴露了很多 Hook (钩子)类,为插件提供挂载的钩子

  1. const {
  2. SyncHook, // 同步钩子
  3. SyncBailHook, // 同步熔断钩子
  4. SyncWaterfallHook, // 同步流水钩子
  5. SyncLoopHook, // 同步循环钩子
  6. AsyncParallelHook, // 异步并发钩子
  7. AsyncParallelBailHook, // 异步并发熔断钩子
  8. AsyncSeriesHook, // 异步串行钩子
  9. AsyncSeriesBailHook, // 异步串行熔断钩子
  10. AsyncSeriesWaterfallHook // 异步串行流水钩子
  11. } = 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

示例

  1. const hook1 = new SyncHook(['arg1', 'arg2', 'arg3'])
  2. hook1.tap('hook1', (arg1, arg2, arg3) => console.log(arg1, arg2, arg3))
  3. hook1.call(1, 2, 3)