day02: 开发一个plugin
2021-05-27 本文已影响0人
云海成长
知识回顾
plugin,是插件,loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。贯穿打包的整个生命周期,插件的执行利用webpack的钩子函数。
钩子机制也特别容易理解,它有点类似于 Web 中的事件。在 Webpack 整个工作过程会有很多环节,为了便于插件的扩展,Webpack 几乎在每一个环节都埋下了一个钩子。这样我们在开发插件的时候,通过往这些不同节点上挂载不同的任务,就可以轻松扩展 Webpack 的能力。
plugin常见的钩子:
- compiler Hooks
- compilation Hooks
- ContextModuleFactory Hooks
- JavascriptParser Hooks
- NormalModuleFactory Hooks
到这里,还是在说一些理论的知识,具体一点,plugin到底是什么?该如何使用?举个例子,每次使用webpack打包的时候,要手动把打包好的bundle引入到index.html里,为了解决这个问题,可以使用html-webpack-plugin插件。遵循以下步骤:
- 安装依赖的插件
npm i -D http-webpack-plugin
- 在配置文件webpack.config.js里引入该插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
- 在配置文件webpack.config.js里的plugins配置项里实例化该插件
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
]
完成以上步骤,我们每次打包,webpack都会以index.html为模板,自动引入打包好的bundle,并将新的index.html输出。我们已经会简单使用plugin了,那么如何自定义插件呢?
一个简单的插件
一个插件本质上是一个方法或者一个带apply方法的类,本文使用后者自定义一个插件,用于去掉bundle里的/** **/注释,可知这个插件的执行时间点在输出 asset 到 output 目录之前执行,于是应该使用emit钩子函数。步骤如下:
- 创建一个文件self-plugin.js,内容如下
class SelfPlugin {
constructor(options) {
console.log(options)
}
apply(compiler) {
compiler.hooks.emit.tap('SelfPlugin', compilation => {
// compilation => 可以理解为此次打包的上下文
for (const name in compilation.assets) {
const contents = compilation.assets[name].source()
const noComments = contents.replace(/\/\*{2,}\/\s?/g, '')
compilation.assets[name] = {
source: () => noComments,
size: () => noComments.length
}
}
})
}
}
// export default SelfPlugin
module.exports = SelfPlugin
这个插件包含apply方法,apply方法接收compiler对象,绑定该对象上的emit钩子函数(还有其他的钩子函数,详情参见官方文档),webpack打包过程中触发该钩子函数,于是插件得以施展作用。
- 在配置文件webpack.config.js里引入该插件
const SelfPlugin = require('./src/self-plugin')
- 在配置文件webpack.config.js里的plugins配置项里实例化该插件
plugins: [
new SelfPlugin({
name: 'testName'
}),
]
至此,一个简单的插件就开发完成啦。