这是我参与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 开始递归分析依赖,准备对每个模块进行 build | compilation | 并行 |
after-compile | 编译 build 过程结束 | compliation | 异步 |
emit | 在将内存中 assets 内容写到磁盘文件夹之前 | compilation | 异步 |
after-emit | 在将内存中 assets 内容写到磁盘文件夹之后 | compilation | 异步 |
done | 完成所有的编译过程 | stats | 同步 |
failed | 编译失败的时候 | error | 同步 |
compilation 对象
compilation 对象代表了一次单一的版本构建和生成资源。
当运行 webpack 时,每当检测到一个文件变化,一次新的编译将被创建,从而生成一组新的编译资源。
一个编译对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。
compilation 对象可以访问所有的模块和它们的依赖(大部分是循环依赖)。在编译阶段,模块被
加载
,封闭
,优化
,分块
,哈希
和重建
等等,这将是编译中任何操作主要的生命周期。
-
normal-module-loader
普通模块 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;
仅供学习参考