adm-zip vs archiver vs jszip vs yazl vs zip-lib vs zip-stream
前端与 Node.js 中 ZIP 压缩库选型指南
adm-ziparchiverjszipyazlzip-libzip-stream类似的npm包:

前端与 Node.js 中 ZIP 压缩库选型指南

adm-ziparchiverjszipyazlzip-libzip-stream 是 JavaScript 生态中用于处理 ZIP 压缩文件的常用 npm 包。它们各自专注于不同的使用场景:部分库支持 ZIP 文件的创建(压缩),部分支持读取(解压),还有一些同时支持双向操作。这些库在浏览器兼容性、Node.js 流式处理、API 设计和功能完整性方面存在显著差异,适用于前端下载生成、后端文件处理、CLI 工具开发等不同工程需求。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
adm-zip02,161121 kB1482 年前MIT
archiver02,95343.1 kB1562 年前MIT
jszip010,330762 kB410-(MIT OR GPL-3.0-or-later)
yazl037558.7 kB191 年前MIT
zip-lib04163.6 kB13 天前MIT
zip-stream01669.33 kB271 年前MIT

前端 ZIP 库深度对比:adm-zip、archiver、jszip、yazl、zip-lib 与 zip-stream

在现代前端开发中,处理 ZIP 文件的需求日益常见 —— 无论是让用户下载打包的资源、上传压缩包解析内容,还是在浏览器中动态生成压缩文件。Node.js 生态提供了多个 ZIP 相关库,但它们的设计目标、能力边界和使用场景差异显著。本文将从工程实践角度,深入剖析 adm-ziparchiverjszipyazlzip-libzip-stream 的技术特性,帮助你做出精准选型。

📦 核心能力定位:谁做什么?

首先明确一点:这些库并非都支持“创建”和“解压”双向操作。有些专注压缩(如 yazl),有些专注解压(如 adm-zip),而另一些则是全功能方案(如 jszip)。理解这一点是选型的第一步。

✅ 支持解压的库

  • adm-zip:可读取并解压 ZIP 文件(支持内存或文件系统)。
  • jszip:可在浏览器和 Node.js 中加载 ZIP 并提取内容。

✅ 支持压缩的库

  • archiver:通用归档工具,支持 ZIP、TAR 等格式,输出流式数据。
  • jszip:支持在内存中构建 ZIP 并导出为 Blob、Buffer 或 Base64。
  • yazl:纯 ZIP 压缩库,仅支持创建 ZIP,不支持解压。
  • zip-lib:基于 yazlyauzl 封装,提供更简洁的 API,支持压缩和解压。
  • zip-stream:底层 ZIP 流生成器,通常作为 archiver 的依赖,不直接面向应用层。

⚠️ 注意:zip-stream 是一个低级流工具,官方文档明确指出它主要用于 archiver 内部,不建议在应用代码中直接使用。本文仍将其纳入比较,但会明确其定位。

🔧 解压能力对比:如何读取 ZIP 内容?

adm-zip:文件系统友好型解压

adm-zip 最适合需要直接操作文件系统的场景(如 CLI 工具或后端服务)。它能从文件路径或 Buffer 加载 ZIP,并支持提取到磁盘或读取内存中的条目。

// adm-zip: 从文件解压
const AdmZip = require('adm-zip');
const zip = new AdmZip('./archive.zip');

// 提取所有文件到目录
zip.extractAllTo('./output/');

// 读取单个文件内容(Buffer)
const entry = zip.getEntry('file.txt');
const content = entry.getData(); // Buffer

jszip:浏览器优先的解压

jszip 在浏览器中表现优异,支持从 Blob、ArrayBuffer 或 Base64 加载 ZIP,并以 Promise 方式异步读取内容。

// jszip: 浏览器中解压 Blob
import JSZip from 'jszip';

const zip = new JSZip();
const content = await zip.loadAsync(blob); // blob 来自 input[type=file]

// 读取文件内容为文本
const text = await content.file('file.txt').async('text');

zip-lib:简化版双向操作

zip-libyauzl(解压)和 yazl(压缩)做了封装,提供统一的 Promise 接口。

// zip-lib: 解压文件到内存对象
import { unzip } from 'zip-lib';

const files = await unzip('./archive.zip');
// 返回 { [filename]: Buffer } 对象

