archiver、jszip 和 pizzip 都是用于处理压缩归档文件(主要是 ZIP 格式)的 JavaScript 库,但它们的运行环境和设计目标截然不同。
archiver 是 Node.js 环境下的流式归档生成器,专为服务器端处理大文件设计,支持管道流式传输,避免内存溢出。
jszip 是一个通用的压缩库,既支持 Node.js 也支持浏览器,它在内存中构建 ZIP 文件,API 友好,适合中小型文件的读写。
pizzip 同样支持浏览器和 Node.js,但它的生态位更窄,通常与 docxtemplater 配合用于生成 Office 文档,对二进制内容的处理有特定优化。
在 JavaScript 生态中处理 ZIP 压缩文件时,开发者常面临三个主要选择:archiver、jszip 和 pizzip。虽然它们都能生成 ZIP 文件,但底层机制、运行环境和适用场景差异巨大。选错工具可能导致浏览器崩溃、服务器内存溢出或代码难以维护。让我们从架构师的角度深入对比。
archiver 是纯粹的 Node.js 库。
stream 模块。// archiver: 仅适用于 Node.js
const archiver = require('archiver');
const output = fs.createWriteStream('archive.zip');
const archive = archiver('zip');
archive.pipe(output);
archive.append(fs.createReadStream('file.txt'), { name: 'file.txt' });
archive.finalize();
jszip 是跨平台的。
// jszip: 浏览器或 Node.js 均可
const JSZip = require('jszip');
const zip = new JSZip();
zip.file('file.txt', 'Hello World');
zip.generateAsync({ type: 'blob' }).then(function(content) {
// 在浏览器中可触发下载
saveAs(content, 'archive.zip');
});
pizzip 同样支持全平台。
jszip。// pizzip: 浏览器或 Node.js 均可
const PizZip = require('pizzip');
const zip = new PizZip();
zip.file('file.txt', 'Hello World');
// 生成同步或异步取决于配置,通常用于文档二进制流
const content = zip.generate({ type: 'blob' });
这是三者最核心的架构差异,直接影响性能上限。
archiver 使用流式处理(Streaming)。
// archiver: 流式管道,内存友好
const archive = archiver('zip', { zlib: { level: 9 } });
// 直接管道到 HTTP 响应,无需等待全部完成
archive.pipe(res);
// 可以持续添加文件流
archive.append(fs.createReadStream('large-file.log'), { name: 'log.txt' });
archive.finalize();
jszip 使用内存加载(In-Memory)。
// jszip: 全量内存加载
const zip = new JSZip();
// 文件内容必须完全读取
zip.file('large-file.log', fs.readFileSync('large-file.log'));
// generateAsync 会阻塞直到所有数据压缩完成
const content = await zip.generateAsync({ type: 'nodebuffer' });
pizzip 同样基于内存加载。
jszip 类似,不适合超大文件。// pizzip: 全量内存加载
const zip = new PizZip();
zip.file('document.xml', binaryContent);
// generate 通常返回完整内容
const content = zip.generate({ type: 'base64' });
archiver 基于事件和流。
.pipe() 连接目标,通过事件监听进度。// archiver: 事件驱动
archive.on('progress', function(data) {
console.log('Progress:', data.entries.processed);
});
archive.on('error', function(err) {
throw err;
});
jszip 基于 Promise。
async/await 结合。generateAsync 明确表明异步操作。// jszip: Promise 链
try {
const content = await zip.generateAsync({
type: 'blob',
compression: 'DEFLATE',
compressionOptions: { level: 9 }
});
console.log('Zip generated');
} catch (err) {
console.error('Generation failed', err);
}
pizzip 混合风格。
generate(),但也支持回调。// pizzip: 同步或回调
const content = zip.generate({
type: 'blob',
compression: 'DEFLATE'
});
// 或者
zip.generate(function(err, data) {
if (err) throw err;
console.log('Done');
});
这是 pizzip 存在的核心理由。
archiver 不特定于文档。
// archiver: 通用文件打包
archive.directory('./docs/', 'documents');
jszip 可用于文档,但需手动处理。
docxtemplater 官方推荐 pizzip。// jszip: 手动处理 docx 结构
const zip = await JSZip.loadAsync(file);
const content = await zip.file('document.xml').async('string');
// 需要手动管理 XML 命名空间和结构
pizzip 与 docxtemplater 深度集成。
// pizzip: 配合 docxtemplater
const zip = new PizZip(content);
const doc = new docxtemplater(zip, { paragraphLoop: true, linebreaks: true });
doc.render({ user: 'John' });
const out = doc.getZip().generate({ type: 'blob' });
| 特性 | archiver | jszip | pizzip |
|---|---|---|---|
| 运行环境 | 🟢 Node.js 仅 | 🟢 浏览器 + Node | 🟢 浏览器 + Node |
| 内存模型 | 🌊 流式 (Streaming) | 🧠 内存 (In-Memory) | 🧠 内存 (In-Memory) |
| 大文件支持 | ✅ 优秀 (不限大小) | ❌ 差 (受内存限制) | ❌ 差 (受内存限制) |
| API 风格 | 📡 事件/流 | 🤝 Promise | ⚙️ 同步/回调 |
| 主要用途 | 服务器备份/下载 | 前端压缩/通用 | Office 文档生成 |
| 生态绑定 | 无 | 通用 | docxtemplater |
archiver 是后端服务的标准选择 🖥️。当你需要在 Node.js 服务器上打包日志、备份数据库 dump 文件或提供大文件下载时,它是唯一正确的选择。流式架构保证了服务器的稳定性。
jszip 是前端开发的首选工具 🌐。如果你需要在浏览器中让用户下载多个文件、导出项目数据或处理中小型压缩包,它的 Promise API 和广泛的文档支持能极大提高开发效率。
pizzip 是特定领域的专用工具 📑。除非你正在使用 docxtemplater 生成 Word/PPT 报告,否则优先选择 jszip。在通用 ZIP 处理上,jszip 的社区支持和更新频率更具优势。
最终思考:不要试图在浏览器中使用 archiver(无法运行),也不要试图在服务器上用 jszip 处理 GB 级文件(会崩溃)。根据数据流向和运行环境做出选择,是架构设计的基本功。
选择 jszip 如果你需要在浏览器端生成压缩包,或者在 Node.js 中处理中小型文件。它的 API 基于 Promise,易于使用,支持读取和修改现有的 ZIP 文件,是通用场景下的首选方案。
选择 archiver 如果你的运行环境是 Node.js 服务器,并且需要处理大文件或流式传输。它允许你边读取边压缩,直接管道传输到 HTTP 响应或文件系统,非常适合生成大型下载包或备份任务,避免占用大量内存。
选择 pizzip 如果你主要在使用 docxtemplater 生成 Word 或 PowerPoint 文档。它在处理 Office 文档的二进制结构和特定压缩需求上与模板引擎配合更紧密,通用 ZIP 处理不如 jszip 活跃。
A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API.
See https://stuk.github.io/jszip for all the documentation.
const zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
const 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");
});
/*
Results in a zip containing
Hello.txt
images/
smile.gif
*/
JSZip is dual-licensed. You may use it under the MIT license or the GPLv3 license. See LICENSE.markdown.