Webpack Plugin制作1中的license打包插件不太规范,需要改进。
准备工作
本文的工程环境承接上文
这个简单的工程目录如下:
- build
- node_modules
- package.json
- plugins
- 0.createLicense.js
- 1.createFileList.js
- loaders
- src
- index.js
- LICENSE
简单分析
细心的话,可以发现上一节中文件列表并不包含LICENSE.txt, 虽然build目录实际上是有的。
# In this build:
- bundle.js
- index.html
这很正常,因为我们写插件的时候实际上是撇开webpack单干,和它的交互仅仅是初始化传递参数和被调用。
这相当于另起炉灶了,这样子显然webpack不会知道你悄悄的对输出目录做了什么手脚。
现在看起来没什么,但是当情况复杂,在你开发调试的时候,会发现问题很大。
例如,devServer,它对接的是webpack放在内存里的内容;以及模块热重载、sourcemap等等。
要利用这些强大的特性,我们必须理解并follow这一套流程。
具体要怎么做呢?
我们可以参考上一节的官方示例,依葫芦画瓢。
这里要注意的是,虽然我们也可以和汇总文件列表插件一样,选择在处理assets的总结阶段进行LICENSE的新增工作。
但是这样子我们目标的功能实现可能会有问题。会与插件实例在webpack配置的plugin数组中的位置产生关系。
也就是说,如果汇总文件插件的位置比LICENSE插件靠前,那么markdown文件里面仍旧不会记录LICENSE.txt。
为此,我们将生成并提交新增asset的时机前移:
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE×- stage: Compilation.PROCESS_ASSETS_STAGE_PRE_PROCESS √
插件实现
const pluginName = 'CreateLicensePlugin';
const fs = require("fs");
const { resolve } = require("path");
class CreateLicensePlugin {
constructor(options = {}) {
this.licensePath = options.licensePath || './LICENSE'
}
apply(compiler) {
const { hooks, options, webpack } = compiler;
const outputPath = options.output.path
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
compilation.hooks.processAssets.tap({
name: pluginName,
// https://github.com/webpack/webpack/blob/main/lib/Compilation.js#L5062
// 在最初阶段添加LICENSE
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_PRE_PROCESS,
}, (assets) => {
// 将LICENSE读取并添加到assets
if (fs.existsSync(this.licensePath)) {
const data = fs.readFileSync(this.licensePath);
compilation.emitAsset(
'LICENSE.txt',
new webpack.sources.RawSource(data)
);
} else {
console.error(`${this.licensePath} is not exist!`)
}
});
});
}
}
module.exports = CreateLicensePlugin;
源代码
https://github.com/nicennnnnnnlee/webpack-plugin-loader-examples