在日常前端开发中,图片资源往往是网页体积的“大头”。之前开发的太阳系仿真系统(代码已开源:gitee.com/zach2019/so… TinyPNG、Squoosh),但它们通常依赖手动上传 → 下载 → 替换的操作流程——不仅重复枯燥,还难以融入现代前端工程化的自动化流水线。 作为开发者,我自然是希望能自动绝不手动,代码能解决的问题绝不麻烦别人。无论是处理存量静态资源,还是在构建时自动压缩被引用的图片,都应无需人工干预。正因如此,我开发了开源工具 @zhaoshijun/compress —— 一套集 CLI 批量处理与 Vite 构建集成于一体的图片自动化压缩方案,真正做到解放前端开发的双手。
npm包地址:www.npmjs.com/package/@zh…
✨ 核心亮点
-
「🛠 双模驱动」:
- 「CLI 模式」:一键扫描并批量压缩本地存量图片。
- 「Vite 插件模式」:在
vite build构建时自动拦截并压缩引用的图片,开发环境零感知。
-
「⚡️ 极速性能」:底层基于 Node.js 高性能图片处理库 「Sharp」,速度飞快,质量无损。
-
「📦 智能缓存」:Vite 插件内置 Content Hash 缓存机制,「未修改的图片跳过压缩」,拒绝拖慢构建速度。
-
「🛡 安全可靠」:CLI 模式默认不覆盖原图,支持备份;Vite 模式仅处理引用资源。
💡 设计思路解密
这个工具的设计初衷是**“一套逻辑,多端复用”**。将核心压缩能力封装,分别通过 CLI 和 Vite 插件暴露给用户。
1. 核心逻辑:Sharp 封装
为了保证压缩质量和速度,我选择了 sharp。核心函数抹平了不同格式的参数差异。
// src/core/compressor.js
import sharp from 'sharp';
export async function compressImage(input, options) {
let instance = sharp(input);
// 统一处理格式参数
if (format === 'png') {
// 开启调色板量化,显著减小体积
instance = instance.png({ palette: true, compressionLevel: 9 });
} else {
// JPEG/WebP 默认高质量压缩
instance = instance.jpeg({ quality: options.quality || 88 });
}
return instance.toBuffer();
}
2. Vite 插件:构建流拦截
Vite 插件的核心在于利用 Rollup 的 generateBundle 钩子。在这个阶段,我们能获取到所有即将输出的资源文件,直接替换其内容。
// vite/index.js
export function compressVitePlugin(options) {
return {
name: '@zhaoshijun/compress',
apply: 'build', // 仅在构建时生效
async generateBundle(_, bundle) {
for (const fileName in bundle) {
// 筛选图片资源
if (isSupportedImage(fileName)) {
const originalBuffer = bundle[fileName].source;
// ⚡️ 核心:压缩并替换资源内容
const compressed = await compressImage(originalBuffer, config);
bundle[fileName].source = compressed;
// 同时更新文件名(如 logo.png -> logo.min.png)
// 并自动替换 JS/CSS 中的引用路径
}
}
}
};
}
3. 性能优化:基于内容的哈希缓存
为了避免每次构建都重新压缩所有图片,我们实现了一个简单的文件系统缓存。
// src/utils/cache.js
export async function getCache(content) {
// 计算文件内容 Hash
const hash = crypto.createHash('sha256').update(content).digest('hex');
const cachePath = path.join(CACHE_DIR, hash);
// 如果 Hash 命中,直接返回缓存文件,跳过压缩
if (await fs.pathExists(cachePath)) {
return await fs.readFile(cachePath);
}
return null;
}
🛠 快速上手指南
第一步:安装
npm install @zhaoshijun/compress -D
场景一:使用 CLI 批量压缩存量图片
如果你有一堆静态图片需要处理,直接运行 CLI 命令:
# 扫描当前目录,压缩图片并输出到 ./compressed 目录
npx @zhaoshijun/compress
# 常用参数
# --dry-run : 仅预览,不实际写入
# --backup : 备份原文件
CLI 会在终端显示进度条和压缩前后的体积对比:
✔ assets/banner.jpg: 1.2 MB → 450 KB (Saved 62.5%)
场景二:集成到 Vite 项目
在 vite.config.js 中配置插件,即可在打包时自动瘦身:
import { defineConfig } from 'vite';
import { compressVitePlugin } from '@zhaoshijun/compress';
export default defineConfig({
plugins: [
compressVitePlugin({
quality: 80, // 压缩质量
cache: true // 开启缓存
})
]
});
以后每次运行 npm run build,你的产物图片就已经是最优体积了!
🔗 总结
工具化、自动化是提升前端工程效率的关键。@zhaoshijun/compress 通过简单的配置,解决了图片压缩这一高频痛点。
欢迎大家下载体验,如果有问题或建议,欢迎在评论区留言!
本文使用 markdown.com.cn 排版