min-staged
v1.0.2
Published
基于 husky 和 lint-staged 的资源压缩工具,集自动压缩、旧项目迁移、压缩效果预览、单文件调整压缩参数等功能于一体!
Readme
概述
基于 husky 和 lint-staged 的资源压缩工具,压缩能力基于 sharp 和 svgo 实现。
动机
调研现有资源压缩方案及存在的问题:
- 优点:可预览压缩效果,支持调试压缩参数(squoosh)
- 缺点:重复人工工作
- build time 压缩,eg:vite-plugin-image-optimizer、unplugin-imagemin
- 优点:自动压缩,不用人工干预
- 缺点:每次 build 都要压缩、build 时间会随项目静态资源增加而变长、压缩参数对全局生效;
- git hook 压缩,eg:imagemin-lint-staged、imagemin-lint-staged sharp 版本
- 优点:自动压缩,无需人工干预
- 缺点:(总有几个存在)现有方案不再维护、不支持灵活配置压缩参数、不支持旧项目迁移、不支持实时预览效果、不支持单一更改压缩参数、压缩器会'过时';
那能不能开发一个工具既能兼有以上方案的优点,又能解决以上缺点呢?于是有了 min-staged。
功能
- [x] 1. 基于 git hook,在 git commit 时,自动压缩资源文件,与 git 相关,适用范围更广
- [x] 2. 旧项目迁移支持:提供 cli 命令批量压缩,eg:
npx min-staged --legacy -d ./src - [x] 3. 支持灵活配置覆盖默认配置(基于 cosmiconfig)
- [x] 4. 压缩完成后提供压缩效果确认页面,支持单文件更改压缩参数
- [x] 5. 支持插件系统,可自定义各格式压缩器(保持可扩展更新)
安装初始化
- 安装
lint-staged,并配置 pre-commit hook;
// pre-commit
pnpm exec lint-staged
# 或者用yarn 或 npm命令,和项目一致就行
# yarn run lint-staged
# npm run lint-staged- 安装
min-staged
# using npm
npm install -D min-staged
# using pnpm
pnpm install -D min-staged
# using yarn
yarn add --dev min-staged- 在
package.json中添加如下配置
// package.json
{
"lint-staged": {
"*.{png,jpeg,jpg,gif,svg}": ["min-staged"]
}
}使用
1. 新项目
每次 git commit 时,min-staged 会自动压缩符合 package.json 里指定格式的资源文件。
执行流程分两种模式:
无 preview 模式(默认):拿到文件列表 → 并发压缩 → 写入文件系统,自动完成,无需干预
有 preview 模式(配置
preview: true):启动本地预览服务 → 自动打开浏览器确认页面 → 用户确认后写入文件系统确认页面提供:左右分屏对比视图、实时调参面板(防抖 300ms),点击"确认全部并提交"后写入文件系统并继续 commit 流程。
若直接关闭确认页面,则按当前预览的结果写入(避免 commit 流程被挂住)。
2. 旧项目迁移
先执行以下命令,min-staged 会遍历该目录下符合格式的资源文件,批量压缩并自动创建一个提交:
# 目标目录 ./src 可自定义修改
npx min-staged --legacy -d ./src
--legacy表示旧项目迁移标识,-d表示需要压缩的目标资源目录
迁移完成后 min-staged 会自动创建一个提交,默认 message 为 Auto commit from min-staged.。
如果项目有自己的 commit 规范,用 legacyCommitMessage 覆盖:
// .min-stagedrc.json
{
"legacyCommitMessage": "chore: 压缩静态资源 #0"
}后续新文件会在 git commit 时自动压缩。
自定义压缩配置
配置基于 cosmiconfig 实现,推荐使用 .min-stagedrc.ts,也支持 .min-stagedrc.json、.min-stagedrc.yml、min-staged.config.js 等常见格式。
注意:使用
.min-stagedrc.ts需要项目已安装typescript(cosmiconfig 加载 TS 配置的前置依赖)。纯静态资源仓库等没有 TS 工具链的项目建议直接用.min-stagedrc.json。
顶层配置项
| 字段 | 类型 | 默认值 | 说明 |
| --------------------- | --------- | ------------------------------- | ------------------------------------------- |
| preview | boolean | false | 是否在写入前打开压缩确认页面 |
| legacyCommitMessage | string | 'Auto commit from min-staged.' | --legacy 迁移模式下自动提交的 commit message |
| plugin | object | 内置插件 | 各格式压缩器与参数,见下文 |
内置默认参数
| 格式 | 参数 | 默认值 | 范围 |
| -------------- | ---------------- | ------ | ------------------- |
| png | quality | 90 | 0–100 |
| png | compressionLevel | 9 | 0–9 |
| jpeg / jpg | quality | 80 | 0–100 |
| gif | effort | 10 | 1–10 |
| webp | quality | 80 | 0–100 |
| webp | lossless | false | — |
| svg | — | — | svgo preset-default |
覆盖默认参数(推荐)
只需提供想改的参数字段,compressor 继续使用内置实现,未提及的参数保留内置默认值:
// .min-stagedrc.ts
import type { MinStagedConfig } from 'min-staged';
export default {
plugin: {
png: {
params: {
quality: { default: 80 }, // 内置默认 90
compressionLevel: { default: 7 }, // 内置默认 9
},
},
jpeg: {
params: {
quality: { default: 75 }, // 内置默认 80
},
},
},
} satisfies MinStagedConfig;完整替换压缩器(高级)
提供 compressor 时,整体替换对应格式的内置实现,可配合 preview: true 开启确认页面:
// .min-stagedrc.ts
import type { MinStagedConfig } from 'min-staged';
export default {
preview: true, // 开启压缩确认页面
plugin: {
png: {
compressor: async (filePath, params) => {
const sharp = (await import('sharp')).default;
return sharp(filePath)
.png({ quality: params.quality as number })
.toBuffer();
},
// 可选:参数定义,用于在确认页面渲染调参 UI
params: {
quality: {
type: 'number',
description: '质量',
default: 85,
min: 0,
max: 100,
},
},
},
},
} satisfies MinStagedConfig;不配置
plugin时直接使用内置默认插件;配置了plugin.<ext>但未覆盖的格式仍使用内置实现。
插件参数类型
params 中每个字段的 type 决定确认页面渲染的调参控件:
| type | 控件 | 额外字段 |
| --------- | ------------------------------- | ------------------- |
| number | 数字输入框;有 min/max 时为滑块 | min, max |
| boolean | toggle 开关 | — |
| string | 文本输入框 | — |
| select | 下拉选择 | options: string[] |
TODO 列表
- [ ] 搜索代码里的 todo
- [ ] 项目工程化改进、ci 自动发布流程
- [ ] ...
