React企业中台实战 - 第三章.规约:代码提交规范的铁三角

第三章. 规约:代码质量与提交规范

在上一章,我们完成了项目的初始化与环境配置。现在,我们将为这座“大厦”建立一套不可动摇的“建筑规范”。一个没有规约的项目,最终会因混乱而坍塌。本章,我们将着手建立项目的“代码质量铁三角”:

  1. 代码质量 (Biome.js):建立统一、高效的代码格式化与 Lint 检查标准。
  2. 提交卡控 (Lefthook):在代码提交前,强制自动执行质量检查。
  3. 提交规范 (Commitlint):确保每一次代码提交记录都清晰、规范、可追溯。

这个体系将成为项目的“质量守门员”,确保任何进入代码库的代码,都符合团队的最高标准。

3.1. 代码质量基石:集成 Biome.js

3.1.1. 技术选型:为何选择 Biome

在集成工具之前,我们必须先阐明决策。ESLint + Prettier 是过去数年的黄金组合,但我们选择 Biome 是基于对 2025 年前端工程化趋势的判断,核心驱动力是 效率简化

  • 性能差异ESLintPrettier 基于 JavaScript/TypeScript 构建,在大型项目中,全量检查与格式化可能耗时数十秒。Biome 使用 Rust 编写,其执行速度是前两者组合的 数十倍。这种速度差异在本地提交和 CI/CD 流水线中,能带来显著的体验提升。
  • 配置与维护成本:ESLint + Prettier 方案需要维护至少两个独立的配置文件 (.eslintrc, .prettierrc)、一系列插件 (@typescript-eslint/parser 等) 以及解决它们之间规则冲突的工具 (eslint-config-prettier)。配置过程繁琐且容易出错。
  • 一体化优势:Biome 是一个 一体化 工具,它集成了 Formatter(格式化器)、Linter(检查器)和 Importer(导入排序器)。由于功能源自同一内核,它们的设计从根源上避免了规则冲突。我们用一个工具、一份配置,就替代了过去需要多个工具协作才能完成的工作。

选择 Biome,是一次明确的工程升级:用一个更现代、更高效的集成工具,替换掉一个需要繁琐配置才能协同工作的传统组合。

3.1.2. 安装并初始化 Biome

首先,我们将 Biome 作为开发依赖项添加到项目中。

1
pnpm add -D @biomejs/biome

安装完成后,我们不手动创建配置文件,而是使用 Biome 的官方命令来初始化,这能确保我们获得一个标准的、包含最新 schema 信息的配置文件。

1
pnpm biome init

执行后,项目根目录会生成一个 biome.json 文件。这是我们后续所有代码质量规则的配置中心。

3.1.3. 渐进式配置 biome.json

我们不会一次性展示最终配置,而是逐步添加和解释每一个配置块,理解其背后的架构决策。

第一步:定义基础格式化风格 (Formatter)

我们首先定义团队统一的代码格式化风格。现代开发实践和团队协作的舒适度是主要考量。

文件路径: biome.json

1
2
3
4
5
6
7
8
9
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"formatter": {
"enabled": true,
"lineWidth": 120,
"indentStyle": "space",
"indentWidth": 2
}
}
  • lineWidth: 120:在现代宽屏显示器下,Prettier 默认的 80 字符过于狭窄,常导致 TS 类型和 JSX 属性不自然地换行。120 字符是更舒适、可读性更高的标准。
  • indentStyle: "space"indentWidth: 2:我们选择使用 2 个空格进行缩进。这是社区中最广泛接受的规范,能确保在任何环境下代码的缩进表现都完全一致。

第二步:配置 Linter 基础规则

接下来,我们开启 Linter,并设定规则的取舍。这里的关键在于找到 严格性实用性 的平衡点。

