本文参考了:超硬核|带你畅游在 Webpack 插件开发者的世界
需求
需要把打包的所有产物压缩到一个 zip 文件中
可以定义文件名
思路
实现
查阅文档可知 emit 为在文件输出前的钩子,该钩子为异步串行钩子,其回调参数为 compilation 对象
compilation 对象能通过 getAssets 函数获得所有的资源数组
我们通过 typescript 类型声明文件发现,asset 对象结构如下

其中的 source 对象结构如下

其中的 source 函数就是我们所需要的
继续查阅文档得知 compilation.emitAsset 方法可以增加输出的文件
其第二个参数 source 对象需要通过 webpack-source 这个库来创建
最后实现的完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| import JSZip from 'jszip'; import { RawSource } from 'webpack-sources';
const pluginName = 'CompressAssetsPlugin'; class CompressAssetsPlugin { constructor({ output }) { this.output = output; }
apply(compiler) { compiler.hooks.emit.tapAsync(pluginName, (compilation, callback) => { const zip = new JSZip(); const assets = compilation.getAssets(); assets.forEach(({ name, source }) => { zip.file(name, source.source()); }); zip.generateAsync({ type: 'nodebuffer' }).then((result) => { compilation.emitAsset(this.output, new RawSource(result)); callback(); }); }); } }
export default CompressAssetsPlugin;
|
使用
在配置文件中引入插件并使用

打包产物
