跳到主要内容

compress-assets-plugin

2024年04月06日
柏拉文
越努力,越幸运

一、认识


compress-assets-plugin 可以将本次打包生成出的所有资源打包成为一个 zip 包额外输出。主要逻辑如下所示:

  1. 通过 compiler.hooks.emit 钩子访问 compilation 对象

  2. 通过 compilation.getAssets() 获取本次打包生成所有的 assets 资源

  3. 实例化 jszip 对象, 循环 assets 资源并往 zip 对象中添加资源名称和源代码内容

  4. 调用 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"