2.webpack 插件机制

283 阅读4分钟

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

webpack 插件机制

webpack 插件是一个具有 apply 方法的 JavaScript 对象。apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问。

特点

webpack 插件 先来瞅瞅 webpack 插件在项目中的运用

const MyPlugin = require('myplugin')
const webpack = require('webpack')

webpack({
  ...,
  plugins: [new MyPlugin()]
  ...,
})
  • 那么符合什么样的条件能作为 webpack 插件呢?一般来说,webpack 插件有以下特点:

  • 1.独立的 JS 模块,暴露相应的函数

  • 2.函数原型上的 apply 方法会注入 compiler 对象

  • 3.compiler 对象上挂载了相应的 webpack 事件钩子

  • 4.事件钩子的回调函数里能拿到编译后的 compilation 对象,如果是异步钩子还能拿到相应的 callback

整体结构:

function MyPlugin(options) {}
// 2.函数原型上的 apply 方法会注入 compiler 对象
MyPlugin.prototype.apply = function(compiler) {
  // 3.compiler 对象上挂载了相应的 webpack 事件钩子 4.事件钩子的回调函数里能拿到编译后的 compilation 对象
  compiler.plugin('emit', (compilation, callback) => {
    ...
  })
}
// 1.独立的 JS 模块,暴露相应的函数
module.exports = MyPlugin

compiler 对象

compiler 即 webpack 的编辑器对象,在调用 webpack 时,会自动初始化 compiler 对象

compiler 对象中包含了所有 webpack 可配置的内容,开发插件时,我们可以从 compiler 对象中拿到所有和 webpack 主环境相关的内容。

事件钩子触发时机得到的内容类型
entry-option初始化 option-同步
run开始编译compiler异步
compile真正开始的编译,在创建 compilation 对象之前compilation 参数同步
compilation生成好了 compilation 对象,可以操作这个对象啦compilation同步
make从 entry 开始递归分析依赖,准备对每个模块进行 buildcompilation并行
after-compile编译 build 过程结束compliation异步
emit在将内存中 assets 内容写到磁盘文件夹之前compilation异步
after-emit在将内存中 assets 内容写到磁盘文件夹之后compilation异步
done完成所有的编译过程stats同步
failed编译失败的时候error同步

compilation 对象

compilation 对象代表了一次单一的版本构建和生成资源。
当运行 webpack 时,每当检测到一个文件变化,一次新的编译将被创建,从而生成一组新的编译资源。
一个编译对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。

compilation 对象可以访问所有的模块和它们的依赖(大部分是循环依赖)。在编译阶段,模块被 加载封闭优化分块哈希 和 重建 等等,这将是编译中任何操作主要的生命周期。

普通模块 loader,真实地一个一个加载模块图(分析之后的所有模块一种数据结构)中所有的模块的函数。

模块,就是通常所说的 AMD, CMD 等模块化的模块。

  • seal

编译的封闭已经开始,这个时候再也收不到任何的模块了,进入编译封闭阶段。

  • optimize

优化编译,这个事件钩子特别重要,很多插件的优化工作都是基于这个事件钩子,表示 webpack 已经进入优化阶段

  • optimize-modules

模块的优化

  • optimize-chunks

webpack 的 chunk 优化阶段。可以拿到模块的依赖,loader 等,并进行相应的处理。

  • additional-assets

这是一个异步的事件钩子,在这个阶段可以为 compilation 对象创建额外的 assets,也就是说可以异步的在最后的产物中加入自己自定义的一些资源

  • optimize-chunk-assets

优化 chunk 的 assets 的事件钩子,这个优化阶段可以改变 chunk 的 assets 以达到重新改变资源内容的目的。assets 被存储在 this.assets 中,但是它们并不都是 chunk 的 assets。一个 chunk 有一个 files 属性指出这个 chunk 创建的所有文件。附加的 assets 被存储在 this.additionalChunkAssets 中

  • optimize-assets

优化所有的 assets 的异步事件钩子,在这个阶段可以直接通过 this.assets 拿到所有的 assets,并进行自定义操作。类似 optimize-chunk-assets,但是这个事件钩子的回调是拿不到 chunks 的

webpack 插件示例:

// MyPlugin.js  
function MyPlugin(options) {     
  // Configure your plugin with options... 
}  
MyPlugin.prototype.apply = function (compiler) {     
  compiler.plugin('compile', function (params) {         
    console.log('The compiler is starting to compile...');     
  });      
  compiler.plugin('compilation', function (compilation) {         
    console.log('The compiler is starting a new compilation...');   
    compilation.plugin('optimize', function () {             
      console.log('The compilation is starting to optimize files...');         
    });     
  });      
  // 异步的事件钩子     
  compiler.plugin('emit', function (compilation, callback) {         
    console.log('The compilation is going to emit files...');         
    callback();     
  }); 
};  
module.exports = MyPlugin;

仅供学习参考

参考