webpack
做为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高。本系列是笔者本身的学习记录,比较基础,但愿经过问题 + 解决方式的模式,之前端构建中遇到的具体需求为出发点,学习webpack
工具中相应的处理办法。(本篇中的参数配置及使用方式均基于webpack4.0版本
)javascript
plugin
机制是webpack
中另外一个核心概念,它基于事件流框架tapable
,你能够参考浏览器环境中的【DOM事件模型】,【SPA模型中的生命周期钩子】或是node环境中的【EventEmitter模块】来理解其做用。plugin
系统提供给开发者监听webpack
生命周期并在特定事件触发时执行指定操做的能力。html
固然,要写一个真正能实现必定功能的插件,你还须要了解Compiler和Compilation这两个概念,网上能够找到很是多相关的文章(《webpack-docs/plugin》)。前端
从表现上看,Compiler暴露了和webpack
整个生命周期相关的钩子,经过以下的方式访问:java
//基本写法 compiler.hooks.someHook.tap(...) //若是但愿在entry配置完毕后执行某个功能 compiler.hooks.entryOption.tap(...) //若是但愿在生成的资源输出到output指定目录以前执行某个功能 compiler.hooks.emit.tap(...)
webpack
在重要的生命周期节点上都提供了事件钩子,咱们能够借此加入一些自定义的功能。咱们来编写一个插件,直观地看看webpack
中涉及的钩子:node
//check-compiler-hooks-plugin.js const pluginName = 'checkCompilerHooksPlugin'; module.exports = class checkCompilerHooksPlugin { apply(compiler){ //打印出entryOption执行完毕时Compiler暴露的钩子 for(var hook of Object.keys(compiler.hooks)){ console.log(hook); } } }
能够看到Compiler
上可使用的钩子(固然这种方式看到的钩子和实际触发顺序无关):
webpack
注意上图中Compiler.hooks暴露的事件钩子中有一个compilation,下一小节将解释它。git
Compilation暴露了与模块
和依赖
有关的粒度更小的事件钩子,官方文档中的说法是模块会经历加载(loaded),封存(sealed),优化(optimized),分块(chunked),哈希(hashed)和从新建立(restored)这几个典型步骤,从上面的示例能够看到,compilation是Compiler生命周期中的一个步骤,使用compilation
相关钩子的通用写法为:github
compiler.hooks.compilation.tap('SomePlugin',function(compilation, callback){ compilation.hooks.someOtherHook.tap('SomeOtherPlugin',function(){ .... }) });
咱们仿照上面的方法就能够查看到compilation
对象上(compilation事件触发时,在回调函数中取得的引用)暴露的事件钩子。web
Compiler和Compilation暴露的事件钩子总数超过30个,具体信息能够直接在官方文档直接查询API,在特定的阶段钩入想要添加的自定义功能。想要更好地理解
plugin
的做用机制,还须要了解webpack
的整个生命周期以及事件流框架tapable
.浏览器
根据webpack
官方文档的说明,一个自定义的plugin
须要包含:
apply
方法官网给出了一个基本的结构示例:
//console-log-on-build-webpack-plugin.js const 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以内部运行机制》