Webpack - tapable

132 阅读2分钟

Webpack 本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是 Tapable,Tapable 有点类似于 nodeJs 中的 Events 库,其提供了许多异步、同步的方法;核心原理也是依赖于发布订阅模式

其实 tapable 就是一个 library(npm 包),他可以为 webpack 的插件 创建很多的hooks, 使用方法直接戳此 tapable 的使用

可以从连接中看到

  • Basic hook: 它只是连续的调用每一个被注册的方法
  • Waterfall: waterfall hook也是连续调用每一个被注册的方法,只是他可以从每个方法中传递 值 到下一个方法中
  • Bail: bail hook 允许提前退出,当任意注册的方法返回任何值(非空),这个 bail hook 将会停止剩下的 hook
  • Loop: 当一个插件在 look hook 中 return 了一个非 undefined 的值,这个hook 将会从第一个插件重新启动,直到多有的插件都 return undefined 值 除此之外,Sync 标志着是同步的方法 ,Async 标志着是异步的方法

异步的钩子有串行和并行两种

tapable库中

  • 有三种注册的方法 tap(listenerName,(args) => {}) 同步注册、tapAsync(listenerName,(args,callback) => {里边需要执行callback})、tapPromise(listenerName,(args) => { return new Promise(xxx)})

使用的简单demo

const { SyncHook } = require("tapable")

class Lesson {
  constructor() {
    this.hooks = {
      arch: new SyncHook(['techName']),
    }
  }
  tap() {
    // 注册监听函数
    this.hooks.arch.tap("node", (techName) => {
      console.log("node: ", techName);
    });
    this.hooks.arch.tap("react", (techName) => {
      console.log("react: ", techName);
    });
  }
  start() {
    // 执行钩子里的函数
    this.hooks.arch.call("pink");
  }
}

const l = new Lesson();
l.tap(); // 注册两个事件
l.start(); // 启动钩子

简单实现一个 SyncHook

class SyncHook {
  constructor(args) {
    // 字符串数组
    this.tasks = []; // 用来存放tap的方法任务
  }
  tap(name, task) {
    // 每次注册监听函数的时候,将事件名字push到tasks中
    this.tasks.push(task)
  }
  // 同步的钩子
  call(...args) {
    this.tasks.forEach((task) => task(...args))
  }
}

更多 tapable 的hook demo 和 对应的实现原理请戳链接