compress-assets-plugin
2024年04月06日
一、认识
compress-assets-plugin
可以将本次打包生成出的所有资源打包成为一个 zip
包额外输出。主要逻辑如下所示:
-
通过
compiler.hooks.emit
钩子访问compilation
对象 -
通过
compilation.getAssets()
获取本次打包生成所有的assets
资源 -
实例化
jszip
对象, 循环assets
资源并往zip
对象中添加资源名称和源代码内容 -
调用
zip.generateAsync
生成zip
包, 通过compilation.emitAsset
输出到this.output
二、实现
const JSZip = require('jszip');
const { RawSource } = require('webpack-sources');
const pluginName = 'CompressAssetsPlugin';
class CompressAssetsPlugin {
constructor(options) {
this.options = options;
this.output = options.output;
}
apply(compiler) {
compiler.hooks.emit.tapAsync(pluginName, (compilation, callback) => {
// 创建 zip 对象
const zip = new JSZip();
// 获取本次打包生成所有的 assets 资源
const assets = compilation.getAssets();
// 循环每一个资源
assets.forEach(asset => {
const { name, source } = asset;
// 调用 source() 方法获得对应的源代码 这是一个源代码的字符串
const sourceCode = source.source();
// 往 zip 对象中添加资源名称和源代码内容
zip.file({ name, sourceCode });
});
// 调用 zip.generateAsync 生成 zip 压缩包
zip.generateAsync({ type: 'nodebuffer' }).then(result => {
// 通过 new RawSource 创建压缩包
// 并且同时通过 compilation.emitAsset 方法将生成的 Zip 压缩包输出到 this.output
compilation.emitAsset(this.output, new RawSource(result));
// 调用 callback 表示本次事件函数结束
callback();
});
});
}
}
module.exports = CompressAssetsPlugin;
三、测试
3.1 webpack.config.js
const path = require('path');
const CompressAssetsPlugin = require('../core/index.js');
module.exports = {
devtool: false,
mode: 'development',
entry: {
main: path.resolve(__dirname, './index.js')
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new CompressAssetsPlugin({
output: 'result.zip'
})
]
};
3.2 package.json
"compress-assets": "webpack --config ./plugins/compressAssetsPlugin/example/webpack.config.js"