说明
- 这套笔记是对于
webpack 5.x
进行阐述的。(webpack <= 4
用法稍有不同)
概述:
插件是 webpack
的支柱功能。Webpack 自身也是构建于你在 webpack 配置中用到的相同的插件系统之上!
plugin 和 loader 的不同
loader 是为了解决 webpack 内置功能不足而进行的扩展,而 plugin 是在 webpack 自身的 compiler 上监听和操作流程。
plugin 的特点
- webpack 插件是一个具有 apply 方法的 JavaScript 对象。apply 方法会被 webpack compiler 调用,并且在 整个编译生命周期都可以访问 compiler 对象。
- 为什么 webpack 的插件大多数是用 class 写的呢?由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入一个 new 实例。(取决于你的 webpack 用法,对应有多种使用插件的方式。)
常用的插件
插件名称 | 插件说明 |
---|---|
html-webpack-plugin |
在 webpack 运行时创建一个带有打包好的 js 的 html 文件的 plugin |
vue-loader.VueLoaderPlugin |
解析 vue SFC 文件的 plugin 的plugin |
clean-webpack-plugin |
清除上一次打包内容的 plugin |
mini-css-extract-plugin |
提取样式到 css 文件中 |
css-minimizer-webpack-plugin |
压缩 css 文件 |
uglifyjs-webpack-plugin |
压缩 js 文件的 plugin (webpack 3 以前使用) |
terser-webpack-plugin |
压缩 js 文件的 plugin |
clean-webpack-plugin |
清空之前打包的内容(webpack5 内置) |
以 html-webpack-plugin
为例:
js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// ...
new HtmlWebpackPlugin({
template: resolve(__dirname, 'public/index.html'),
filename: 'index.html',
title: '首页',
chunks: ['index'],
excludeChunks: ['node_modules'],
minify: {
removeComments: true,
collapseWhitespace: true
}
})
// ...
};
如果我想写一个插件,怎么办?
实现思路
- webpack 的
plugins
属性接收一个数组,里面都是一个含有apply
方法(包含形参 compiler 对象)的对象 - webpack 的插件基本上都是 new 出来的
所以,我们可以写一个包含 apply
成员方法的一个类来实现一个我们的插件。
具体步骤
以实现 TestPlugin
为例:
markdown
|- plugins # 插件目录
|- test-plugin
|- index.js # 导出 TestPlugin 的文件
|- ...
|- ... # 其他自定义插件
|- src
|- ... # 业务代码
|- webpack.config.js
- 写一个包含
apply
成员方法的类,命名为TestPlugin
并导出
js
class TestPlugin {
constructor(options) {
this.userOptions = options || {}; // 接收用户传递过来的插件
this.pgName = 'TestPlugin'; // 默认配置 name
this.version = '1.0.0'; // 默认配置 version
}
/** @param {import('webpack').Compiler} compiler */
apply(compiler) {
console.log("this.userOptions", this.userOptions);
const { pgName, version } = this;
compiler.hooks.run.tap(pgName, (compilation) => { // compilation === compiler -> true
console.log();
console.log('🔥🔥🔥 正在启用 TestPlugin !!! 🔥🔥🔥 ');
console.log(`
参数:
名称:"${pgName}"
版本:"${version}"
`);
console.log('==== 开始走流程。。。 ====');
console.log('==== 流程走完了!!! ====');
console.log('==== 🔥🔥🔥 TestPlugin 启用完毕 !!! ==== 🔥🔥🔥 ');
});
}
}
module.exports = new TestPlugin();
module.exports.TestPlugin = TestPlugin;
- 在
webpack.config.js
注册一下这个插件
js
const { TestPlugin } = require('./plugins/test-plugin');
const config = {
// ...
plugins: [
// ...
new TestPlugin({
foo: 'Foo'
})
],
// ...
};
module.exports = config;