likes
comments
collection
share

webpack 手写插件流程

作者站长头像
站长
· 阅读数 15

引言

插件介绍

相比于loader,plugin拥有更宽的能力范围,它几乎能触及到webpack工作的每一个环节 原理:plugin通过勾子机制实现 在webpack工作的过程中,会有很多个环节,为了便于插件的扩展,webpack几乎为每一个环节都埋下了一个勾子,开发插件时,就可以往这些节点上挂载不同的任务,以扩展webpack的能力

webpack 手写插件流程

webpack具体有哪些勾子:

webpack 手写插件流程 官网勾子链接 并且webpack要求plugin必须是一个函数或者是一个包含apply方法的对象

开始

做一个能去除webpack打包注释的插件

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()
],

解读:

  1. apply方法接受一个compiler对象参数,该对象就是webpack工作中最核心的一个对象,它包含了此次构建过程中所有的配置信息,并且我们也通过它来注册我们的勾子函数
  2. 此次选择了emit勾子,因为去掉注释需要bundle.js里的代码已生成 webpack 手写插件流程
  3. 遍历资源文件compilation.assets,name为每个资源的名称 webpack 手写插件流程
  4. 拿到对应名称的资源compilation.assets[name].source(),然后做全局注释的替换replace
  5. 最后在覆盖回assets的原有属性,source和size

自此,myPlugin就算完成 效果: webpack 手写插件流程

总结

webpack还有很多其他的勾子,可以实现很多其他我们想要的功能,详细可以到webpack官网查看 --配图椰香大芒果

往期精彩文章