asai-nodejs-zip
v0.2.6
Published
asai for you
Readme
asai-nodejs-zip — ZIP 压缩/解压缩插件
功能概述
asai-nodejs-zip 基于 compressing 库,提供 ZIP 格式的文件夹压缩、文件压缩、解压缩和流式压缩功能。所有方法均返回 Promise。
入口文件 — zip.js
依赖
import compressing from 'compressing';
import fs from 'fs';API 详细说明
zip(zipf, dir, opts)
压缩文件夹为 ZIP 文件。
参数:
| 参数 | 类型 | 必需 | 默认值 | 说明 |
|------|------|------|--------|------|
| zipf | string | ✓ | — | 目标 ZIP 文件路径 |
| dir | string | ✓ | — | 要压缩的源文件夹路径 |
| opts | object | ✗ | {} | 配置选项 |
opts 选项:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| ignoreBase | boolean | false | 为 true 时,压缩忽略源文件夹根目录,仅打包内部文件和子文件夹 |
| zipFileNameEncoding | string | 'utf8' | 文件名编码(支持 gbk、shift_jis 等) |
编码支持:
| 语言 | 编码值 |
|------|--------|
| 简体中文 | gbk, gb18030, gb2312, cp936 |
| 繁体中文 | big5, cp950 |
| 韩文 | cp949, euc-kr |
| 日文 | sjis(shift_jis), cp932, euc-jp |
示例:
const zip = require('./zip');
// 压缩文件夹
await zip.zip('./output.zip', './data', { ignoreBase: true });
// 压缩文件夹(中文编码)
await zip.zip('./中文文件.zip', './data', { zipFileNameEncoding: 'gbk' });zipfile(zipf, file, opts)
压缩单个文件为 ZIP 文件。
参数:
| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| zipf | string | ✓ | 目标 ZIP 文件路径 |
| file | string | ✓ | 要压缩的源文件路径 |
| opts | object | ✗ | 配置选项(同 zip()) |
示例:
// 压缩单个文件
await zip.zipfile('./myfile.zip', './document.docx');unzip(zipf, dir, opts)
解压缩 ZIP 文件到指定目录。
参数:
| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| zipf | string | ✓ | 要解压的 ZIP 文件路径 |
| dir | string | ✓ | 解压目标目录 |
| opts | object | ✗ | 配置选项(同 zip()) |
示例:
// 解压缩
await zip.unzip('./backup.zip', './restore/');zipstream(zipf, dir)
使用流式方式压缩文件夹(递归子目录)。
与 zip() 的区别:逐文件 addEntry,适合需自定义相对路径的场景;内部用 path.join / path.resolve 遍历。
参数:
| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| zipf | string | ✓ | 目标 ZIP 文件路径 |
| dir | string | ✓ | 源文件夹路径 |
示例:
await zip.zipstream('./data.zip', './upload/');zipEntries(zipf, entries, opts)
多条目直接打包(跳过 staging 目录)。
参数:
| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| zipf | string | ✓ | 输出 ZIP 路径 |
| entries | Array<{src, relativePath}> | ✓ | 源文件绝对/相对路径及 ZIP 内相对路径 |
| opts | object | ✗ | 如 zipFileNameEncoding(默认 utf8) |
示例:
await zip.zipEntries('./bundle.zip', [
{ src: './src/a.js', relativePath: 'a.js' },
{ src: './src/b.js', relativePath: 'lib/b.js' },
], { zipFileNameEncoding: 'gbk' });使用示例
const zip = require('./zip');
async function backupAndRestore() {
// 1. 压缩项目文件夹(忽略根目录)
await zip.zip(
'./backups/project-2024.zip',
'./my-project/',
{ ignoreBase: true }
);
// 2. 解压到新位置
await zip.unzip(
'./backups/project-2024.zip',
'./restored-project/'
);
}注意事项
- 依赖
compressing包,请确保已安装 - 处理中文文件名时,建议指定
zipFileNameEncoding: 'gbk' zipstream()递归子目录,与zip()覆盖范围一致;路径拼接使用path.joinzipEntries()在entries为空时 reject;源文件不存在时带路径报错- 所有方法均为异步,返回 Promise
测试
单元测试目录:.youmengyu/test/unit/webserver/plugs/asai-nodejs-zip/
# 仓库根目录
node .youmengyu/test/asaitest.mjs --no-open
# 或单文件
npx tsx --test .youmengyu/test/unit/webserver/plugs/asai-nodejs-zip/<file>.test.mjs代码分析与优化建议
✅ 已优化项目
1. zipstream() 支持递归子目录 ✅
优化内容:递归 walk() 遍历子目录(path.join),功能与 zip() 对齐。
const walk = (d) => {
for (const name of fs.readdirSync(d)) {
const full = path.join(d, name);
// ...
}
};2. 错误信息增强 ✅
优化内容:所有方法在 catch 时增加上下文信息(源路径、目标路径),便于调试时快速定位失败的压缩操作。
// 优化前:没有上下文
reject(e);
// 优化后:带有操作描述
reject(new Error(`[ZIP] 压缩文件夹失败: ${zipf} <- ${dir}: ${e.message}`));🔜 待优化项目
| 优先级 | 问题 | 状态 | |--------|------|------| | 🟡 P2 | 统一 zip 和 zipstream 接口,内部自动选择策略 | 待处理 |
优化优先级总结
| 优先级 | 问题 | 影响 |
|--------|------|------|
| ✅ 已修复 | zipstream 不递归 | 功能缺陷 |
| ✅ 已修复 | 错误信息增强 | 可调试性 |
