Skip to content

refactor: 使用 JSZipp 替换 jszip 处理 ZIP 文件#1479

Open
cyfung1031 wants to merge 5 commits into
mainfrom
pr/jszip-to-fflate/001
Open

refactor: 使用 JSZipp 替换 jszip 处理 ZIP 文件#1479
cyfung1031 wants to merge 5 commits into
mainfrom
pr/jszip-to-fflate/001

Conversation

@cyfung1031
Copy link
Copy Markdown
Collaborator

@cyfung1031 cyfung1031 commented May 28, 2026

Checklist / 检查清单

  • Fixes mentioned issues / 修复已提及的问题 - JSZip 不支持 zip64 导致脚本数量受限
  • Code reviewed by human / 代码通过人工检查
  • Changes tested / 已完成测试

Description / 描述

本 PR 将项目中的 ZIP 处理逻辑从 jszip 迁移到 JSZipp(web-jszipp),以减少对 jszip 及其相关依赖的使用,并统一 ZIP 文件的读写、打包和时间戳处理。

主要变更:

  • 新增 web-jszipp 依赖,移除 jszip 及其相关依赖。
  • 重写 src/pkg/utils/jszip-x.ts,基于 JSZipp 实现兼容现有调用方式的 ZIP 封装。
  • 更新扩展打包脚本 scripts/pack.js,使用 JSZipp 的 ZipWriter 生成 Chrome / Firefox ZIP 包。
  • 调整 ZIP 文件读写逻辑,支持写入 stringBlob 内容。
  • 修正 ZIP 文件修改时间的处理方式,移除原有针对 jszip 的时区偏移补偿。
  • 保留 ZIP 生成时的 comment 字段支持。
  • 移除 Buffer nodeStream 支持。

Remarks

  • 支持 Zip64,因此单个文件可以超过 4GB 或文件数量超过 65,535。

Screenshots / 截图

@cyfung1031
Copy link
Copy Markdown
Collaborator Author

cyfung1031 commented May 28, 2026

@CodFrm comment: "Created by Scriptcat" 是有什么作用??

JSZIP打包出来的,里面有些档案包含这个,有些没有

如果要保留这个东西, fflate 会全部档案都加这个
不保留就全部都不加


待这个处理好再取消 draft

@cyfung1031 cyfung1031 changed the title jszip-to-fflate refactor: 使用 fflate 替换 jszip 处理 ZIP 文件 May 28, 2026
@CodFrm
Copy link
Copy Markdown
Member

CodFrm commented May 29, 2026

@CodFrm comment: "Created by Scriptcat" 是有什么作用??

JSZIP打包出来的,里面有些档案包含这个,有些没有

如果要保留这个东西, fflate 会全部档案都加这个 不保留就全部都不加

待这个处理好再取消 draft

只是一个注释,你用某些zip管理器打开,你可以看到右侧有这个评论

@cyfung1031 cyfung1031 marked this pull request as ready for review May 30, 2026 06:03
@cyfung1031 cyfung1031 marked this pull request as draft May 30, 2026 07:26
@cyfung1031

This comment was marked as outdated.

@cyfung1031 cyfung1031 force-pushed the pr/jszip-to-fflate/001 branch from c902cc7 to 4a99319 Compare May 30, 2026 14:02
@cyfung1031 cyfung1031 changed the title refactor: 使用 fflate 替换 jszip 处理 ZIP 文件 refactor: 使用 JSZipp 替换 jszip 处理 ZIP 文件 Jun 4, 2026
@cyfung1031 cyfung1031 marked this pull request as ready for review June 5, 2026 00:08
@cyfung1031
Copy link
Copy Markdown
Collaborator Author

#1489 修正
Screenshot 2026-06-05 at 9 09 04

@cyfung1031
Copy link
Copy Markdown
Collaborator Author

cyfung1031 commented Jun 5, 2026

@CodFrm comment: "Created by Scriptcat" 是有什么作用??
JSZIP打包出来的,里面有些档案包含这个,有些没有
如果要保留这个东西, fflate 会全部档案都加这个 不保留就全部都不加
待这个处理好再取消 draft

只是一个注释,你用某些zip管理器打开,你可以看到右侧有这个评论

做了一个全新的 JSZipp

测试:


这个PR用的是预设压缩设定,modifiedDate 是用完整UTC时间,而不是DOS本机时间

我不是用web worker做法。而是用更高效的iterative compression, 不但壓縮快,而且內存負擔小。

@CodFrm
Copy link
Copy Markdown
Member

CodFrm commented Jun 5, 2026

@CodFrm comment: "Created by Scriptcat" 是有什么作用??
JSZIP打包出来的,里面有些档案包含这个,有些没有
如果要保留这个东西, fflate 会全部档案都加这个 不保留就全部都不加
待这个处理好再取消 draft

