1.0.3 • Published 9 months ago
@pzhiq/ptiny v1.0.3
@pzhiq/ptiny - TinyPNG 智能图片压缩工具
 
一款基于 TinyPNG 官方 API 开发的智能图片压缩工具,支持递归目录处理、压缩缓存和自动重试机制,帮助开发者高效优化项目中的图片资源。
📖 背景与需求
开发背景
现代 Web 项目常面临图片体积过大的问题,传统手动压缩方式存在以下痛点:
- 多层级目录结构需要递归处理
 - 重复压缩相同文件浪费 API 调用次数
 - 网络波动导致偶发性压缩失败
 - 需要保留原始目录结构
 
核心能力
- ✅ 递归处理:自动扫描子目录中的图片文件
 - ✅ 智能缓存:基于文件哈希值跳过已压缩内容
 - ✅ 失败重试:网络异常时自动重试(最多5次)
 - ✅ 结构保留:完整保持原始目录层级关系
 - ✅ 安全机制:内置 API 调用频率控制
 
📦 安装
npm install -g @pzhiq/ptiny🛠 使用方式
基础命令
ptiny -s <源目录> -o <输出目录> [--key <API密钥>]参数说明
| 参数 | 简写 | 必填 | 说明 | 
|---|---|---|---|
--source <path> | -s | 是 | 待压缩的图片源目录路径 | 
--output <path> | -o | 是 | 输出目录(与源目录相同时覆盖文件) | 
--key <string> | 否 | TinyPNG API 密钥(支持命令行和变量传入) | 
🌟 核心特性
文件处理流程
graph LR
    A[遍历源目录] --> B[计算MD5]
    B --> C{缓存比对}
    C -->|未压缩| D[调用API]
    C -->|已缓存| E[跳过]
    D --> F[保存文件]
    F --> G[更新缓存]
    D -->|失败| H[重试5次]关键技术
- MD5 哈希缓存
 
// 计算文件哈希
async function calculateFileHash(filePath) {
  const content = await fs.readFile(filePath);
  return crypto.createHash('md5').update(content).digest('hex');
}- 缓存文件:
.tiny-cache(自动生成在运行目录) - 格式:
JSON键值对存储文件路径与哈希值 
- 重试机制 | 重试次数 | 等待时间 | 重试策略 | |----------|----------|------------------------| | 1 | 1秒 | 基础网络补偿 | | 2 | 2秒 | 防止服务限流 | | 3 | 3秒 | 规避临时中断 | | 4 | 4秒 | 应对高负载延迟 | | 5 | 5秒 | 最终失败抛出错误 |
 
(/Users/manbapan/Library/Application Support/typora-user-images/image-20250214101144019.png)
📝 使用示例
常规压缩
# 压缩 images 目录到 optimized 目录
ptiny -s ./images -o ./optimized --key YOUR_API_KEY覆盖原始文件
# 慎用!直接替换源文件
ptiny -s ./photos -o ./photos递归处理演示
输入目录结构:
src/
  ├─ header.png
  └─ gallery/
       └─ photo1.jpg
输出目录结构:
dist/
  ├─ header.png
  └─ gallery/
       └─ photo1.jpg⚠️ 注意事项
密钥安全
- 通过 
--key参数传入 - 内置默认密钥可能触发 API 限流
 
- 通过 
 缓存管理
# 强制重新压缩(清除缓存) rm .tiny-cache文件规则
- 支持格式:JPEG/PNG/WEBP(以最新的TinyPng支持格式为准)
 - 自动跳过非图片文件
 
文件覆盖警告
当源目录与输出目录相同时,会替换原始文件
❓ 常见问题
Q1:如何处理子目录?
工具自动递归处理所有层级的图片文件,保持原始目录结构。
Q2:压缩失败如何排查?
控制台会输出详细错误日志,常见原因:
- API 密钥无效
 - 网络连接异常
 - 文件格式不受支持
 - 文件夹路径异常
 
Q3:如何验证压缩效果?
输出日志包含压缩详情:
压缩完成! 统计信息:
----------------------------------------
总计处理图片: xx 张
成功压缩: xx 张
跳过压缩: xx 张
压缩失败: xx 张
----------------------------------------
原始总大小: xx
压缩后总大小: xx
共节省空间: xx (xx%)Q4:如何获取 API 密钥?
- 访问 TinyPNG API Portal
 - 注册账号并获取密钥
 - 免费版每月 500 次压缩额度
 
Q5:输出目录不存在怎么办?
工具会自动创建输出目录(包括嵌套目录)。
📜 其它信息
问题反馈:Gitee Issue
项目源码:Gitee仓库