← 返回题目列表

Git Hooks、Husky 和 lint-staged 在前端工程化中怎么配合?

中等 第 26 / 31 题 更新于 2026/07/29
前端工程化Git HooksHuskylint-staged

简化版

Git Hooks 可以在提交、推送等阶段执行脚本;Husky 用来管理项目级 hooks;lint-staged 只对暂存区文件运行格式化和 lint。它们常配合做提交前质量门禁,但不能替代 CI,因为本地 hook 可能被跳过。

详细版

常见组合:

  • pre-commit:运行 lint-staged,只检查本次改动文件。
  • commit-msg:校验 commit message 规范。
  • pre-push:可选跑轻量测试。
  • CI:跑完整 lint、test、build。

为什么用 lint-staged:

  • 全量 lint 在大项目里太慢。
  • 只检查暂存文件能提高提交体验。
  • 自动格式化后重新写回暂存区。

注意点:

  • hook 要快,太慢会被开发者绕过。
  • 本地 hook 可被 --no-verify 跳过。
  • CI 必须保留最终门禁。
  • 不要在 pre-commit 里跑超重任务。

完整版教学

一、本地门禁解决的是“早发现”

CI 能挡住坏代码进主干,但如果每次都等 CI 才发现格式错误,反馈太晚。Git Hooks 把部分检查前移到提交时,让低级问题在本地就被修掉。它的目标不是替代 CI,而是降低 CI 红灯和 review 噪声。

Husky 的价值是把 hooks 配置进项目,让团队共享同一套提交规则。lint-staged 则让检查范围缩小到暂存文件,避免每次提交都扫完整仓库。

git commit
  → pre-commit
  → lint-staged 检查暂存文件
  → commit-msg 校验提交信息
  → 进入远端 CI 全量检查

二、lint-staged 为什么只看暂存区

开发者本地可能有很多未完成文件。如果提交只改了 2 个文件,却全量格式化 500 个文件,会引入巨大无关 diff。lint-staged 只处理 git add 的文件,符合“提交什么检查什么”的直觉。

数字例子:全仓库 ESLint 需要 90 秒,暂存 3 个文件只需要 2 秒。90 秒的 pre-commit 很快会逼开发者使用 --no-verify;2 秒的检查更容易被团队接受。

{
  "lint-staged": {
    "*.{js,ts,vue,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,md,json}": ["prettier --write"]
  }
}

三、Husky 管的是 hook 分发

Git 原生 hooks 存在 .git/hooks,默认不随仓库提交。Husky 通过项目脚本把 hook 配置放进仓库,使团队成员安装依赖后自动拥有同样的 hook。这样规则不再靠口口相传。

不过安装脚本也要注意包管理器和 CI 环境。某些环境不需要安装 hooks,某些 monorepo 需要在根目录统一管理。工程化配置要服务团队,而不是变成“每台机器都要玄学修 hook”。

四、commit message 校验有什么意义

规范提交信息能让 changelog、版本发布、自动化分析更可靠。比如 Conventional Commits 中 feat: 表示功能,fix: 表示修复,BREAKING CHANGE 表示破坏性变更。工具可以据此生成发布日志。

类型含义示例
feat新功能feat: add login page
fix修复fix: correct price display
docs文档docs: update usage
refactor重构refactor: split hooks

这对组件库和多包发布尤其重要,因为版本和 changelog 经常依赖提交或 changeset 记录。

五、hook 不能承担太重任务

pre-commit 适合快任务:格式化、增量 lint、类型局部检查。全量测试、完整构建、端到端测试通常更适合 CI 或 pre-push。否则提交体验太慢,开发者会主动绕开 hook。

一个经验是 pre-commit 尽量控制在 5 到 10 秒内。超过 30 秒就要认真评估是否放错阶段。工程化不是越严格越好,而是在反馈速度和质量之间做平衡。

六、CI 是最终事实

本地 hooks 可以被跳过,也可能因为依赖没装、环境不同而失效。CI 才是合并前最终门禁。所有关键规则都应该在 CI 再跑一遍,尤其是 build、test、typecheck、安全扫描。

记忆钩子:本地 hook 是门口提醒,CI 是高速收费站;提醒可以漏,收费站不能撤。

七、常见误区与追问

  • 误区:有 Husky 就不需要 CI 检查。 本地 hook 可被跳过,CI 必须保留最终门禁。
  • 误区:pre-commit 越严格越好。 太慢会破坏体验,应把重任务放到 CI 或 pre-push。
  • 误区:lint-staged 会检查全仓库。 它主要处理暂存区文件,适合增量质量控制。
  • 追问:为什么格式化后还要重新 add? 格式化会修改文件,lint-staged 通常会把修改重新加入暂存区。
  • 追问:commit-msg 校验有什么价值? 支持 changelog、语义化发布和提交历史可读性。
  • 追问:如何防止 hook 环境不一致? 锁定 Node 和包管理器版本,并在 CI 中跑同样规则。

八、加强记忆

Git Hooks 这题用“本地快检,CI 终检”来记。Husky 负责分发 hooks,lint-staged 负责只检查暂存文件,commit-msg 负责提交规范;pre-commit 要快,CI 要全。本地体验和主干质量都照顾到,工程化才长久。