0
核心思想:看文档
1. 明确定义
在编写一个插件之前,首先要区分编译器和编译过程
编译器(compiler)
一般是一个对象,表示配置的Webpack环境,在启动的时候就进行构建,包括了选项,加载程序等信息
编译过程(compilation)
代表一次资源的构建过程,每次进行文件更改后都会生成一个新的编译过程,会显示有关模块资源、已编译资 源、已更改⽂件和已监视依赖项的当前状态的信息。
2. 编写方法
不考虑已经过时的原型方法
class No1WebpackPlugin {
constructor (options) {
this.options = options
}
apply (compiler) {
complier.hooks.done.tap('HelloWorldPlugin', compilation => {
console.log('hello world!!!!')
})
}
}
module.exports = No1WebpackPlugin;
可以观察到,核心在于编译器所使用的钩子以及其应用的过程
参数
简单来说,用到的参数,就是规定一个用于Webpack编译过程的钩子,文档
-
Hooks类表示的是钩子是哪一种类型的,比如上面用到的done,它就属于AsyncSeriesHook这个类 -
tap、tapAsync、tapPromise这三个方法是用于注入不同类型的自定义构建行为
3.使用
以一个生成文件列表的插件为例
class FilelistPulgin {
constructor(options) {
this.options = options
this.filename = this.options.filename || "filelist.md"
}
apply (compiler) {
compiler.hooks.emit.tapAsync("filelist", (compilation,callback) => {
const filename = this.filename
const fileListName = this.filename;
let len = Object.keys(compilation.assets).length;
let content = `# 一共有${len}个文件\n\n`;
for (let filename in compilation.assets) {
content += `- ${filename}\n`
}
compilation.assets[fileListName] = {
// 7.
source: function () {
return content;
},
// 8.
size: function () {
return content.length;
}
}
// 9.
callback()
})
}
}
module.exports = FilelistPulgin
-
通过
compiler.hooks.emit.tapAsync()来触发生成资源到output目录之前的钩子,且回调函数会有两个参数,一个是compilation,一个是callback回调函数 -
通过
compilation.assets获取到所有待生成的文件,这里是获取它的长度
然后再config中编写下面的内容
添加引入const FilelistPulgin = require("./plugins/file-list")
new FilelistPulgin({ filename: "filelist.md" })
npm run build后就可以看到dist目录里出现了一个展示文件列表的md文件