插件目的在于解决 loader 无法实现的其他事。本文简单介绍插件的使用方法,对于重要的plugin从原理的角度分析其实现的方法。插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!
Plugins是什么
插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!
webpack事件流
还记得webpack有哪些常用的事件吗?webpack插件起到的作用,就是为这些事件挂载回调,或者执行指定脚本。webpack的事件流是通过 Tapable 实现的,它就和我们的EventEmit一样,是这一系列的事件的生成和管理工具,它的部分核心代码就像下面这样:
在 webpack hook 上的所有钩子都是 Tapable 的示例,所以我们可以通过 tap 方法监听事件,使用 call 方法广播事件,就像官方文档介绍的这样:
几个比较常用的hook我们也已经在前文介绍过了。
Plugins是什么
插件目的在于解决 loader 无法实现的其他事。如果剖析webpack plugin的本质,它实际上和webpack loader一样简单,其实它只是一个带有apply方法的class。
这样就实现了一个简单的webpack plugin,如果我们要使用它,只需要在webpack.config.js
里 require 并实例化就可以了:
每次我们需要使用某个plugin的时候都需要new一下实例化,自然,实例过程中传递的参数,也就成为了我们的构造函数里拿到的options了。
而实例化所有plugin的时机,便是在webpack初始化所有参数的时候,也就是事件流开始的时候。所以,如果配合 shell.js 等工具库,我们就可以在这时候执行文件操作等相关脚本,这就是webpack plugin所做的事情。
如果你想在指定时机执行某些脚本,自然可以使用在webpack事件流上挂载回调的方法,在回调里执行你所需的操作。
Tapable新用
如果我们想赋予webpack事件流我们的自定义事件能够实现嘛?答案是肯定的,可以通过下面的4步实现:
引入Tapable并找到你想用的hook
引入Tapable并找到你想用的hook,同步hook or 异步hook 。
实例化hook
实例化Tapable中你所需要的hook并挂载在compiler或compilation上
监听tap
在你需要监听事件的位置tap监听:
执行call方法
在你所需要广播事件的时机执行call方法并传入数据:
完整代码实现可以参考我在文章最前方贴出的项目,大概就是下面这样:
现在我的自定义插件里实例化一个hook并挂载在webpack事件流上:
|
|
在监听插件里监听我的自定义事件
在webpack配置里引入两个插件并实例化:
输出结果就是这样:
我们拿到了call方法传入的数据,并且成功在environment时机里成功输出了。
实战剖析
来看一看已经被众人玩坏的 html-webpack-plugin ,我们发现在readme底部有这样一段demo:
如果你认真读完了上个板块的内容,你会发现,这个 htmlWebpackPluginAfterHtmlProcessing 不就是这个插件自己挂载在webpack事件流上的自定义事件嘛,它会在生成输出文件准备注入HTML时调用你自定义的回调,并向回调里传入本次编译后生成的资源文件的相关信息以及待注入的HTML文件的内容(字符串形式)供我们自定义操作。在项目搜一下这个钩子:
这不和我们在2.0里说的一样嘛,先实例化我们所需要的hook,从名字就可以看出来只有第一个是同步钩子,另外几个都是异步钩子。然后再找找事件的广播:
和我们刚刚介绍的一模一样对吧,只不过异步钩子使用promise方法去广播,其他不就完全是我们自定义事件的流程。大家如果有兴趣可以去打下console看看 htmlWebpackPluginAfterHtmlProcessing
这个钩子向回调传入的数据,或许你能发现一片新大陆哦。
常用插件
html-webpack-plugin
插件的基本作用就是生成html文件,可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口。另外可以为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题。
html-webpack-plugin的一个实例生成一个html文件,如果单页应用中需要多个页面入口,或者多页应用时配置多个html时,那么就需要实例化该插件多次;
即有几个页面就需要在webpack的plugins数组中配置几个该插件实例:
clean-webpack-plugin
使用webpack4时,使用到了clean-webpack-plugin插件,正常情况下,使用webpack命令进行打包,配置文件如下:
这时由于clean-webpack-plugin作用在打包前都会清除之前的文件,生成新的带有hash值的文件.
extract-text-webpack-plugin【4.0已废弃】
Extact text from bundle into a file, 从bundle中提取出特定的text到一个文件中,使用extract-text-webpack-plugin
就可将css从js中独立抽离出来。简单使用如下:
|
|
它将从每一个用到了require(“*.css”)的entry chunks文件中抽离出css到单独的output文件
参考资料
webpack官方文档
HtmlWebpackPlugin官方教程
webpack4-用之初体验,一起敲它十一遍
Webpack 常见静态资源处理 - 模块加载器(Loaders)+ExtractTextPlugin插件
webpack官方文档
手摸手,带你用合理的姿势使用webpack4(上)