序
接前文plugin
浅析记录我简单自定义了一个plugin代码如下:
class TestP {
constructor() {
console.log('test TestPlugin')
}
apply(complier) {
console.log('test TestPluginApply')
}
}
module.exports = TestP
Tapable提供的插件统一接口的类型有 AsyncParallelHook(异步并行钩子),AsyncSeriesHook(异步串行钩子),SyncHook(同步),SyncBailHook(同步熔断 即返回内容return一个非undefined的值,则不再继续执行后面的监听函数)....10种
注册钩子的方法
- 1.找到需要使用的钩子函数,从官方文档了解钩子的类型
- 2.根据钩子类型,参数类型 挂载方法在插件apply方法中找到对应的周期函数添加自定义事件
complier hooks注册
栗子
egs:使用complier的周期函数 `environment` 为异步钩子
class TestP {
constructor() {
console.log('test TestPlugin')
}
apply(complier) {
console.log('test TestPluginApply')
// 注册到环境准备好执行的周期中 environment为异步钩子
complier.hooks.environment.tap('TestP', () => {
console.log('test plugin environment ')
})
}
}
module.exports = TestP
控制台:
根据钩子的接入类型不一致注册事件的时候写法也有多种异步钩子可以接受多个方法
emit
emit
为 AsyncSeriesHook
异步串行钩子
它挂载的方法是依次执行(同步)的, 可以用tap,tapAsync,tapPromise都能注册只是后续参数不一致按需使用
返回执行内容写上延时
complier.hooks.emit.tap('TestP', (compilation) => {
setTimeout(() => {
console.log('emit1111')
}, 1000)
})
// tapAsync
complier.hooks.emit.tapAsync('TestP', (compilation, callBack) => {
setTimeout(() => {
console.log('emit222')
// 执行返回函数
callBack()
}, 2000)
})
// tapPromise
complier.hooks.emit.tapPromise('TestP', (compilation) => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('emit 3333')
// 执行返回函数
resolve()
}, 1000)
})
})
控制台的结果依旧是同步执行
的结果
make
make从官方文档中看出 make是一个异步并行的钩子,回调方法有一个参数
配置示例 使用同一注册方法 tapAsync:
complier.hooks.make.tapAsync('TestP', (compilation, callBack) => {
setTimeout(() => {
console.log('make11111')
// 执行返回函数
callBack()
}, 3000)
})
complier.hooks.make.tapAsync('TestP', (compilation, callBack) => {
setTimeout(() => {
console.log('make2222')
// 执行返回函数
callBack()
}, 1000)
})
complier.hooks.make.tapAsync('TestP', (compilation, callBack) => {
setTimeout(() => {
console.log('make 3333')
// 执行返回函数
callBack()
}, 2000)
})
编译的结果是异步执行
的结果 打印内容的顺序取决于任务结束的时间
compilation hooks注册
compilation hooks注册使用的方法与上述complier 钩子注册方法一致。 但是需要注意的是由于webpack流程的执行周期中
compilation的钩子函数需要在make函数执行之后 注册才能使用
代码示例如下:
如注册事件到 seal
complier.hooks.make.tapAsync('TestP', (compilation, callBack) => {
// // seal为异步钩子
// 在complation 的钩子函数需要在make函数执行之后注册才能使用
compilation.hooks.seal.tap('TestP', () => {
console.log('test seal')
})
setTimeout(() => {
console.log('make 3333')
// 执行返回函数
callBack()
}, 2000)
})
总结
钩子事件的注册也是严格遵循webpack的流水线工作顺序,不会因为上下文关系的顺序执行不同的事件,刚好又回到了《webpack深入浅出》书中所说的话:“插件需要监听所有与他有关的事,这样才能加入到流水线中去改变生产线的运作
”