关于javascript:Webpack40各个击破8tapable篇

36次阅读

共计 2019 个字符,预计需要花费 6 分钟才能阅读完成。

一. tapable 概述

tapable地址:【tapable-0.2】

tapablewebpack 的外围框架(4.0 以上版本的 API 曾经产生了变动),是一个基于事件流的框架,或者叫做公布订阅模式,或观察者模式,webpack的整个生命周期及其凋谢的自定义插件零碎都离不开 tapable 的反对,钻研其运行原理是浏览 webpack 源代码的第一步。官网仓库 master 分支的代码是通过 ES6 重构的,模块化拆分十分细,且退出了很多非核心逻辑,浏览难度较大。倡议先从官网仓库中 0.2 版本的分支开始学习,整个源码只有 400 行,绝对容易了解。

二. tapable-0.2 源码解析

2.1 代码构造

// 类定义
function Tapable() {this._plugins = {};
}
// 模块导出
module.exports = Tapable;
// 定义了许多外部办法和原型办法
...

Tapable实际上就是一个类定义的模块。

2.2 事件监听办法

tapable通过原型办法 Tapable.prototype.plugin 来注册事件监听。

这段代码并不简单,调用 plugin 办法来注册一个事件,参考浏览器环境中的 addEventListener() 办法就很容易了解了。其逻辑就是将回调函数依照事件名称进行归类存储,在 tapable 实例中对立调度治理。

//__plugin 属性上挂载了各个注册事件的回调函数
tapable.__plugins = {'click':[fn1, fn2, fn3],
   'mousedown':[fn21,fn22,fn23]
    ...
}

2.3 事件触发办法

tapable提供了许多事件触发的形式,其基本功能能够参考浏览器环境中的dispatchEvent()

tapable中的事件触发形式能够按命名分为如下几个大组:

  • waterfall办法会将上一个监听的执行后果传给下一个
  • bailResult办法只会执行到第一个返回后果不是 undefined 的监听器
  • Series办法会线性执行异步监听器,上一个完结后下一个才会开始
  • Parallel办法会并行执行所有异步监听

tapable中的典型办法如下:

  • Tapable.prototype.applyPlugins()

同步办法,该办法承受任意参数,以第一个参数为事件名查找监听器数组,顺次执行监听器的 apply() 办法,触发时将调用时除名称以外的其余参数传入 apply() 办法。

  • Tapable.prototype.applyPluginsWaterfall()

同步办法,该办法承受任意参数,如果指定事件没有注册监听器,则返回第二个参数 (init),否则顺次执行监听器的apply() 办法,传入的 args 是前一个执行前一个监听器 apply() 办法的返回值。瀑布流这个办法名很形象。

  • Tapable.prototype.applyPluginsBailResult()

同步办法,该办法承受任意参数,顺次执行监听器的 apply() 办法并获得返回值,直到某个 apply() 返回一个不为 undefined 的后果,则进行执行并将这个后果返回。

  • Tapable.prototype.applyPluginsAsync()

异步执行监听回调的办法。这个办法是程序执行,等到第一个插件执行完结后才会执行下一个插件,实现的形式就是将下一个插件当做回调函数传入第一个插件,在第一个插件的 apply() 办法的办法体最初(或是异步办法最初)来调用下一个监听插件的执行。这里利用闭包实现了一个迭代器,变量记录在 applyPluginsAsync() 办法中(就是变量 i), 并在回调中函数next() 中放弃了对 i 的援用。

例如须要用 applyPluginsAsync() 办法执行的插件须要在 apply 办法中显式执行回调函数:

class Plugin1{apply(info){var callback = Array.prototype.pop.call(arguments[1]);
        // 这里取到的 callback, 实际上就是源码中的具名函数 next()
        callback();}
}

其余的异步办法大同小异,不再赘述。

源码的异步办法定义中应用 copyProperties() 来解决两个函数,笔者尝试了很多状况这个办法都并未执行,理论状况就是将 next 函数退出了参数数组并继续执行,心愿对此有钻研的读者可能点明一下。

三. tapable1.0 概述

tapable地址:【tapable-1.0】

tapable在 1.0 版本做了很大改良,应用 ES6 语法重写了整个框架,除了更换了 API 外,在插件定义方面进行了显著降级,原来只通过 plugin() 办法来定义插件,不浏览源码很难晓得插件的标准格局,新版本的 tapable 提供了根本样例,细分的事件钩子 (*Hook),新的触发事件的办法(tap,tapAsync,tapPromise) 等等,但实现的根本需要是统一的,感兴趣的读者能够自行学习。

正文完
 0