Claude Code实战教程(8):Hooks进阶指南——自动化守门员
《从零开始的 Claude Code 实战系列教程》第 8 篇 · 公众号「麒麟剑的AI自动化Lab」连载
▲ Hooks 就像自动化守门员,在关键时刻拦截问题,保障代码质量
一、你有没有遇到过这些情况?
- “每次提交代码前都要手动跑测试,烦死了”
- “团队新人经常在代码里写 console.log,调试完忘了删”
- “代码格式不统一,每个人写法都不一样”
传统做法是用 Git Hooks(pre-commit、pre-push),但配置复杂,容易出错。
Claude Code 的 Hooks 更简单、更强大——用自然语言描述规则,AI 帮你执行检查。
二、Hooks 是什么?为什么它值得你关注?
Hooks 是 Claude Code 的”自动化守门员”——在文件修改、命令执行等关键时刻自动运行的脚本。
核心价值
| 价值 | 说明 |
|---|---|
| 质量保证 | 提交前自动检查代码规范 |
| 效率提升 | 避免重复的手动操作 |
| 一致性 | 团队所有人遵循相同规则 |
| 自动化 | 无需人工干预,自动执行 |
Hooks vs Git Hooks
| 特性 | Git Hooks | Claude Code Hooks |
|---|---|---|
| 配置方式 | 写 shell 脚本 | 写 YAML/JSON 配置 |
| 智能程度 | 只能执行固定命令 | AI 可以理解意图 |
| 灵活性 | 低 | 高 |
| 学习成本 | 中等 | 低 |
三、Hooks 的注册方式
配置路径
.claude/settings.json(项目级)
~/.claude/settings.json(全局级)配置文件结构
{
"hooks": {
"PreToolUse": [
{
"matcher": "(Write|Edit|WriteTo|Create|BatchEdit)",
"hooks": [
{
"type": "command",
"command": "pre-write-check.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "post-command-hook.sh"
}
]
}
]
}
}四、Hook 生命周期与输出协议
输入格式
{
"hook": "PreToolUse",
"hookId": "before-edit",
"params": {
"tool": "Write",
"path": "src/index.ts",
"content": "..."
},
"cwd": "/path/to/project"
}输出格式
继续执行:
{}阻止执行:
{
"approved": false,
"feedback": "禁止在 production 目录中使用 console.log"
}五、实战:创建 Pre-Commit Hook
Step 1:创建 Hook 脚本
mkdir -p .claude/hooks
cat > .claude/hooks/pre-write-check.sh << 'EOF'
#!/bin/bash
# pre-write-check.sh - 在文件写入前检查代码规范
read input
# 提取文件路径和内容
file_path=$(echo "$input" | jq -r '.params.path')
content=$(echo "$input" | jq -r '.params.content')
# 检查是否有 console.log(仅生产环境)
if echo "$content" | grep -q "console.log"; then
if [[ "$file_path" != *"test"* && "$file_path" != *"spec"* ]]; then
echo '{"approved": false, "feedback": "禁止在业务代码中使用 console.log,请使用 logger 模块"}'
exit 1
fi
fi
# 检查是否有 TODO/FIXME 注释
if echo "$content" | grep -qE "TODO|FIXME"; then
echo '{"approved": false, "feedback": "代码中包含 TODO/FIXME 注释,请先处理或移除"}'
exit 1
fi
# 检查文件格式(简单的换行检查)
if [[ -n "$content" ]] && [[ "${content: -1}" != $'\n' ]]; then
echo '{"feedback": "文件末尾应有一个换行符"}'
fi
echo '{}'
EOF
chmod +x .claude/hooks/pre-write-check.shStep 2:注册 Hook
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/pre-write-check.sh"
}
]
}
]
}
}Step 3:测试 Hook
在 Claude Code 中尝试写入包含 console.log 的代码,Hook 会阻止并提示。
六、常用 Hook 场景
1. Pre-Commit:提交前检查
{
"matcher": "(Write|Edit|WriteTo|Create|BatchEdit)",
"hooks": [
{
"type": "command",
"command": "pre-commit-check.sh"
}
]
}2. Post-Command:命令执行后验证
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "post-command-hook.sh"
}
]
}3. File Watcher:监听文件变化
{
"hooks": [
{
"type": "fileWatcher",
"path": "src/**/*.{ts,tsx}",
"intervalMs": 1000
}
]
}七、Hook 的 matcher 表达式
支持的 Tool 名称
Write, Edit, WriteTo, Create, BatchEdit, Bash, Read, Glob, Grep表达式语法
# 精确匹配
"matcher": "Bash"
# 正则匹配
"matcher": "(Write|Edit|WriteTo|Create)"
# 包含特定工具的命令
"matcher": "Bash.*test"八、高级技巧:组合多个 Hook
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "pre-write-check.sh",
"timeoutMs": 5000
}
]
},
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "pre-command-hook.sh"
}
]
}
]
}
}九、实战:创建测试覆盖率 Hook
cat > .claude/hooks/test-coverage-check.sh << 'EOF'
#!/bin/bash
read input
# 检查是否是测试相关的命令
if echo "$input" | grep -q "npm run test"; then
# 运行测试并获取覆盖率
npm run test:cov
# 检查覆盖率是否达标
COVERAGE=$(cat coverage/lcov.info | grep -oP 'branches.\K[^,]+' | head -1)
if [ "$COVERAGE" -lt 80 ]; then
echo '{"approved": false, "feedback": "测试覆盖率低于 80%,当前为 '"$COVERAGE"'%"}'
exit 1
fi
fi
echo '{}'
EOF十、本章小结
| 概念 | 说明 |
|---|---|
| Hook 类型 | PreToolUse, PostToolUse |
| matcher | 正则表达式,匹配工具名称 |
| 输出协议 | {"approved": false, "feedback": "..."} 阻止执行 |
| 配置位置 | .claude/settings.json |
| 常见场景 | 提交前检查、命令验证、文件监听 |
下期预告(第 9 篇):Subagents与多Agent并行——让多个Claude同时工作,速度提升3倍
关注本系列,从入门到专家,系统掌握 Claude Code 的全部技能。