webpack 手写插件流程
引言
插件介绍
相比于loader,plugin拥有更宽的能力范围,它几乎能触及到webpack工作的每一个环节 原理:plugin通过勾子机制实现 在webpack工作的过程中,会有很多个环节,为了便于插件的扩展,webpack几乎为每一个环节都埋下了一个勾子,开发插件时,就可以往这些节点上挂载不同的任务,以扩展webpack的能力
webpack具体有哪些勾子:
官网勾子链接
并且webpack要求plugin必须是一个函数或者是一个包含apply方法的对象
开始
做一个能去除webpack打包注释的插件
// myPlugin.js
class MyPlugin{
// compiler => webpack配置对象
apply(compiler){
console.log('MyPlugin 启动')
// 调用emit勾子,挂载函数
// compilation => 此次打包的上下文
compiler.hooks.emit.tap('MyPlugin', compilation => {
// 遍历资源文件信息
// 键name为每个资源的名称
for(const name in compilation.assets){
// console.log(name)
if(name.endsWith('.js')){
// 每个资源的值
const contents = compilation.assets[name].source()
const withoutComments = contents.replace(/\/\*\*+\*\//g,'')
// 覆盖原始对象
compilation.assets[name] = {
source: () => withoutComments,
size: () => withoutComments.length
}
}
}
})
}
}
module.exports = MyPlugin
webpack.config.js
const MyPlugin = require('./myPlugin')
plugins: [
...
new MyPlugin()
],
解读:
- apply方法接受一个compiler对象参数,该对象就是webpack工作中最核心的一个对象,它包含了此次构建过程中所有的配置信息,并且我们也通过它来注册我们的勾子函数
- 此次选择了emit勾子,因为去掉注释需要bundle.js里的代码已生成
- 遍历资源文件compilation.assets,name为每个资源的名称
- 拿到对应名称的资源compilation.assets[name].source(),然后做全局注释的替换replace
- 最后在覆盖回assets的原有属性,source和size
自此,myPlugin就算完成
效果:
总结
webpack还有很多其他的勾子,可以实现很多其他我们想要的功能,详细可以到webpack官网查看 --配图椰香大芒果
往期精彩文章
转载自:https://juejin.cn/post/7106309142041591845