本文记录了如何在 Next.js + Bun 项目中配置 Husky,实现 commit 和 push 前的自动代码质量检查,确保代码质量和部署安全。
📋 目录
🎯 背景与目标
问题背景
在团队开发中,经常遇到以下问题:
- 代码格式不统一,影响可读性
- TypeScript 类型错误导致运行时问题
- 构建失败但已推送到远程仓库
- 部署时才发现代码问题,影响发布流程
解决方案目标
- 自动化检查:在 Git 操作时自动运行代码质量检查
- 快速反馈:在本地就能发现并修复问题
- 团队统一:确保所有团队成员使用相同的质量标准
- 部署安全:防止有问题的代码进入生产环境
🛠️ 技术选型
为什么选择 Husky?
工具 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
Husky | 功能强大、社区活跃、配置灵活 | 学习成本中等 | 中大型项目 |
simple-git-hooks | 轻量级、零配置 | 功能有限 | 小型项目 |
手动 Git Hooks | 完全控制 | 维护成本高、不便于团队协作 | 特殊需求 |
技术栈
- 包管理器:Bun
- 代码检查:Biome(替代 ESLint + Prettier)
- 类型检查:TypeScript
- 构建工具:Next.js
- Git Hooks:Husky v9
🔧 环境准备
1. 项目依赖
确保项目已安装必要依赖:
json
1234567
{
"devDependencies": {
"@biomejs/biome": "1.9.4",
"husky": "^9.1.7",
"typescript": "^5.8.2"
}
}
2. 现有脚本
项目已有的相关脚本:
json
12345678
{
"scripts": {
"build": "next build",
"typecheck": "tsc --noEmit",
"check": "biome check .",
"check:write": "biome check --write ."
}
}
⚙️ 配置步骤
步骤 1:安装 Husky
bash
12345
# 安装 Husky
bun add -D husky
# 初始化 Husky
bunx husky init
步骤 2:配置 package.json
更新 package.json
中的 prepare
脚本:
json
12345
{
"scripts": {
"prepare": "husky"
}
}
重要:使用 Husky v9 语法,不是 v8 的 "husky install"
。
步骤 3:创建 pre-commit Hook
创建 .husky/pre-commit
文件:
bash
1234567891011121314151617181920212223
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# Git hook: pre-commit
# Fast checks only – lint + type (bun)
echo "🧹 Running code quality checks..."
echo "📝 Checking code style with Biome..."
bun run check
if [ $? -ne 0 ]; then
echo "❌ Biome check failed! Please fix the issues above."
exit 1
fi
echo "🔍 Type checking..."
bun run typecheck
if [ $? -ne 0 ]; then
echo "❌ Type check failed! Please fix the type errors above."
exit 1
fi
echo "✅ Pre-commit checks passed!"
步骤 4:创建 pre-push Hook
创建 .husky/pre-push
文件:
bash
123456789101112131415161718192021
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# Git hook: pre-push
# Heavy check – build to catch compile-time issues (bun)
echo "🔍 Running type check..."
bun run typecheck
if [ $? -ne 0 ]; then
echo "❌ Type check failed!"
exit 1
fi
echo "🏗️ Testing production build..."
bun run build
if [ $? -ne 0 ]; then
echo "❌ Build failed! Push cancelled."
exit 1
fi
echo "✅ All checks passed! Pushing to remote..."
步骤 5:设置执行权限
bash
123456
# 重新初始化 Husky(自动设置权限)
bun run prepare
# 手动设置权限(如果需要)
chmod +x .husky/pre-commit
chmod +x .husky/pre-push
🔍 工作原理
Git Hooks 机制
mermaid
12345678910
graph TD
A[git commit] --> B[pre-commit hook]
B --> C{检查通过?}
C -->|是| D[提交成功]
C -->|否| E[提交失败]
F[git push] --> G[pre-push hook]
G --> H{检查通过?}
H -->|是| I[推送成功]
H -->|否| J[推送失败]
Husky 核心文件结构
plaintext
1234567
.husky/
├── _/ # Husky 核心目录(不跟踪)
│ ├── husky.sh # 核心脚本
│ ├── pre-commit # 模板文件
│ └── pre-push # 模板文件
├── pre-commit # 自定义 hook(跟踪)
└── pre-push # 自定义 hook(跟踪)
关键代码解析
1. Husky 导入
bash
1
. "$(dirname -- "$0")/_/husky.sh"
- 加载 Husky 核心脚本
- 设置正确的工作目录和环境变量
- 必须包含,否则 hooks 无法正常工作
2. 错误处理
bash
12345
bun run check
if [ $? -ne 0 ]; then
echo "❌ Check failed!"
exit 1
fi
-
$?
获取上一个命令的退出码 -
exit 1
阻止 Git 操作继续 - 提供清晰的错误提示
📖 使用指南
正常使用
bash
12345
# 提交代码(自动运行 pre-commit 检查)
git commit -m "feat: add new feature"
# 推送代码(自动运行 pre-push 检查)
git push
跳过检查
bash
12345
# 跳过 pre-commit 检查
git commit --no-verify -m "urgent fix"
# 跳过 pre-push 检查
git push --no-verify
检查结果示例
成功情况
bash
1234
🧹 Running code quality checks...
📝 Checking code style with Biome...
🔍 Type checking...
✅ Pre-commit checks passed!
失败情况
bash
1234
🧹 Running code quality checks...
📝 Checking code style with Biome...
❌ Biome check failed! Please fix the issues above.
husky - pre-commit script failed (code 1)
⚡ 性能优化
问题分析
当前配置的耗时:
- TypeScript 检查:~1-2秒
- Next.js 构建:~6-8秒
- 总耗时:~8-10秒
优化策略
策略 1:分支差异化检查
修改 .husky/pre-push
:
bash
12345678910111213141516171819
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
branch="$(git rev-parse --abbrev-ref HEAD)"
# 只在主分支进行完整检查
if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then
echo "🚨 Pushing to protected branch, running full checks..."
echo "🔍 Running type check..."
bun run typecheck || exit 1
echo "🏗️ Testing production build..."
bun run build || exit 1
else
echo "🔍 Running type check only (feature branch)..."
bun run typecheck || exit 1
fi
echo "✅ All checks passed! Pushing to remote..."
策略 2:构建缓存优化
bash
12345678910111213141516
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo "🔍 Running type check..."
bun run typecheck || exit 1
# 尝试快速构建检查
echo "📦 Checking build compatibility..."
if bun run build --dry-run 2>/dev/null; then
echo "✅ Build check passed!"
else
echo "🏗️ Running full build test..."
bun run build || exit 1
fi
echo "✅ All checks passed! Pushing to remote..."
性能对比
策略 | Push 耗时 | 质量保障 | 适用场景 |
---|---|---|---|
无检查 | <1秒 | 无 | 个人项目 |
仅类型检查 | 1-2秒 | 中等 | 开发分支 |
完整检查 | 8-10秒 | 高 | 主分支 |
分支策略 | 1-10秒 | 高 | 团队项目 |
🔧 故障排除
常见问题
1. Hook 不执行
症状:Git 操作没有触发检查
原因:
- 缺少 Husky 导入
- 文件权限不正确
- Husky 未正确初始化
解决:
bash
12345678
# 检查文件权限
ls -la .husky/pre-commit
# 重新初始化
bun run prepare
# 手动设置权限
chmod +x .husky/pre-commit
2. 检查失败但操作继续
症状:看到错误信息但 Git 操作成功
原因:缺少 exit 1
解决:确保每个检查都有错误处理:
bash
1
bun run check || exit 1
3. 环境变量问题
症状:找不到 bun
或 node
命令
原因:PATH 环境变量不正确
解决:使用绝对路径或确保 Husky 正确加载环境:
bash
12345
# 使用绝对路径
/usr/local/bin/bun run check
# 或确保 husky.sh 正确加载
. "$(dirname -- "$0")/_/husky.sh"
调试技巧
1. 手动测试 Hook
bash
12345
# 直接运行 hook 文件
./.husky/pre-commit
# 查看详细输出
bash -x ./.husky/pre-commit
2. 检查 Git 配置
bash
1234
# 查看 Git hooks 目录
git config core.hooksPath
# 应该指向 .husky
3. 查看 Husky 状态
bash
12345
# 检查 Husky 是否正确安装
bunx husky --version
# 查看 hooks 列表
ls -la .husky/
🏆 最佳实践
1. 团队协作
Git 跟踪策略
bash
123456
# ✅ 应该跟踪的文件
.husky/pre-commit
.husky/pre-push
# ❌ 不应该跟踪的文件
.husky/_/
新成员设置
bash
12345
# 克隆项目后
git clone <repo>
cd <project>
bun install # 自动运行 prepare 脚本
# 完成!hooks 自动生效
2. 检查策略
分层检查
- pre-commit:快速检查(格式 + 类型)
- pre-push:完整检查(类型 + 构建)
- CI/CD:最终保障(测试 + 部署)
检查内容
bash
123456789
# pre-commit:快速反馈
- 代码格式检查
- 基础类型检查
- 语法错误检查
# pre-push:部署安全
- 完整类型检查
- 构建兼容性测试
- 关键功能验证
3. 错误处理
用户友好的提示
bash
12
echo "❌ Type check failed! Please fix the type errors above."
echo "💡 Run 'bun run typecheck' to see detailed errors."
提供修复建议
bash
12
echo "🔧 To fix formatting issues, run:"
echo " bun run check:write"
4. 性能考虑
缓存利用
- 利用 TypeScript 增量编译
- 使用 Next.js 构建缓存
- 避免重复检查未修改的文件
并行检查
bash
12
# 同时运行多个检查
bun run check & bun run typecheck & wait
📊 效果评估
配置前后对比
指标 | 配置前 | 配置后 | 改善 |
---|---|---|---|
代码格式一致性 | 60% | 95% | +35% |
类型错误发现时机 | 运行时 | 提交时 | 提前发现 |
构建失败率 | 15% | 2% | -13% |
团队代码质量 | 参差不齐 | 统一标准 | 显著提升 |
实际收益
- 开发效率:问题在本地就能发现,减少调试时间
- 代码质量:统一的格式和类型检查,提高可维护性
- 部署安全:避免有问题的代码进入生产环境
- 团队协作:统一的开发标准,减少代码审查时间
🔮 未来扩展
可能的增强
- 测试集成:在 pre-push 中加入单元测试
- 安全扫描:集成依赖漏洞检查
- 性能检查:Bundle 大小和性能指标
- 提交信息规范:使用 commitlint 规范提交信息
高级配置示例
bash
1234567891011121314
# 集成测试的 pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo "🔍 Running type check..."
bun run typecheck || exit 1
echo "🧪 Running tests..."
bun run test || exit 1
echo "🏗️ Testing production build..."
bun run build || exit 1
echo "✅ All checks passed! Pushing to remote..."
📚 参考资源
官方文档
相关工具
- lint-staged - 只检查暂存的文件
- commitlint - 提交信息规范检查
- lefthook - 现代化的 Git hooks 管理
最佳实践参考
📝 总结
通过配置 Husky Git Hooks,我们实现了:
✅ 自动化代码质量检查
✅ 团队开发标准统一
✅ 部署安全性保障
✅ 开发效率提升
这套配置在保证代码质量的同时,也考虑了开发体验和性能优化。通过合理的分层检查策略,既保证了主分支的代码质量,又不会让日常开发过于缓慢。
记住:好的工具配置是团队高效协作的基础,投资在工具配置上的时间,会在长期的开发过程中得到丰厚的回报。
最后更新:2024年10月19日
作者:Frankie
项目:Zetar Mold Production System