说明
玩转 webpack 学习笔记
要求
- 生成的 zip 包文件名称可以通过插件传入
- 需要使用 compiler 对象上的特地 hooks 进行资源的生成
Node.js 里面将文件压缩为 zip 包
使用 jszip:https://github.com/Stuk/jszip
jszip 使用示例
var zip = new JSZip(); zip.file("Hello.txt", "Hello World\n"); var img = zip.folder("images"); img.file("smile.gif", imgData, { base64: true }); zip.generateAsync({ type: "blob" }).then(function (content) { // see FileSaver.js saveAs(content, "example.zip"); });
Compiler 上负责文件生成的 hooks
Hooks 是 emit,是一个异步的 hook (AsyncSeriesHook),emit 生成文件阶段,读取的是 compilation.assets 对象的值
可以将 zip 资源包设置到 compilation.assets 对象上
实战
1、复制上次的 my-plugin 文件夹
复制一下上次的插件环境,修改一下名称为 zip-plugin
相关的名称
2、安装 jszip 依赖
npm i jszip -S
3、编写 zip-plugin.js
const JSzip = require('jszip'); const zip = new JSzip(); const path = require('path'); const RawSource = require('webpack-sources').RawSource; class ZipPlugin { constructor(options) { this.options = options; } apply(compiler) { // emit 是异步的,这里需要使用 tapAsync compiler.hooks.emit.tapAsync('ZipPlugin', (compilation, callback) => { // 创建一个目录,读取传参 filename const folder = zip.folder(this.options.filename); for (let filename in compilation.assets) { // 打印的是 RawSource console.log(compilation.assets[filename]); const source = compilation.assets[filename].source(); console.log('source---->', source); // 把内容添加到 folder folder.file(filename, source); } // 生成 zip zip.generateAsync({ type: 'nodebuffer' }).then(content => { console.log('content---->', content); console.log('compilation.options--->', compilation.options); // 绝对路径 const outputPath = path.join( compilation.options.output.path, this.options.filename + '.zip' ) console.log("绝对路径--->", outputPath); // 相对路径 const outputRelativePath = path.relative( compilation.options.output.path, outputPath ); console.log("相对路径--->", outputRelativePath); // 将内容挂载到assets上面去 使用 RawSource 将 buffer 转为 source compilation.assets[outputRelativePath] = new RawSource(content); // 执行 callback callback(); }) }) } } module.exports = ZipPlugin;
compilation.assets[filename]
source
content
compilation.options
4、打包测试
执行 webpack
我们可以解压一下这个文件,发现是 ok 的。