一. plugin概述
1.1 Plugin的作用
plugin
机制是webpack
中另一个外围概念,它基于事件流框架tapable
,你能够参考浏览器环境中的【DOM事件模型】,【SPA模型中的生命周期钩子】或是node环境中的【EventEmitter模块】来了解其作用。plugin
零碎提供给开发者监听webpack
生命周期并在特定事件触发时执行指定操作的能力。
当然,要写一个真正能实现肯定性能的插件,你还须要理解Compiler和Compilation这两个概念,网上能够找到十分多相干的文章(《webpack-docs/plugin》)。
1.2 Compiler
从体现上看,Compiler裸露了和webpack
整个生命周期相干的钩子,通过如下的形式拜访:
//根本写法compiler.hooks.someHook.tap(...)//如果心愿在entry配置结束后执行某个性能compiler.hooks.entryOption.tap(...)//如果心愿在生成的资源输入到output指定目录之前执行某个性能compiler.hooks.emit.tap(...)
webpack
在重要的生命周期节点上都提供了事件钩子,咱们能够借此退出一些自定义的性能。咱们来编写一个插件,直观地看看webpack
中波及的钩子:
//check-compiler-hooks-plugin.jsconst pluginName = 'checkCompilerHooksPlugin';module.exports = class checkCompilerHooksPlugin { apply(compiler){ //打印出entryOption执行结束时Compiler裸露的钩子 for(var hook of Object.keys(compiler.hooks)){ console.log(hook); } }}
能够看到Compiler
上能够应用的钩子(当然这种形式看到的钩子和理论触发程序无关):
留神上图中Compiler.hooks裸露的事件钩子中有一个compilation,下一大节将解释它。
1.3 Compilation
Compilation裸露了与模块
和依赖
无关的粒度更小的事件钩子,官网文档中的说法是模块会经验加载(loaded),封存(sealed),优化(optimized),分块(chunked),哈希(hashed)和从新创立(restored)这几个典型步骤,从下面的示例能够看到,compilation是Compiler生命周期中的一个步骤,应用compilation
相干钩子的通用写法为:
compiler.hooks.compilation.tap('SomePlugin',function(compilation, callback){ compilation.hooks.someOtherHook.tap('SomeOtherPlugin',function(){ .... })});
咱们仿照下面的办法就能够查看到compilation
对象上(compilation事件触发时,在回调函数中获得的援用)裸露的事件钩子。
Compiler和Compilation裸露的事件钩子总数超过30个,具体信息能够间接在官网文档间接查问API,在特定的阶段钩入想要增加的自定义性能。想要更好地了解plugin
的作用机制,还须要理解webpack
的整个生命周期以及事件流框架tapable
.
二. 如何写一个plugin
依据webpack
官网文档的阐明,一个自定义的plugin
须要蕴含:
- 一个javascript命名函数
- 插件函数的prototype上要有一个
apply
办法 - 指定一个绑定到webpack本身的事件钩子
- 注册一个回调函数来解决webpack实例中的指定数据
- 解决实现后调用webpack提供的回调
官网给出了一个根本的构造示例:
//console-log-on-build-webpack-plugin.jsconst pluginName = 'ConsoleLogOnBuildWebpackPlugin';class ConsoleLogOnBuildWebpackPlugin { apply(compiler){ compiler.hooks.run.tap(pluginName, compilation=>{ console.log('webpack构建过程开始'); }); }}
将其增加到webpack插件中后能够看到运行中触发了传入的回调函数:
四. 实战
在《webpack4.0各个击破(4)——javascript & splitChunks》一文中,咱们应用splitChunks
性能对初始模块进行代码宰割,在为多页面利用模型的html入口插入script标签时遇到了无奈主动插入的问题,那么本节咱们用一个webpack-dispatch-chunk-plugin
来解决一下这个问题。
解决的逻辑就是利用html-webpack-plugin
裸露的更改资源标签的事件钩子htmlWebpackPluginAlterAssetTags
来进行资源解决,此时资源曾经离过模块化和代码宰割并曾经在名称中退出了hash标记,只须要此时过滤掉名称中含有vendors
且不蕴含相应入口名称的新的chunk
即可,当然这只是一个基本功能,想要动静实现性能,还须要将上例中checkMap
局部变为对Compiler或是Compilation上对应属性的援用,本篇不再赘述。
【参考】
[1] 《webpack之外部运行机制》