- afterEmit:文件已经写入磁盘完成
- done:完成编译
WebPack 编译流程图原图出自:https://blog.didiyun.com/index.php/2019/03/01/webpack/
看完之后,如果还是看不懂或者对缕不清webpack构建流程的话,建议通读一下全文,再回来看这段话,相信一定会对webpack构建流程有很更加深刻的理解 。
理解事件流机制 Tapablewebpack本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是Tapable 。
Webpack 的 Tapable 事件流机制保证了插件的有序性,将各个插件串联起来,Webpack 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条webapck机制中,去改变webapck的运作,使得整个系统扩展性良好 。
Tapable也是一个小型的 library,是Webpack的一个核心工具 。类似于node中的events库,核心原理就是一个订阅发布模式 。作用是提供类似的插件接口 。
webpack中最核心的负责编译的Compiler和负责创建bundles的Compilation都是Tapable的实例,可以直接在 Compiler 和 Compilation 对象上广播和监听事件,方法如下:
/*** 广播事件* event-name 为事件名称,注意不要和现有的事件重名*/compiler.apply('event-name',params);compilation.apply('event-name',params);/*** 监听事件*/compiler.plugin('event-name',function(params){});compilation.plugin('event-name', function(params){});
Tapable类暴露了tap、tapAsync和tapPromise方法,可以根据钩子的同步/异步方式来选择一个函数注入逻辑 。tap 同步钩子
compiler.hooks.compile.tap('MyPlugin', params => { console.log('以同步方式触及 compile 钩子 。')})
tapAsync 异步钩子,通过callback回调告诉Webpack异步执行完毕tapPromise 异步钩子,返回一个Promise告诉Webpack异步执行完毕compiler.hooks.run.tapAsync('MyPlugin', (compiler, callback) => { console.log('以异步方式触及 run 钩子 。') callback()})compiler.hooks.run.tapPromise('MyPlugin', compiler => { return new Promise(resolve => setTimeout(resolve, 1000)).then(() => { console.log('以具有延迟的异步方式触及 run 钩子') })})
Tabable用法const { SyncHook, SyncBailHook, SyncWaterfallHook, SyncLoopHook, AsyncParallelHook, AsyncParallelBailHook, AsyncSeriesHook, AsyncSeriesBailHook, AsyncSeriesWaterfallHook } = require("tapable");
文章插图
tapable
简单实现一个 SyncHook
class Hook{ constructor(args){ this.taps = [] this.interceptors = [] // 这个放在后面用 this._args = args } tap(name,fn){ this.taps.push({name,fn}) }}class SyncHook extends Hook{ call(name,fn){ try { this.taps.forEach(tap => tap.fn(name)) fn(null,name) } catch (error) { fn(error) } }}
tapable是如何将webapck/webpack插件关联的?Compiler.jsconst { AsyncSeriesHook ,SyncHook } = require("tapable");//创建类class Compiler { constructor() { this.hooks = { run: new AsyncSeriesHook(["compiler"]), //异步钩子 compile: new SyncHook(["params"]),//同步钩子 }; }, run(){ //执行异步钩子 this.hooks.run.callAsync(this, err => { this.compile(onCompiled); }); }, compile(){ //执行同步钩子 并传参 this.hooks.compile.call(params); }}module.exports = Compiler
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 翡翠|半岛调查 | 入“局”两年多,“败”光上亿元!整容术、开美颜… 赌石套路大揭秘→
- MySQL 安装 MariaDB Audit Plugin 插件,实现审计日志输出
- 中医揭秘:中成药、颗粒剂、代煎药、自己煎药,哪个效果最好?
- ps动画插件Animator Photoshop汉化版功能介绍
- win10上帝模式大揭秘,体验深藏不露的神秘功能
- 社保和商业保险住院都有补贴?一文揭秘这几个真相
- 揭秘财神爷厚爱的家居色彩风水 禁忌7种颜色
- 木工打柜子和定制柜谁更好?价格差距有多大?10年老师傅大揭秘
- |猎头揭秘:年薪500万的高端人士,专业造假你无法想象
- 揭秘 Shopify 的软件发布流程,如何做到合并上千程序员的工作?