文件路径: biome.json (追加 linter 配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"formatter": {
"enabled": true,
"lineWidth": 120,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "off"
},
"a11y": {
"useKeyWithClickEvents": "off"
}
}
}
}
  • rules: { recommended: true }:开启 Biome 推荐的所有规则集。这是我们的“基础安全网”,能捕获大量潜在的编码错误。
  • suspicious: { noExplicitAny: "off" }这是一个重要的架构妥协。在企业项目中,尤其是在与类型定义不完善的第三方库集成时,any 是一个必要的“逃生舱口”。我们的目标是 逐步减少 any 的使用,而不是在项目初期就“一刀切”导致开发流程卡顿。
  • a11y: { useKeyWithClickEvents: "off" }这是另一个基于场景的权衡。此规则要求 onClick 事件必须伴随键盘事件以保证无障碍访问。对于 Prorise-Admin 这样的企业内部系统,我们经常使用 divspan 附加 onClick 来构建自定义交互。为追求内部组件的开发灵活性,我们选择关闭此规则。

第三步:整合 JavaScript/TypeScript 特定配置

我们针对 JS/TS 文件,特别是 JSX 的书写习惯,进行微调。

文件路径: biome.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
// ... (formatter 和 linter 配置)
"linter": {
"enabled": true,
"rules": {
// ...
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"css": {
"linter": {
"enabled": false
}
},
}
  • quoteStyle: "single":在 JavaScript/TypeScript 代码中,我们统一使用单引号 ''
  • jsxQuoteStyle: "double":在 JSX (类 HTML) 的属性中,我们统一使用双引号 ""。这是 W3C 规范推荐的做法,也符合社区习惯,实现了代码与标记的风格区分。

注意:这里我们将Css关闭了,因为TailwincssV4的@theme注解无法被biome检测到,这在最新版本的pr中有提及过,还未更新,所以我们暂时关闭css的检测

第四步:配置自动导入排序 (Organizer)

这是 Biome 替代 eslint-plugin-simple-import-sort 的核心功能,用于保持代码整洁。

文件路径: biome.json (追加 organizer 配置)

1
2
3
4
5
6
7
8
{
// ... (formatter, linter, javascript 配置)
"jsxQuoteStyle": "double"
},
"organizer": {
"enabled": true
}
}
  • organizer: { enabled: true }:开启此功能后,Biome 将能够自动对 import 语句进行排序和分组,极大地提升了代码的规范性和可读性。

3.1.4. 解决 Biome 与“自动导入”的冲突(上一章完成)

配置完成后,我们面临一个预期中的问题:Biome 的 Linter 无法识别由 unplugin-auto-import 插件“魔法般”注入的全局 API,这在我们上一章就已经解决过了,但是我们重复一次

在终端中对 src/App.tsx 文件执行一次检查:

1
pnpm biome check src/App.tsx

你会立刻看到 Biome 抛出错误:

1
2
src/App.tsx:4:19 lint(correctness/noUndeclaredVariables)
✖ `useState` is not defined.

问题根源:Biome 只认通过 import 语句显式导入的变量。它不知道 unplugin-auto-import 在构建时会自动注入 useState

解决方案:我们需要让 Biome(以及 TypeScript 编译器 tsc)能够识别这些全局注入的 API。unplugin-auto-import 已经为我们生成了 auto-imports.d.ts 类型声明文件,我们只需在 tsconfig.json 中明确地包含它即可。

文件路径: tsconfig.json