只是一个注释,你用某些zip管理器打开,你可以看到右侧有这个评论

做了一个全新的 JSZipp

测试:

这个PR用的是预设压缩设定,modifiedDate 是用完整UTC时间,而不是DOS本机时间

我不是用web worker做法。而是用更高效的iterative compression, 不但壓縮快,而且內存負擔小。

好吧,虽然我觉得fork/pr现有的库去做更好,但是你已经折腾出来了,也没关系


我实际验证了一下,这个 PR 用 web-jszipp@1.0.5 整体可行。

本地跑过:

  • pnpm install --frozen-lockfile --ignore-scripts 通过
  • pnpm exec tsc --noEmit --pretty false 通过
  • Vitest 全量测试通过,51 个 test files / 954 tests

web-jszipp@1.0.5 的 package engines 要求 pnpm >=10.33.2,所以 packageManager 建议一起升到 pnpm@10.33.2

benchmark 我也看了你的页面,并在本地按类似数据分布补了一轮。页面默认是 fileCount=8400 / batchSize=600 / level=6,我本地为了避免多个 worker 并发互相抢 CPU,是顺序跑。跨库结果大概是:

  • fflate async: zip 848ms,sample unzip 159ms,size 6574514
  • fflate sync: zip 871ms,sample unzip 149ms,size 6574514
  • JSZipp compact: zip 1351ms,sample unzip 41ms,size 6562268
  • JSZipp default: zip 1767ms,sample unzip 80ms,size 6713468
  • zip.js CS: zip 2922ms,sample unzip 95ms,size 7420162
  • JSZip: zip 6330ms,sample unzip 63ms,size 6843256

所以如果只看压缩速度,fflate 还是更快;但 JSZipp 明显快于 JSZip 和 zip.js。体积方面 compact/Dos only 表现最好,default 因为会写 UTC extra field,体积会略大。

内存也补测了,每个库独立进程跑同类场景,maxRSS 大概是:

  • JSZipp default / compact: 约 153MB
  • zip.js CS: 约 350MB
  • fflate sync/async: 约 393-423MB
  • JSZip: 约 460MB

所以“内存负担小”这个点本地结果是支持的。

modifiedDate 也测了:确实会写 UTC extra field,回读是 UTC 时间,不是单纯依赖 legacy DOS 本机时间。不过 ZIP 时间精度会截断到秒,毫秒不会保留,这个对我们打包应该没影响。

剩下主要有两个点建议处理:

  1. packageManager 升到 pnpm@10.33.2,和 web-jszipp 的 engines 对齐。
  2. src/pkg/utils/jszip-x.ts 里现在用了 pathMode: "unsafe"。我实测 ../evil.user.js 这种 entry 会被接受;strict 会拒绝。导入备份是用户可控 zip,建议不要用 unsafe,至少改成 strict,更推荐 strict-package,并考虑加 maxArchiveSize / maxEntrySize

@cyfung1031
Copy link
Copy Markdown
Collaborator Author

好吧,虽然我觉得fork/pr现有的库去做更好,但是你已经折腾出来了,也没关系

本来在fflate提交了PR,但原来问题都持续超过一年都没好好处理。认真研究才发现细节实现很差。例如根本没想过档案量和单档大小的问题。从根本开始就没考虑,fork也要大改。作者也不太接受AI代码。
(而且不做单元测试,根本不知道工具能不能用)

也想试试看用AI从头开始设计整个library以至实现,能做到怎么样。反正这种东西做了出来后没bug就不用更新。
(还想看看rspack 2.x是怎样的)

结果做出来的东西我很满意呀。( 当然要把代码压缩到极限还是要靠人脑处理。)
既简单,又小巧,又快。最重要的是AI做出来的很稳定。不会突然解压失败压缩失败。

@CodFrm
Copy link
Copy Markdown
Member

CodFrm commented Jun 5, 2026

好吧,虽然我觉得fork/pr现有的库去做更好,但是你已经折腾出来了,也没关系

本来在fflate提交了PR,但原来问题都持续超过一年都没好好处理。认真研究才发现细节实现很差。例如根本没想过档案量和单档大小的问题。从根本开始就没考虑,fork也要大改。作者也不太接受AI代码。 (而且不做单元测试,根本不知道工具能不能用)

也想试试看用AI从头开始设计整个library以至实现,能做到怎么样。反正这种东西做了出来后没bug就不用更新。 (还想看看rspack 2.x是怎样的)

结果做出来的东西我很满意呀。( 当然要把代码压缩到极限还是要靠人脑处理。) 既简单,又小巧,又快。最重要的是AI做出来的很稳定。不会突然解压失败压缩失败。

😄 AI 真是太好用了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants