WEBKT

告别扯皮!用 Git Hooks + lint-staged 打造团队代码风格的自动“守门员”

4 0 0 0

你是不是也受够了在 Code Review 里争论缩进是两格还是四格?行尾要不要加分号?每次提交前都要手动跑一遍格式化命令也太反人类了。

是时候把这些琐事交给机器了。今天手把手带你搭建一个基于 Git Hooks 的自动化代码检查和格式化流程,让不符合规范的代码根本无法进入仓库,从根源上保证团队代码的一致性。

🛠️ 我们的武器库

这套方案的核心是几个精巧的工具组合:

  1. Husky:现代化地管理 Git Hooks。它让你能像在 package.json 里配置脚本一样轻松定义钩子行为,解决了原生 hooks 难以同步给团队成员的问题。
  2. lint-staged:“利器”。它只对 git add 后暂存区(staged)的文件运行指定的命令,快如闪电⚡。让你没必要每次都对整个项目进行 linting。
  3. Prettier & ESLint :分别负责代码格式化(风格)和静态检查(质量问题)。Prettier “专断独行”,但能消除所有风格争论;ESLint 灵活可配置,捕捉潜在错误。

🚀 四步搭建自动化流水线

假设我们有一个 Node.js 项目。

Step 1: 安装依赖

npm install --save-dev husky lint-staged prettier eslint
# 或者用 yarn / pnpm

Step 2: 启用 Husky

现代版本的 Husky (v7+) 安装后会自动完成初始化。通常你只需要执行:

npx husky-init && npm install

这个命令会做三件事:

  1. package.json 中添加一个准备脚本 "prepare": "husky install"
  2. 创建 .husky 目录(这里就是存放我们钩子脚本的地方)。
  3. .husky/pre-commit 中生成一个示例钩子文件。

现在,Husky 已经接管了你项目的 Git Hooks。.husky 目录是可以提交到版本库的!

Step 3: 配置 lint-staged

package.json (或单独的 .lintstagedrc.js等文件)中添加配置:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix", // ESLint自动修复
      "prettier --write" // Prettier格式化
    ],
    "*.{css,scss,less,md,json}": [
      "prettier --write"
    ]
  }
}

这个配置的意思是:

  • 对于暂存区的 JS/TS 等文件,先跑 ESLint 修复问题,再用 Prettier 统一格式化。
  • 对于样式文件、Markdown、JSON等,直接用 Prettier格式化。

Step 4: “焊接” Husky 与 lint-staged

修改 .husky/pre-commit 这个钩子文件:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

搞定!现在当你执行 git commit时,会触发以下链条:
git commit → Husky(pre-commit) → npx lint-staged → lint-staged读取配置 → 仅对暂存文件依次执行 ESLint & Prettier → (如果全部通过)→ Commit成功;(如果检查出错或格式化有冲突)→ Commit中止。

🔧 Why & How It Works?

Q: .git/hooks里的钩子不是不能共享吗?

A: Bingo!这是原生Hook的最大痛点。Husky的方案是在.git/hooks里安装一个通用的“代理”,这个代理会去执行项目目录下.husky/里的对应脚本(比如pre-commit)。而.husky/目录是可以随项目一起提交的!新成员克隆项目后运行一次 npm install (会触发prepare脚本),就自动完成了Hook的安装。

Q: pre-commit vs pre-push?

A: pre-commit更快反馈,“脏”代码不会进本地历史;pre-push允许你在本地自由Commit(比如WIP),但在分享给他人前做最终检查。我们一般选pre-commit来保证每个提交点都是干净的。(注:你可以在.husky/pre-push里添加单元测试等更耗时的检查)。

Q: ESLint和Prettier冲突怎么办?

A: ESLint主要负责代码质量规则(如未使用的变量),Prettier负责风格(空格、换行)。使用 eslint-config-prettier来关闭ESLint中所有与格式相关的规则,让Prettier接管即可。

📈 进阶技巧与避坑指南

  1. 指定配置文件路径
    如果你的配置文件不在根目录:

    {
      "lint-staged": {
        "*.js": ["prettier --write --config ./path/to/.prettierrc"]
      }
    }
    
  2. 跳过Hook提交
    偶尔需要绕过检查(慎用):

    git commit -m \"紧急fix\" --no-verify # or -n
    
  3. 只对新增文件生效?
    可以在Hook脚本里结合 git diff --cached --name-only --diff-filter=A来识别新增文件并应用特殊规则(例如必须添加版权声明)。

  4. 支持Monorepo?
    在根项目的package.json中配置husky和lint-staged即可作用于所有子包。

✨ One More Thing

真正的工程化不止于此。你可以将这个流程扩展:
.

个人习惯是把项目的这套配置固化成一个脚手架或模板仓库。新项目初始化时一键拥有完整的代码风格守护能力。“工欲善其事必先利其器”,把时间浪费在和机器较劲上不值得。

CodeSailor Git Hooks前端工程化代码规范

评论点评