写一个webpack plugin

plugins是可以用自身原型方法apply来实例化的对象。apply只在安装插件被Webpack compiler执行一次。apply方法传入一个webpck compiler的引用,来访问编译器回调。

plugins基本结构

class HelloPlugin{
  // 在构造函数中获取用户给该插件传入的配置
  constructor(options){
  }
  // Webpack 会调用 HelloPlugin 实例的 apply 方法给插件实例传入 compiler 对象
  apply(compiler) {
    // 在emit阶段插入钩子函数,用于特定时机处理额外的逻辑;
    compiler.hooks.emit.tap('HelloPlugin', (compilation) => {
      // 在功能流程完成后可以调用 webpack 提供的回调函数;
    });
    // 如果事件是异步的,会带两个参数,第二个参数为回调函数,在插件处理完任务时需要调用回调函数通知webpack,才会进入下一个处理流程。
    compiler.plugin('emit',function(compilation, callback) {
      // 支持处理逻辑
      // 处理完毕后执行 callback 以通知 Webpack 
      // 如果不执行 callback,运行流程将会一直卡在这不往下执行 
      callback();
    });
  }
}
module.exports = HelloPlugin;

  

webpack Plugin的工作原理

  1. 读取配置的过程中会先执行 new HelloPlugin(options) 初始化一个 HelloPlugin 获得其实例。

  2. 初始化 compiler 对象后调用 HelloPlugin.apply(compiler) 给插件实例传入 compiler 对象。

  3. 插件实例在获取到 compiler 对象后,就可以通过compiler.plugin(事件名称, 回调函数) 监听到 Webpack 广播出来的事件。 并且可以通过 compiler 对象去操作 Webpack

参考 webpack 之如何手写一个plugin?_一期一会 - SegmentFault 思否

 

 

 

example:

class FilePlugin {
  constructor(options) {
    this.options = options
  }
  apply(compiler) {
    compiler.hooks.emit.tap('FilePlugin', (compilation) => {
  //
htmlWebpackPluginBeforeHtmlGeneration拓展
    compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration.tapAsync('FilePlugin', (filePluginData, callback) => {
      if (this.options.jsPaths && Array.isArray(this.options.jsPaths) && this.options.jsPaths.length) {
         
this.options.jsPaths.forEach(item => { filePluginData.assets.js.unshift(item) })
      }
      if (this.options.cssPaths && Array.isArray(this.options.cssPaths) && this.options.cssPaths.length) {
        this.options.cssPaths.forEach(item => { filePluginData.assets.css.unshift(item) })
      }
      callback(
null, filePluginData)
    })
  })
 }
}
module.exports
= FilePlugin

 

posted @ 2021-01-28 15:52  yaokunlun  阅读(95)  评论(0编辑  收藏  举报