zip.js 评测:浏览器里处理超大 Zip 文件,并行压缩与 Zip64 是核心
项目速览:用于压缩和解压缩文件的 JavaScript 库,支持并行压缩、Web 流、zip64、分割文件、数据加密和 deflate64 解压缩。
秒懂
- 它是什么?
- zip.js 是一个面向浏览器和 Deno 的 JavaScript 压缩库,主打大文件、并行压缩和 Zip64。本文基于官方文档和 README,分析它的工作机制、上手方式、局限性和适用场景。
- 适合谁用?
- zip.js 适合需要在浏览器或 Deno 中处理超过 4GB 的 Zip 文件、需要并行压缩或流式读写的开发者。它不适合对压缩率有极致要求、且无法接受 Web Worker 复杂性的场景,也不适合需要 deflate64 压缩(仅解压)的用例。
- 能商用吗?
- 可以。BSD-3-Clause 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 2 天前。
- 用什么语言写的?
- 主要是 JavaScript(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月17日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是浏览器里的大文件压缩问题
浏览器原生的压缩 API 存在明显边界。`CompressionStream` 只支持 gzip 和 deflate,不产出 Zip 容器格式,也没有加密和分卷能力。zip.js 的出现正是为了补上这个缺口:它把 Zip 的读写完整搬到了 JavaScript 里,而且目标明确是“大文件”。README 第一句就写明设计目的是处理大量数据。它支持 Zip64,所以单文件或整个归档超过 4GB 不再是硬限制。对于需要在前端生成或解压大型归档的应用,比如导出数据库备份、处理上传的日志包,这个库提供了原生的方案。它的目标用户是前端工程师和 Deno 脚本作者,不是 Node.js 后端开发者,虽然它也能在 Node 里跑,但那里有更成熟的替代。
核心机制:Web Streams 与可插拔压缩引擎
zip.js 的架构围绕 Web Streams 设计。写入时,`ZipWriter` 接收一个 writer 对象,比如 `BlobWriter`,然后把条目数据流式写入。读取时,`ZipReader` 配合 reader 对象,比如 `BlobReader` 或 `HttpReader`,按需解压。这种流式设计意味着内存占用不会随文件大小线性增长。压缩本身默认使用浏览器的 `CompressionStream`,这是原生 deflate 实现,速度快且不占 JavaScript 线程。但 `CompressionStream` 并非所有浏览器都支持,所以 zip.js 提供了回退机制:你可以通过 `configure()` 注入自定义 worker 和压缩引擎,文档里给出了用 fflate 作为回退的例子。这个设计很务实,它把性能关键的压缩路径交给平台,同时保留了对老浏览器的兼容性。
并行压缩:靠 Web Workers 而不是魔法
并行压缩是 zip.js 的招牌特性之一。它的实现方式是让每个压缩任务跑在独立的 Web Worker 里。README 中展示了如何用 `new Worker(new URL("./zip-worker.js", import.meta.url))` 创建 worker,并强调 Vite、webpack 和 Rollup 能识别这种写法并自动打包。这意味着并行能力不是自动获得的,你需要按文档配置 worker。默认情况下,zip.js 可能使用内置 worker 脚本,但定制时你必须自己管理 worker 的生命周期。这个设计有代价:worker 的创建和通信有开销,所以对小的条目,并行可能反而更慢。文档没有给出性能基准,所以并行加速比到底如何,需要你在自己的数据上验证。它更适合条目数量多、单个文件体积大的场景。
上手:三个 API 对象搞定基本读写
从 README 的 Hello world 示例看,基本用法非常直接。写入一个条目需要三样东西:一个 writer 目标,一个 reader 源,和一个 `ZipWriter`。代码里用 `new TextReader("Hello world!")` 包装字符串,用 `new BlobWriter()` 作为输出,然后 `zipWriter.add("hello.txt", helloWorldReader)`,最后 `close()` 得到 Blob。读取对称,用 `ZipReader` 加 `BlobReader`。流式版本用 `TransformStream`,把 `writable` 接到 `ZipWriter`,`readable` 转成 Blob。并行添加条目也很简单,直接 `Promise.all` 多个 `add()` 调用即可。这些示例都来自官方文档,实际使用时你需要引入 `@zip.js/zip.js` 包,Deno 环境用 `jsr:@zip-js/zip-js`。配置自定义 worker 的代码稍微复杂,需要单独建一个 `zip-worker.js` 文件,并调用 `initWorker`。
真正的局限:deflate64 只能解压,压缩引擎依赖平台
zip.js 支持 deflate64 解压,但 README 只提到“Deflate64 decompression”,没有说支持 deflate64 压缩。这意味着你遇到用 deflate64 压缩的归档能解开,但生成时只能用标准 deflate。这是一个不对称的能力,如果你需要产出 deflate64 格式,这个库帮不上忙。另一个限制是压缩引擎的可插拔性。默认依赖 `CompressionStream`,但它的压缩级别和策略你无法完全控制。如果你想用 zlib 的特定参数,比如不同的内存级别或策略,就得自己实现引擎。文档没有提供内置的替代引擎,只给了 fflate 的例子。还有一点,Zip64 支持虽然解决了 4GB 限制,但某些老旧解压工具可能不识别 Zip64 扩展字段,生成的归档在旧软件里可能打不开。
替代方案:fflate 与原生 CompressionStream 的对比
最直接的替代是 fflate,文档里也用它作为自定义引擎的例子。fflate 是一个纯 JavaScript 的压缩库,不依赖 Web Workers,也不依赖 `CompressionStream`,因此可以在所有环境一致运行。它的压缩速度可能不如原生流,但行为可预测。另一个选择是直接使用浏览器的 `CompressionStream` 和 `DecompressionStream`,如果你只需要 gzip 或 deflate,不需要 Zip 容器格式,那原生 API 就够用,零依赖。zip.js 的差异在于它提供了 Zip 的封装、Zip64、加密和分卷支持,这些是原生 API 没有的。如果你的需求只是压缩一个字符串,fflate 或原生 API 更轻;如果需要完整的 Zip 归档,zip.js 是更完整的选择。
维护与许可:BSD-3-Clause 下的活跃更新
仓库显示最近一次推送是 2026 年 8 月 28 日,版本号 v2.8.61,更新频率高,几天内就有多个补丁版本。这说明项目处于活跃维护状态。许可证是 BSD-3-Clause,这是宽松许可,允许商用和修改,只要保留版权声明。对于企业采用来说,许可风险很低。但要注意,zip.js 依赖 Web Workers 和 `CompressionStream`,这些是平台特性,升级浏览器或运行时可能影响行为。你需要在升级库版本时回归测试压缩和解压流程。文档提到测试在 `tests/all` 目录,但 README 没有给出覆盖率数据,所以测试深度未知。
编辑结论
zip.js 适合需要在浏览器或 Deno 中处理超过 4GB 的 Zip 文件、需要并行压缩或流式读写的开发者。它不适合对压缩率有极致要求、且无法接受 Web Worker 复杂性的场景,也不适合需要 deflate64 压缩(仅解压)的用例。采用前应验证:你的构建工具是否能正确打包 `new Worker(new URL(...))` 形式的 worker,以及目标浏览器是否支持 CompressionStream,这直接决定回退路径是否会被触发。若你的项目以 Node.js 为主且不需要浏览器端能力,原生 `zlib` 或 `fflate` 可能更轻量。zip.js 的维护活跃,但依赖其内置 worker 的定制能力时,需预留时间阅读文档中的自定义指南。
社区笔记