跳到主要内容

commit

  1. husky是什么?原理是什么?

    • 什么是 Husky? Husky 是一个用于管理 Git hooks 的工具,让你可以在特定 Git 操作(如 commit、push)时自动执行脚本操作,比如:

      • 提交前自动 eslint --fix

      • 提交信息格式校验(配合 commitlint)

      • push 前运行单元测试或构建检查

    • Git Hooks 是什么?
      Git 本身提供了一组“钩子”机制,即你可以在某些操作发生前/后触发脚本:

      Git Hook触发时机常见用途
      pre-commit执行 git commit 之前自动代码格式化、Lint 检查
      commit-msg提交信息写入后校验提交信息格式(如 Conventional Commits)
      pre-push执行 git push执行测试或构建检查
      post-push执行 git push发送通知、部署应用等
      Git 默认会在 .git/hooks 中放置这些钩子的示例文件(如 pre-commit.sample),但它默认不启用、也不便于团队协作。
    • Husky 的作用和优势

      传统手动 Hook 设置Husky 提供的方式
      手动编辑 .git/hooks/xxx在项目中集中管理 .husky/xxx
      不易共享、无版本控制脚本托管在项目,自动安装
      无执行权限、易失效自动赋权,易于团队统一
    • Husky 的原理(深入理解)

      1. 安装时(执行 husky install):
        Husky 会在 .git/hooks/ 目录下创建一个软链接或脚本文件:

        .git/hooks/pre-commit

        其内容类似于:

        #!/bin/sh
        . "$(dirname "$0")/../../.husky/_/husky.sh"
        exec <project-root>/.husky/pre-commit "$@"

        这段脚本的作用是:从 .git/hooks/ 间接调用 .husky/ 目录下你写的实际逻辑脚本。

      2. 当你执行 git commit:

        • Git 触发 .git/hooks/pre-commit;

        • Husky 的 pre-commit 脚本执行(例如运行 npx lint-staged);

        • 如果脚本返回非 0(出错),Git 提交会被中止。

    • Husky 的执行流程图

      你执行 git commit

      └───► .git/hooks/pre-commit

      └───► .husky/pre-commit

      └───► 执行脚本(lint、测试、检查等)

    • 常见应用场景举例

    操作配合工具说明
    提交前运行 Linteslintlint-staged保证代码格式规范、自动修复问题
    校验提交信息格式commitlint遵循 Conventional Commits,便于自动生成 changelog
    push 前运行测试/构建vitestvue-tsc保证 push 的代码无语法或逻辑错误
  2. 使用 Commitizen + commitlint + husky + cz-conventional-changelog/cz-customizable 实现交互式提交 + 格式校验 + Git 提交钩子

    1. 安装依赖

      pnpm add -D commitizen cz-conventional-changelog commitlint @commitlint/cli husky

      package.json 中添加初始化命令:

      "scripts": {
      "prepare": "pnpm install && pnpm exec husky init",
      }
    2. 初始化 husky + commitlint 校验钩子 由于 Husky 9.x 移除了 add 命令,使用 手动创建 Git hook 文件 + chmod +x 的方式,因此我们需要手动添加钩子, 在 .husky 目录下创建 commit-msg 文件,写入:

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

      npx --no -- commitlint --edit "$1"

      命令解释:
      . "$(dirname "$0")/_/husky.sh"

      部分含义
      .等价于source,在当前 Shell 环境中执行 *.sh 脚本里的命令(不会开启子进程)
      dirname "$0"当前脚本文件所在目录的路径
      $(dirname "$0")输出:.husky
      $(dirname "$0")/_/husky.sh输出:.husky/_/husky.sh,这个 husky.sh 是 Husky 安装时自动创建的脚本模板,用于1. 初始化一些默认变量;2. 检查当前是否在 Git 仓库中;3. 提供一些通用的执行兼容逻辑。

      整体意思就是:引入 .husky/_/husky.sh 文件,让当前的 hook(如 pre-commit、commit-msg)在执行时具备 Husky 的执行环境和保护逻辑。

      npx --no -- commitlint --edit "$1"

      • npx:执行一个临时安装的 npm 包(这里是 commitlint)
      • --no:这是 npx 的参数,意思是:不要自动安装缺失的包,只用本地项目里的。
      • --:这是 参数分隔符,告诉 npx:“后面的参数不是给 npx 的,而是给它执行的那个命令(commitlint)的”。
      • commitlint --edit $1:这是 commitlint 的实际命令,意思是:校验某个文件里的提交信息是否符合规范。$1 是 commitlint 的参数,表示要校验的文件路径,这个路径由 Git 传递给 commit-msg 钩子。

      整体意思就是:执行 commitlint,校验某个文件里的提交信息是否符合规范。这个文件路径由 Git 传递给 commit-msg 钩子。

    3. 配置 commitlint(校验规则) 新建文件 commitlint.config.ts:

      // commitlint.config.js
      module.exports = {
      extends: ['@commitlint/config-conventional']
      }
    4. 设置 Commitizen 适配器

      // package.json
      {
      "config": {
      "commitizen": {
      "path": "cz-conventional-changelog"
      }
      }
      }
    5. 添加提交命令

      // package.json
      {
      "scripts": {
      "commit": "cz"
      }
      }
    6. 自定义交互式命令 移除 cz-conventional-changelog,安装 cz-customizable

      pnpm remove cz-conventional-changelog
      pnpm add -D cz-customizable

      修改 package.json

      // package.json
      {
      "config": {
      "commitizen": {
      "path": "cz-customizable"
      },
      "cz-customizable": {
      "config": "./.cz-config.cjs"
      }
      }
      }
    7. 创建配置文件 .cz-config.cjs(项目根目录)

提交规范工具依赖作用对比表

包名 📦作用简述所在阶段备注说明
@commitlint/cli提供 commitlint 的命令行工具,用于校验提交信息是否符合规范Git hook: commit-msg通常在 .husky/commit-msg 中调用:npx commitlint --edit $1
@commitlint/config-conventionalcommitlint 的配置 preset,遵循 Conventional Commits 规范配置文件中使用必须配合 commitlint.config.js 中的 extends 一起使用
commitlintcommitlint 核心模块,自动引入 CLI 与配置校验逻辑核心工具通常项目中只装 CLI 就够,commitlint 本体可以理解为 umbrella package
huskyGit Hook 管理工具,用于在 commit/push 前自动执行脚本Git Hooks 阶段会在 .git/hooks 中注册触发器,调用 .husky/ 目录下脚本
commitizen提供交互式命令行提交工具(cz),引导用户输入规范提交信息开发者手动执行命令为 npx czpnpm commit,用于生成符合规范的 commit message
cz-customizablecommitizen 的自定义配置适配器,可以自定义提交类型、提示内容配合 commitizen 使用.cz-config.js 中配置 typesscopesmessages

INTERVIEW

  1. 你在项目搭建中做了哪些?
    我在项目中配置了 Git 提交规范系统,包括 Commitizen 的交互式提交工具,结合 cz-conventional-changelog 实现统一的提交风格,同时使用 commitlint + husky 配置 Git 钩子校验每次 commit 信息是否合规。这样我们整个团队的 Git 历史记录非常清晰,也可以结合 standard-version 或 semantic-release 实现 changelog 和自动版本发布。
    我使用 cz-customizable 替代了默认的 cz-conventional-changelog,来自定义提交类型,使其更贴合我们业务领域,方便本地开发人员理解。例如我们加入了 ui 类型用于区分仅涉及视觉调整的提交,同时我们将交互语言配置为中文,提高团队一致性和提交规范的落地。

参考文档