其他库(archiver, yazl, zip-stream不支持解压,此处不提供示例。

📤 压缩能力对比:如何生成 ZIP?

archiver:流式、多格式、大文件友好

archiver 是最强大的压缩方案,尤其适合处理大文件或需要流式输出的场景(如 HTTP 响应)。它通过管道(pipe)将数据写入可写流(如文件或网络响应)。

// archiver: 流式压缩到文件
const fs = require('fs');
const archiver = require('archiver');

const output = fs.createWriteStream('archive.zip');
const archive = archiver('zip');

archive.pipe(output);
archive.file('file.txt', { name: 'file.txt' });
archive.finalize(); // 触发写入

jszip:内存中构建,适合小文件

jszip 将所有内容保留在内存中,适合前端生成小 ZIP 并触发下载。

// jszip: 浏览器中生成 ZIP 并下载
import JSZip from 'jszip';

const zip = new JSZip();
zip.file('hello.txt', 'Hello World!');

const blob = await zip.generateAsync({ type: 'blob' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'archive.zip';
a.click();

yazl:极简 ZIP 创建器

yazl 只做一件事:创建 ZIP 流。你需要手动管理流的写入和结束。

// yazl: 手动流控制
const yazl = require('yazl');
const fs = require('fs');

const zipfile = new yazl.ZipFile();
zipfile.addBuffer(Buffer.from('Hello'), 'hello.txt');

const output = fs.createWriteStream('archive.zip');
zipfile.outputStream.pipe(output);
zipfile.end(); // 必须调用 end()

zip-lib:高层封装,简单易用

zip-lib 提供了类似 jszip 的简洁 API,但基于流实现,适合 Node.js 场景。

// zip-lib: 压缩目录到 ZIP
import { zip } from 'zip-lib';

await zip('./source-dir', 'archive.zip');
// 自动递归压缩整个目录

zip-stream:底层流,慎用

zip-streamarchiver 的底层依赖,直接使用需处理更多细节。

// zip-stream: 不推荐直接使用
const ZipStream = require('zip-stream');
const fs = require('fs');

const archive = new ZipStream();
const output = fs.createWriteStream('archive.zip');
archive.pipe(output);

archive.entry('Hello', { name: 'hello.txt' }, () => {
  archive.finish();
});

⚠️ 官方未推荐 zip-stream 作为独立使用库,建议优先考虑 archiver

🌐 运行环境支持

浏览器Node.js
adm-zip❌(依赖 fs)
archiver❌(依赖流和文件系统)
jszip✅(通过 Buffer)
yazl❌(依赖 Node Stream)
zip-lib❌(依赖 fs)
zip-stream❌(依赖 Node Stream)

关键结论

  • 如果你的应用运行在浏览器,唯一可行的选择是 jszip
  • 如果你在 Node.js 环境且需要解压,可选 adm-zipzip-lib
  • 如果你在 Node.js 环境且需要压缩,根据需求复杂度选择 archiver(复杂/大文件)、zip-lib(简单目录)或 yazl(极致控制)。

🧪 错误处理与健壮性

  • adm-zip:同步 API,错误以 throw 形式抛出,需 try/catch。
  • jszip:异步 API(Promise),错误通过 reject 传递。
  • archiver:基于流,需监听 'error' 事件。
  • yazl / zip-stream:流式错误同样需监听 'error'
  • zip-lib:Promise 封装,错误通过 reject 传递,更符合现代习惯。

📊 选型决策树

  1. 是否在浏览器中运行?

    • 是 → 选 jszip
    • 否 → 进入下一步
  2. 是否需要解压 ZIP?

    • 是 → 选 adm-zip(需文件系统操作)或 zip-lib(只需内存内容)
    • 否 → 进入下一步
  3. 压缩场景复杂度?

    • 需要压缩大文件、流式输出、或多种格式 → archiver
    • 只需压缩整个目录,追求简单 → zip-lib
    • 需要极致控制 ZIP 结构 → yazl
    • 避免直接使用 zip-stream

💡 总结:各有所长,按需取用

  • adm-zip:Node.js 文件系统解压首选,API 直观但同步阻塞。
  • archiver:Node.js 压缩王者,功能全面,适合生产级大文件处理。
  • jszip:唯一跨环境(浏览器 + Node.js)的全功能库,前端必备。
  • yazl:轻量 ZIP 创建器,适合定制化流式压缩逻辑。
  • zip-lib:对 yazl/yauzl 的现代化封装,API 简洁,适合快速集成。
  • zip-stream:底层工具,不推荐应用层直接使用

选择 ZIP 库不是追求“最强大”,而是匹配你的运行环境、功能需求和数据规模。希望本文能帮你避开陷阱,直击核心。

如何选择: adm-zip vs archiver vs jszip vs yazl vs zip-lib vs zip-stream

  • adm-zip:

    选择 adm-zip 如果你需要在 Node.js 环境中直接操作文件系统来解压 ZIP 文件,例如从磁盘读取 ZIP 并提取内容到指定目录。它的 API 简单直观,适合同步处理小型 ZIP 文件,但不支持浏览器环境,且无法创建 ZIP。

  • archiver:

    选择 archiver 如果你在 Node.js 中需要流式压缩大文件或目录,支持 ZIP、TAR 等多种格式,并计划将输出直接管道到 HTTP 响应或文件流。它是处理复杂归档任务的工业级选择,但不适用于浏览器。

  • jszip:

    选择 jszip 如果你的应用需要在浏览器中动态生成或解析 ZIP 文件(如用户上传解析或前端打包下载),或者需要跨 Node.js 与浏览器的统一 API。它完全基于内存操作,适合中小型文件,是前端场景的唯一可行方案。

  • yazl:

    选择 yazl 如果你在 Node.js 中需要精细控制 ZIP 的创建过程(如逐条添加条目并管理底层流),且不需要解压功能。它是一个轻量、专注的 ZIP 生成器,适合构建自定义压缩逻辑,但需手动处理流生命周期。

  • zip-lib:

    选择 zip-lib 如果你在 Node.js 中希望用简洁的 Promise API 快速完成目录压缩或 ZIP 解压,而不想处理底层流细节。它封装了 yazlyauzl,提供高层抽象,适合中小型项目快速集成,但不支持浏览器。

  • zip-stream:

    避免在新项目中直接使用 zip-stream,因为它是 archiver 的底层依赖,官方未设计为独立应用库。如果你需要流式 ZIP 生成,请优先选择 archiver;只有在深度定制归档逻辑且了解其内部机制时才考虑此包。

adm-zip的README

ADM-ZIP for NodeJS

ADM-ZIP is a pure JavaScript implementation for zip data compression for NodeJS.

Build Status

Installation

With npm do:

$ npm install adm-zip

Electron file system support described below.

What is it good for?

The library allows you to:

  • decompress zip files directly to disk or in memory buffers
  • compress files and store them to disk in .zip format or in compressed buffers
  • update content of/add new/delete files from an existing .zip

Dependencies

There are no other nodeJS libraries that ADM-ZIP is dependent of

Examples

Basic usage

var AdmZip = require("adm-zip");

// reading archives
var zip = new AdmZip("./my_file.zip");
var password = "1234567890";
var zipEntries = zip.getEntries(); // an array of ZipEntry records - add password parameter if entries are password protected

zipEntries.forEach(function (zipEntry) {
    console.log(zipEntry.toString()); // outputs zip entries information
    if (zipEntry.entryName == "my_file.txt") {
        console.log(zipEntry.getData().toString("utf8"));
    }
});
// outputs the content of some_folder/my_file.txt
console.log(zip.readAsText("some_folder/my_file.txt"));
// extracts the specified file to the specified location
zip.extractEntryTo(/*entry name*/ "some_folder/my_file.txt", /*target path*/ "/home/me/tempfolder", /*maintainEntryPath*/ false, /*overwrite*/ true);
// extracts everything
zip.extractAllTo(/*target path*/ "/home/me/zipcontent/", /*overwrite*/ true);

// creating archives
var zip = new AdmZip();

// add file directly
var content = "inner content of the file";
zip.addFile("test.txt", Buffer.from(content, "utf8"), "entry comment goes here");
// add local file
zip.addLocalFile("/home/me/some_picture.png");
// get everything as a buffer
var willSendthis = zip.toBuffer();
// or write everything to disk
zip.writeZip(/*target file name*/ "/home/me/files.zip");

// ... more examples in the wiki

For more detailed information please check out the wiki.

Electron original-fs

ADM-ZIP has supported electron original-fs for years without any user interractions but it causes problem with bundlers like rollup etc. For continuing support original-fs or any other custom file system module. There is possible specify your module by fs option in ADM-ZIP constructor.

Example:

const AdmZip = require("adm-zip");
const OriginalFs = require("original-fs");

// reading archives
const zip = new AdmZip("./my_file.zip", { fs: OriginalFs });
.
.
.