Git Hooks 与 Husky
约 695 字大约 2 分钟
GitHuskylint-staged
2024-08-13
Git Hooks
概念
Git Hooks 是在 Git 事件发生时自动执行的脚本。
客户端钩子
| 钩子 | 时机 |
|---|---|
| pre-commit | 提交前执行 |
| prepare-commit-msg | 提交消息编辑前 |
| commit-msg | 提交消息创建后 |
| post-commit | 提交完成后 |
| pre-push | 推送前 |
| pre-rebase | 变基前 |
服务端钩子
| 钩子 | 时机 |
|---|---|
| pre-receive | 接收推送前 |
| update | 更新引用前 |
| post-receive | 接收推送后 |
Husky
安装
pnpm add -D husky
npx husky install配置
// package.json
{
"scripts": {
"prepare": "husky install"
}
}添加钩子
# 创建钩子
npx husky add .husky/pre-commit "pnpm lint"
# 或手动创建
mkdir -p .husky
echo '#!/usr/bin/env sh' > .husky/pre-commit
echo 'pnpm lint' >> .husky/pre-commit
chmod +x .husky/pre-commitpre-commit 示例
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm lint
pnpm testlint-staged
安装
pnpm add -D lint-staged配置
// package.json
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,sass}": [
"stylelint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
}配合 Husky
npx husky add .husky/pre-commit "pnpm lint-staged"ESLint 配合
.eslintrc.js
module.exports = {
root: true,
extends: ['eslint:recommended'],
parserOptions: {
ecmaVersion: 2022,
sourceType: 'module',
},
rules: {
'no-console': 'warn',
'no-unused-vars': 'error',
},
};pre-commit 检查
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo "Running ESLint..."
pnpm eslint --max-warnings=0 .Prettier 配合
.prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100,
"arrowParens": "always"
}pre-commit 格式化
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm exec prettier --write .Commitlint
安装
pnpm add -D @commitlint/config-conventional @commitlint/cli配置
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert'],
],
},
};配合 Husky
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'完整工作流
安装脚本
#!/bin/bash
pnpm add -D husky lint-staged @commitlint/cli @commitlint/config-conventional
npx husky install
pnpm add -D -w eslint prettier stylelint配置脚本
# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo "Running pre-commit checks..."
pnpm lint-staged
echo "Pre-commit checks passed!"package.json
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,sass,less}": [
"stylelint --fix",
"prettier --write"
],
"*.{json,md,mdx,html}": [
"prettier --write"
]
},
"scripts": {
"prepare": "husky install",
"lint": "eslint src --ext .js,.jsx,.ts,.tsx",
"lint:style": "stylelint src --ext .css,.scss,.sass",
"format": "prettier --write ."
}
}TypeScript 检查
pre-commit 检查
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm tsc --noEmitlint-staged 配置
{
"lint-staged": {
"*.{ts,tsx}": [
"tsc --noEmit",
"eslint --fix",
"prettier --write"
]
}
}跳过 Hooks
场景
- 回滚操作
- 紧急修复
- 特定 CI 环境
# 跳过 pre-commit
git commit --no-verify -m "Emergency fix"
# 跳过 pre-push
git push --no-verify调试
查看 Hooks
# 查看所有 hooks
ls .husky/
# 查看钩子内容
cat .husky/pre-commit测试钩子
# 手动执行钩子
sh .husky/pre-commit
# 查看 git 变量
GIT_DEBUG=1 git commit -m "test"最佳实践
- 保持快速: 钩子执行应快速完成,避免超过 30 秒
- 清晰反馈: 执行失败时提供清晰的错误信息
- 可跳过: 提供
--no-verify选项用于紧急情况 - CI 一致: 本地检查应与 CI 配置保持一致
- 缓存结果: 使用 ESLint flat config 或缓存加速