1
2
3
4
5
6
7
8
9
10
11
12
{
"compilerOptions": {
"target": "ESNext",
// ... (其他配置)
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src", "auto-imports.d.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}

通过在 include 数组中加入 auto-imports.d.ts,我们告诉 TypeScript 和 Biome:“请加载这个文件,里面声明了一些全局可用的类型和变量”。

保存 tsconfig.json 后,再次运行检查命令:

1
pnpm biome check src/App.tsx

错误消失了! 这标志着我们的代码质量工具链与自动导入插件已成功协同工作。

3.1.5. Biome 常用命令速查

在日常开发中,我们会频繁使用以下 Biome 命令。理解它们的用途和区别,能让我们更高效地维护代码质量。

基础命令

1. 检查文件(仅报告问题,不修改)

1
2
3
4
5
6
7
8
# 检查单个文件
pnpm biome check src/App.tsx

# 检查整个 src 目录
pnpm biome check src

# 检查所有文件
pnpm biome check .

用途:在 CI/CD 流水线中使用,或在提交前确认代码质量。

2. 自动修复问题

1
2
3
4
5
6
7
8
# 修复单个文件
pnpm biome check --write src/App.tsx

# 修复整个 src 目录(推荐)
pnpm biome check --write src

# 修复所有文件
pnpm biome check --write .

用途:在提交前批量修复格式问题和安全的 Lint 错误。

3. 仅格式化(不执行 Lint 检查)

1
2
3
4
5
# 格式化单个文件
pnpm biome format --write src/App.tsx

# 格式化整个 src 目录
pnpm biome format --write src

用途:快速格式化代码,不关心 Lint 问题时使用。

4. 仅 Lint 检查(不格式化)

1
2
3
4
5
# 只检查 Lint 问题
pnpm biome lint src

# 修复可自动修复的 Lint 问题
pnpm biome lint --write src

用途:专注于代码质量问题,不改变格式。

进阶命令

5. 在受 Git 影响的文件上运行检查

1
2
3
4
5
# 只检查有改动的文件(需要配置 vcs.enabled)
pnpm biome check --changed

# 修复有改动的文件
pnpm biome check --write --changed

💡 用途:在大型项目中,只检查你修改过的文件,大幅提升速度。

6. 使用不同的配置文件

1
2
# 使用自定义配置文件
pnpm biome check --config-path=./biome.production.json src

推荐的 package.json 脚本

为了方便使用,我们可以在 package.json 中添加快捷脚本:

文件路径: package.json

1
2
3
4
5
6
7
{
"scripts": {
"lint": "biome check src",
"lint:fix": "biome check --write src",
"format": "biome format --write src"
}
}

这样,我们就可以使用更简洁的命令:

1
2
3
pnpm lint        # 检查
pnpm lint:fix # 修复
pnpm format # 格式化

3.1.6. VSCode 集成:让代码质量检查无感化

每次手动运行命令来修复代码格式,这在实际开发中是非常低效的。我们需要让编辑器在 保存时自动应用 Biome 规范,真正实现 “零手动操作” 的代码质量保障,首先我们需要按照官方文档的指示下载专属 Cil

手动安装 |Biomejs

第一步:安装 Biome VSCode 插件

在 VSCode 中安装官方插件:

  1. 打开 VSCode 扩展面板(Ctrl + Shift + X
  2. 搜索 Biome
  3. 安装 Biome 插件(发布者:biomejs

或者通过命令行安装:

1
code --install-extension biomejs.biome

第二步:配置项目级 VSCode 设置

为了确保团队所有成员都使用统一的编辑器配置,我们在项目中创建 .vscode/settings.json 文件。

文件路径: .vscode/settings.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
// 1. 设置 Biome 为默认格式化工具
"editor.defaultFormatter": "biomejs.biome",

// 2. 启用保存时自动格式化
"editor.formatOnSave": true,

// 3. 启用保存时自动修复 Lint 问题
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
},

// 4. 针对特定文件类型的配置
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[jsonc]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
  • editor.defaultFormatter:将 Biome 设为默认格式化工具,替代内置的或其他格式化工具(如 Prettier)。
  • editor.formatOnSave:每次保存文件时,自动执行格式化。
  • editor.codeActionsOnSave
    • quickfix.biome:自动修复可修复的 Lint 问题
    • source.organizeImports.biome:自动整理和排序 import 语句
  • 针对特定文件类型的配置:确保所有 JS/TS/React 文件都使用 Biome。

第三步:创建推荐扩展列表(可选)

为了让新加入的团队成员知道需要安装哪些插件,我们创建一个推荐扩展列表。

文件路径: .vscode/extensions.json

1
2
3
4
5
{
"recommendations": [
"biomejs.biome"
]
}

这样,当团队成员打开项目时,VSCode 会提示他们安装推荐的插件。

验证配置

  1. 打开 src/App.tsx
  2. 故意破坏格式(例如删除分号、改变缩进)
  3. Ctrl + S 保存
  4. 代码应该自动恢复正确的格式!

常见问题

Q: 保存时没有自动格式化?

  • 检查是否安装了 Biome 插件
  • 按 Shift + Alt + O(快捷键)
  • 重启 VSCode 窗口(Ctrl + Shift + PReload Window

Q: 与其他格式化工具冲突?

  • 禁用 Prettier、ESLint 等格式化插件,或在项目设置中明确指定 Biome 优先级

Q: 某些文件不想使用 Biome?

  • biome.json 中添加 files.ignore 配置:
1
2
3
4
5
{
"files": {
"ignore": ["dist", "node_modules", "*.min.js"]
}
}

阶段性成果:我们成功用 Biome 替换了传统的 ESLint + Prettier 组合,并基于企业级项目的实际需求,渐进式地定义了代码格式化风格与 Linter 规则。最关键的是,我们解决了 Biome Linter 与 unplugin-auto-import 之间的核心冲突,并通过 VSCode 集成实现了 “保存即规范” 的无感化开发体验。从现在开始,代码质量将不再是负担,而是自动化的基础设施。


3.2. 提交卡控:建立自动化的质量防线

3.1 节中,我们拥有了强大的 Biome 工具,并推荐配置了 VSCode 插件,实现了保存文件时自动格式化和检查。但这依赖于开发者的“自觉”和“正确的 IDE 配置”。

企业级项目工程化的核心原则之一,就是 将规范制度化、自动化,而不是依赖于人。万一有团队成员忘记安装插件,或者使用了其他编辑器,他依然可以提交格式混乱或存在明显错误的代码,这将导致代码库质量的“破窗效应”。

因此,我们必须建立一道与编辑器无关的、强制性的、自动化的最终防线——Git 提交卡控 (Git Hooks)

3.2.1. 技术选型:为何选择 Lefthook (而非 Husky)

Git 钩子 允许我们在 git commitgit push 等特定 git 操作发生时,自动执行预设的脚本。Husky 是这个领域的传统标准,但我们选择更现代的 Lefthook,这主要基于 性能维护性 的考量。

  • 性能
    Husky 基于 Node.js,每次执行钩子都需要启动 Node.js 进程,存在轻微的启动延迟。Lefthook 则是一个用 Go 语言 编写的独立二进制文件,其启动和执行速度是毫秒级的,几乎没有额外开销。在每天数十次的提交操作中,这种性能差异会累积成更流畅的开发体验。

  • 配置与维护性
    Husky 的配置分散在 .husky/ 目录下的多个 Shell 脚本文件中。Lefthook所有 钩子(如 pre-commit, commit-msg)的配置都集中在一个 单一lefthook.yml 文件中,这种中心化的声明式配置,可读性和可维护性远高于脚本式配置。

3.2.2. 安装与初始化 Lefthook

首先,我们将 Lefthook 作为开发依赖项添加到项目中。

1
pnpm add -D lefthook

安装完成后,必须执行 Lefthook 的初始化命令,将它“注入”到本地的 Git 配置中。

1
2
git init
pnpm lefthook install

lefthook install 做了什么?
这个命令会在你的本地 .git/hooks/ 目录中创建一系列可执行文件(如 pre-commit, commit-msg)。当你执行 git commit 时,Git 会自动调用 .git/hooks/pre-commit 这个钩子脚本,该脚本会启动 lefthooklefthook 接着读取 lefthook.yml 的配置来执行我们定义的任务。

3.2.3.渐进式配置 lefthook.yml

现在,我们在项目根目录已经存在了 lefthook.yml 文件,他默认是注释的,让我们从最核心的 pre-commit (提交前) 钩子开始配置

第一步:配置 Lint 检查任务

我们的首要目标是确保任何有 Lint 错误的代码都无法被提交。

文件路径: lefthook.yml

1
2
3
4
5
pre-commit:
commands:
lint:
glob: "*.{js,jsx,ts,tsx}"
run: pnpm biome lint {staged_files}
  • pre-commit: 定义了在执行 git commit 命令 之前 需要运行的任务。
  • commands: 该钩子下可以定义多个命令,这里我们定义了第一个命令,名为 lint
  • glob: 指定这个命令只对特定文件类型生效,避免在无关文件(如 .md)上运行 Linter。
  • run: 定义了要执行的脚本。{staged_files} 是 Lefthook 内置的变量,它非常关键,意味着 pnpm biome lint 只检查你通过 git add 命令暂存的文件,而不是全量检查项目,从而保证了钩子执行的极高速度。

第二步:演练 Lint 拦截

我们来实际验证一下这道防线是否生效。

首先,故意在 src/App.tsx 中制造一个 Lint 错误。

1
2
3
4
5
6
7
8
9
// src/App.tsx
function App() {
const [count, setCount] = useState(0)
const unusedVar = 'Prorise' // 添加一个未使用的变量

return (
// ...
)
}

然后,尝试提交这段有问题的代码。

1
2
git add .
git commit -m "feat: test lint failure"

Lefthook 将会立即介入,中止提交并抛出 Biome 的错误报告:

1
2
3
4
5
6
7
8
RUNNING pre-commit HOOK
RUNNING lint
✖ lint
src/App.tsx:4:9 lint(correctness/noUnusedVariables)
✖ `unusedVar` is declared but never used.

SUMMARY
└─ lint: FAILED

结果:提交被成功拦截。代码库得到了保护。

第三步:增加自动格式化与类型检查

现在我们的防线已经生效,我们来继续完善它,增加自动格式化和最终的类型检查。

文件路径: lefthook.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pre-commit:
parallel: true
commands:
lint:
glob: "*.{js,jsx,ts,tsx}"
run: pnpm biome lint {staged_files}

format:
glob: "*.{js,jsx,ts,tsx,json,md}"
run: pnpm biome format --write {staged_files}
stage_fixed: true

check-types:
run: pnpm tsc --noEmit
  • parallel: true:这是一个性能优化选项,告诉 Lefthook 同时并行执行下面所有的命令,以最大化利用 CPU 核心,缩短等待时间。
  • format 命令:我们在 Lint 检查的同时,增加了一个格式化任务。
    • --write:告诉 Biome 直接修改文件以修复格式问题。
    • stage_fixed: true:这是 Lefthook 的一个“杀手级”特性。如果 biome format 自动修复了文件的格式,Lefthook 会自动将这些修改重新 git add 到暂存区。这避免了开发者“修复了但忘了暂存”的常见错误。
  • check-types 命令:我们添加了 pnpm tsc --noEmit 作为最后的防线。它会进行全量的 TypeScript 类型检查,确保没有类型错误被提交。--noEmit 意味着只检查,不生成任何 JS 文件。

第四步:完整工作流演练

现在,我们修复 src/App.tsx 中的 Lint 错误(删除 unusedVar),并故意破坏一处格式(例如,删除几处缩进)。

然后再次提交:

1
2
git add .
git commit -m "feat: test auto-format and success"

你会观察到以下流程:

  1. Lefthook 并行启动 lint, format, check-types 任务。
  2. format 任务检测到格式问题,自动修复了 src/App.tsx 并将其重新暂存。
  3. lintcheck-types 任务均未发现错误,成功通过。
  4. 所有任务都成功后,git commit 命令顺利完成。

打开你的代码,你会发现格式已经被自动修正了。

阶段性成果:我们利用 Lefthook 建立了一套强大的、自动化的三阶段提交前质量防线。从现在起,任何不符合 Biome 格式、Lint 规则或 TypeScript 类型检查的代码,都将被 自动拦截自动修复git commit 阶段,确保了入库代码的最高质量。


3.3. 提交规范:让代码历史成为可读的文档

我们的代码质量已由 pre-commit 钩子严格把关,但“代码质量铁三角”还缺最后一环,也是同样重要的一环:提交信息的质量。高质量的代码,需要有高质量的提交历史来承载。

3.3.1. 问题的根源:混乱的 Commit Message

想象一下,项目上线后出现紧急 Bug,你需要快速回溯定位问题。你打开 Git 历史,看到的却是这样一幅景象:

灾难性的 Git Log:

1
2
3
4
5
- fix
- update code
- merged
- fix bug again
- aaa

这几乎是无效信息。你无法判断哪次提交引入了新功能,哪次是关键修复,回溯问题如同大海捞针,项目维护成本急剧升高。

3.3.2. 解决方案:约定式提交规范 (Conventional Commits)

为了解决这个问题,社区诞生了“约定式提交(Conventional Commits)”规范。它规定了一条简单但极其强大的提交信息结构。

一个标准的约定式提交信息结构如下:

1
2
3
4
5
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
  • type (类型): 必需项。用于说明本次提交的类别。我们不会自定义,而是直接采用社区最主流的 Angular 规范中的类型:

    • feat: 新功能 (feature)。
    • fix: 修复 Bug。
    • docs: 仅修改了文档。
    • style: 代码格式修改,不影响代码逻辑 (空格、分号等)。
    • refactor: 代码重构,既不是新增功能也不是修复 Bug。
    • perf: 提升性能的修改。
    • test: 增加或修改测试。
    • chore: 构建流程、辅助工具等非业务代码的变动 (例如修改 vite.config.ts)。
  • scope (范围): 可选项。用于说明本次提交影响的范围,例如某个具体模块。如 feat(auth)fix(header)

  • subject (主题): 必需项。对本次提交的简短描述,不超过 50 个字符。

规范化提交带来的价值是决定性的

  1. 可读性与可维护性:Git Log 本身就成了一份清晰的技术文档。
  2. 自动化:我们可以基于 type自动生成 CHANGELOG,自动判断版本升级策略。
  3. 精准追溯:当需要定位 Bug 时,可以快速过滤 fix 类型的提交,实现外科手术式的精准定位。

3.3.3. 集成工具链:安装与配置 Commitlint

现在我们理解了规范,接下来就需要一个工具来 强制执行 它。Commitlint 是这个领域的标准工具。

首先,安装 Commitlint 的命令行工具和我们刚刚学习的“约定式提交”规则包。

1
pnpm add -D @commitlint/cli @commitlint/config-conventional

然后,在项目根目录创建 commitlint.config.js 文件,声明我们将采用这套规则。
文件路径: commitlint.config.js

1
2
3
4
5
export default {
// 我们直接继承社区中最流行、最完善的 "约定式提交" 规则集。
// 这意味着我们无需手动配置每一条规则,直接拥抱社区最佳实践。
extends: ["@commitlint/config-conventional"],
};

3.3.4. 激活钩子:连接 Lefthook 与 Commitlint

工具已就绪,但它需要一个“扳机”来在正确的时间点触发。这个扳机就是 Git 的 commit-msg 钩子。我们回到 lefthook.yml 完成最后的连接。

文件路径: lefthook.yml (追加 commit-msg 配置)

1
2
3
4
5
6
7
8
9
10
# ... (上一节的 pre-commit 配置)

# 新增 commit-msg 钩子。它在 pre-commit 钩子全部通过后执行。
commit-msg:
commands:
commitlint:
# {1} 是 Lefthook 的一个特殊变量,它代表了 Git
# 用来存储本次提交信息的临时文件的路径 (例如 .git/COMMIT_EDITMSG)。
# 我们将这个路径传递给 commitlint,让它去读取和校验。
run: pnpm commitlint --edit {1}

工作流程解析:当 git commit 时,pre-commit 钩子首先检查代码质量。通过后,Git 将提交信息写入临时文件,此时 commit-msg 钩子被触发,Lefthook 指挥 commitlint 去校验该文件。如果校验失败,整个提交过程将被中止。

3.3.5. 演练与验证

现在,我们的“铁三角”已全部就位。

第一步:代码无误,但提交信息错误

确保代码可以通过 pre-commit 的检查,然后尝试使用一个不规范的提交信息。

1
2
git add .
git commit -m "update app"

第二步:观察 commit-msg 钩子拦截

pre-commit 钩子会静默通过,但 commit-msg 钩子将运行并 失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
│ 🥊 lefthook v1.13.6  hook: commit-msg │
╰───────────────────────────────────────╯
┃ commitlint ❯

⧗ input: update app
✖ subject may not be empty [subject-empty]
type may not be empty [type-empty]

✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint



────────────────────────────────────
summary: (done in 2.98 seconds)
🥊 commitlint (2.98 seconds)
PS C:\Users\Prorise\Desktop\React实战\prorise-admin>

结果:提交被 再次中止commitlint 明确地告诉我们,它没有找到符合规范的 typesubject

第三步:使用规范的提交信息
我们使用正确的格式重新提交。

1
git commit -m "chore: test commitlint workflow"

结果pre-commitcommit-msg 钩子均成功通过,提交完成!

3.3.6. 终极自动化:通过 prepare 脚本实现“零配置”协作

为了让新加入的团队成员能够无感地使用这套规范,我们利用 package.jsonprepare 脚本,实现 Git 钩子的自动安装。

文件路径: package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
// ... (name, version, etc.)
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "pnpm biome check src",
"lint:fix": "pnpm biome check --apply src",
"format": "pnpm biome format --write src",

// 新增 "prepare" 脚本
"prepare": "lefthook install"
},
// ... (dependencies)
}

preparepnpm/npm 的一个标准生命周期脚本,它会在 pnpm install 命令执行 完成之后 自动运行。这意味着,新成员在克隆项目后,只需运行一次 pnpm install,所有 Git 钩子就会被自动配置好,真正实现了“零手动配置”的团队协作体验。


3.4. 版本控制:初始化 Git 仓库并记录成果

至此,我们已经完成了项目工程化配置的“奠基”工作。这是一个完美的节点,我们应该将这个包含了所有规范和配置的“项目基石”状态,永久地记录下来。我们将通过初始化 Git 仓库并完成我们的第一次提交来实现这一点。

第一步:初始化本地仓库

如果你的项目根目录还不是一个 Git 仓库,请执行以下命令:

1
git init

这条命令会在项目根目录下创建一个 .git 目录,正式将我们的 Prorise-Admin 项目置于 Git 的版本控制之下。

第二步:暂存所有文件

我们将所有已创建和修改的文件添加到 Git 的暂存区,准备进行第一次提交。

1
git add .

第三步:完成首次规范化提交

这是检验我们本章成果的关键时刻!我们的首次提交 必须 遵循 3.3 节学习的“约定式提交”规范。

对于“初始化项目并集成工程化工具”这一行为,最合适的 typechore,因为它属于构建流程和辅助工具的变动。

1
git commit -m "chore: initialize project and integrate code quality toolchain"

当你按下回车键后,你将亲眼见证我们构建的自动化体系开始工作:

  1. Lefthook 启动:Git 的 pre-commit 钩子被触发。
  2. 代码质量检查format, lint, check-types 任务会并行运行,检查所有暂存文件。由于我们的代码是规范的,它们会顺利通过。
  3. 提交信息检查commit-msg 钩子被触发。
  4. Commitlint 校验commitlint 会校验我们的提交信息 "chore: initialize project..."。因为它完全符合规范,所以也会顺利通过。
  5. 提交成功:所有检查都通过后,提交最终完成。

现在,我们项目的坚实基础已经被安全地记录在了 Git 历史中。未来的每一章,我们都将在这个基础上,不断地增加新的、符合规范的提交。

3.5. 本章小结

在本章中,我们为 Prorise-Admin 项目锻造了一套坚不可摧的“代码质量铁三角”,将质量保障从“依赖个人自觉”的原始阶段,全面升级到了“自动化、强制性”的工程化阶段。

  1. 代码质量 (Biome.js):我们用高性能的 Biome 统一了代码格式化与 Lint 检查。
  2. 提交卡控 (Lefthook):我们通过 pre-commit 钩子,建立了代码入库前的“质量门禁”,自动执行格式化、Lint 检查和类型检查。
  3. 提交规范 (Commitlint):我们首先深入学习了 约定式提交 (Conventional Commits) 规范 的核心结构,然后通过 commit-msg 钩子集成了 Commitlint,强制执行该规范,确保了 Git 历史的清晰性、可读性和可维护性。
  4. 自动化工作流 (prepare 脚本):我们利用 prepare 脚本实现了 Git 钩子的自动安装,将所有规范固化到了项目的工作流之中,达成了“零手动配置”的团队协作目标。
  5. 版本化基石:最后,我们初始化了 Git 仓库,并使用刚刚建立的完整规范,完成了项目的首次提交,为后续开发奠定了安全、可追溯的版本化基石。

从现在开始,Prorise-Admin 已经具备了强大的 自我净化规范约束 能力,为后续大规模、高质量的功能开发铺平了道路。