webpack源码之tapable

弁言

客岁3月的时刻当时写了一篇
webpack2-update之路,到本日webpack已到了4.2,更新挺快的,功用也在不停的完美,webpack4特征之一就是零设置, webpack生命力真的很顽固,主动跟上环境的变化,相应社区的需求,不停的迭代,由于parcel在其之前就有这个特征了。直接运转webpack敕令,默许production形式,然则会有WARNING。

以下所示在package.json中启动剧本设置

"scripts": {
    "build": "webpack --mode production",  //代码做了紧缩/作用域提拔(就是将依靠模块内容直接放到当前模块内)/去掉了开辟形式下存在的代码/更轻易运用输出的资本文件(assets做了优化处置惩罚)
    "dev": "webpack-dev-server --open --mode development", //支撑解释/提醒/source maps
  },

这类商定大于设置的开辟方式,在许多框架中都存在, 默许的设置覆蓋了大部分用户运用的场景,提高了大部分人的生产力。固然除了默许设置外另有别的一些特征,比方支撑导入更多的模块范例,能够剖析.json.wasm范例的文件等等。

虽然运用形式上变化的这么快, 然则个中心头脑没多大变化。 个中webpack内部有一个事宜流机制,基于tapable,也是本文研讨的对象,它的作用是将各个插件串连起来,另有webpack中担任编译的Compile也是tapable的实例,所以这个蛮重要的,下面详细说一下。

tapable观点

tapable类似于node中的EventEmitter,专注于自定义事宜的触发和处置惩罚,本身能够被继续或混入到别的模块中。比方compile的完成就用到了tapable,以下所示。

var Tapable = require("tapable");

function Compiler() {
    Tapable.call(this);
}

Compiler.prototype = Object.create(Tapable.prototype);

Hook剖析

class Car {
    constructor() {
        this.hooks = {
            accelerate: new SyncHook(["newSpeed"]),
            break: new SyncHook(),
            calculateRoutes: new AsyncParallelHook(["source", "target", "routesList"])
        };
    }

}
const myCar = new Car();
//运用tap要领增加了一个消费者,个中tap的第一个参数,平常是用来确认插件的称号
myCar.hooks.accelerate.tap("LoggerPlugin", newSpeed => console.log(`Accelerating to ${newSpeed}`));
myCar.hooks.accelerate.call('100')
//输出   Accelerating to 100

申明 个中SyncHook继续了Hook要领,重要作用是重写了compile要领。而Hook内部保护了 this.taps = [],每次实行tap时,都邑举行insert,call的时刻经由过程

this[name](...args)

举行实行,在call实行的时刻其内部涉及到工场形式,由于call的挪用,须要先实行当前SyncHook的compile要领,用工场形式的目标就是依据传入的差别option返回差别的经由过程new Function拼接出的
处置惩罚逻辑函数,由于Hook有好几种完成,在完成类的实例中增加的消费者能够是sync,promise,async等等,都须要对应差别compile来举行处置惩罚。

tapable运用剖析

const {Tapable,SyncHook} = require("tapable");
const myCar = new Tapable();
myCar.hooks = {
    myHook: new SyncHook()
};
let speed = 0;
myCar.plugin("my-hook", () => speed+=2);
myCar.hooks.myHook.call();
myCar.plugin("my-hook", () => speed += 10);
myCar.hooks.myHook.call();
console.log(speed);
//输出14

申明
plugin(name:string, handler:function):许可将一个自定义插件注册到 Tapable 实例 的事宜中。它的行动和 EventEmitter 的 on() 要领类似,用来注册一个处置惩罚函数/监听器,来在信号/事宜发作时做一些事变,他终究照样挪用hook.tap(tapOpt, options.fn)举行存储。而call就悉数取出来实行。

总结

上面这些学问是明白插件和webpack运转道理的前置条件,更多内容待下次剖析

参考源码版本申明
tapable: “1.0.0”,
webpack: “^4.2.0”,

参考链接
https://medium.com/webpack/we…
https://medium.com/webpack/we…
https://github.com/dwqs/blog/…
https://doc.webpack-china.org…
https://github.com/webpack/ta…

    原文作者:jsdt
    原文地址: https://segmentfault.com/a/1190000014031536
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