【重学webpack系列——webpack5.0】
1-15节主要讲webpack的使用,当然,建议结合《webpack学完这些就够了》一起学习。
从16节开始,专攻webpack原理,只有深入原理,才能学到webpack设计的精髓,从而将技术点运用到实际项目中。
可以点击上方专栏订阅哦。
以下是本节正文:
- tapable 是一个类似于 Node.js 中的 EventEmitter的库,但更专注于自定义事件的触发和处理
- webpack本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是Tapable。Tapable其实就是一个用于事件发布订阅执行的插件架构。webpack 通过 tapable 将实现与流程解耦,所有具体实现通过插件的形式存在。
- tapable核心原理:发布订阅模式。
1.tapable的使用
tapable在webpack中被广泛应用,先来看看tapable是怎么使用的吧~
let { SyncHook } = require("tapable");
let syncHook = new SyncHook();
syncHook.tap("name1", (...args) => { // 监听,类似events的on
console.log('name1', ...args)
})
syncHook.tap("name2", (...args) => {
console.log("name2", ...args);
})
syncHook.tap("name2", (...args) => {
console.log("name22", ...args);
})
syncHook.call("name2", 'a', 'b'); // 触发
/*
结果为
name1
name2
name22
*/
- 可见tapable这个库,监听用
tap
,触发用call
,且上面无论是箭头还是触发的第一个参数,也就是name,是没有任何意义的
2.手写tapable
module.exports = class SyncHook {
constructor(){
this.events = []
}
tap(eventName, callback){
this.events.push(callback);
}
call(eventName, ...args){
this.events.forEach(fn => fn(...args))
}
}
3.优化tapable
优化tapable,使得其能指定触发某一个事件
module.exports = class SyncHook {
constructor(){
this.events = {}
}
tap(eventName, callback){
if (this.events[eventName]) {
this.events[eventName].push(callback)
} else {
this.events[eventName] = [callback];
}
}
call(eventName, ...args){
if (eventName && this.events[eventName]) {
this.events[eventName].forEach(fn => fn());
} else if (!eventName) {
Object.keys(this.events).forEach(e => {
this.events[e].forEach(fn => fn(...args))
})
}
}
}
4.关于tapable的钩子函数
可以参照以下链接:
25、tapable(1)——介绍_俞华的博客-CSDN博客
26、tapable(2)——SyncHook_俞华的博客-CSDN博客
27、tapable(3)——SyncBailHook_俞华的博客-CSDN博客