webpack原理篇(六十五):实战开发一个压缩构建资源为zip包的插件

Posted 凯小默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack原理篇(六十五):实战开发一个压缩构建资源为zip包的插件相关的知识,希望对你有一定的参考价值。

说明

玩转 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 的。

以上是关于webpack原理篇(六十五):实战开发一个压缩构建资源为zip包的插件的主要内容,如果未能解决你的问题,请参考以下文章

webpack原理篇(六十四):更复杂的插件开发场景

webpack原理篇(六十一):更复杂的 loader 的开发场

webpack原理篇(六十):使用 loader-runner 高效进行 loader 的调试

webpack原理篇(六十三):插件基本结构介绍

webpack拓展篇(六十九):vite 的构建原理(完结)

webpack进阶篇(二十五):webpack打包组件和基础库