持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
引言
继上一篇 webpack手写loader流程 继续完成webpack手写plugin的流程
需要有一定的webpack基础
插件介绍
相比于loader,plugin拥有更宽的能力范围,它几乎能触及到webpack工作的每一个环节
原理:plugin通过勾子机制实现
在webpack工作的过程中,会有很多个环节,为了便于插件的扩展,webpack几乎为每一个环节都埋下了一个勾子,开发插件时,就可以往这些节点上挂载不同的任务,以扩展webpack的能力
webpack具体有哪些勾子:
官网勾子链接
并且webpack要求plugin必须是一个函数或者是一个包含apply方法的对象
开始
做一个能去除webpack打包注释的插件
webpack.config.js基本结构忽略,基本结构可看上一篇webpack手写loader流程
在第一层目录新建myPlugin.js
// 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官网查看
--配图椰香大芒果
往期精彩文章
🌟两种方式轻松做react css样式隔离
🌟彻底理解redux的中间件原理
🌟canvas实现刮刮奖效果
🌟前端实现pdf下载
🌟web前端性能优化(全汇总)
🌟一句话概括this指向问题
🌟MutationObserver 实现微任务原理分析
🌟遇到几次的大厂笔试题:装饰数组push方法
🌟V8垃圾回收策略与GC算法
🌟浏览器缓存策略(强缓存和协商缓存)
🌟$nextTick 源码解读与原理分析
🌟手动封装适合react hook使用的状态管理工具