前端基建必备技能:代码提交规范

前端项目的提交规范前端基建必备技能之一。下面介绍规范提交代码时会用到的工具,以及在常见场景中如何去使用。

Husky

Git hooks 管理工具。

允许开发者在项目中设置自定义的 Git 钩子脚本。

自动检查您的提交消息、代码,并在提交或推送时运行测试。

安装

js 复制代码
npm install --save-dev husky

初始化

js 复制代码
npx husky init

初始化成功之后,会在项目根目录下创建.husky.husky/_文件夹,并创建钩子(git hooks)脚本,目录结构如下:

js 复制代码
├─ .husky
│  ├─ _
│  │  ├─ .gitignore
│  │  ├─ applypatch-msg
│  │  ├─ commit-msg
│  │  ├─ h
│  │  ├─ husky.sh
│  │  ├─ post-applypatch
│  │  ├─ post-checkout
│  │  ├─ post-commit
│  │  ├─ post-merge
│  │  ├─ post-rewrite
│  │  ├─ pre-applypatch
│  │  ├─ pre-auto-gc
│  │  ├─ pre-commit
│  │  ├─ pre-push
│  │  ├─ pre-rebase
│  │  └─ prepare-commit-msg
│  └─ pre-commit

Git Hooks

名称 说明 使用场景
applypatch-msg 当从一个应用补丁中创建一个新的提交时运行 通常用于验证补丁消息格式
pre-applypatch 在应用补丁到工作目录和索引前触发 可以用来阻止不满足条件的补丁被应用
post-applypatch 补丁成功应用后执行 可以用于清理、通知或进一步处理
pre-commit 执行 git commit 前触发 常用于运行代码风格检查(如 ESLint)、类型检查(如 TypeScript)或单元测试等,防止不符合规范的代码进入仓库。
prepare-commit-msg 在编辑提交消息文件之前运行 可以自动生成(如:Commitizen)或修改默认的提交消息
commit-msg 在提交消息写入磁盘之后,但提交实际发生之前执行 通常用于验证提交消息格式是否符合团队规范,可以结合工具如 Commitlint 来实现。
post-commit 提交操作完成后立即触发 可用于执行发送通知、更新本地构建版本号或其他后提交的任务
pre-rebase 在开始交互式 rebase 或自动 rebase 之前触发 可以用来禁止某些类型的 rebase 操作
post-checkout 切换分支或者检出某个提交后执行 用于进行与当前工作目录状态相关的切换后的操作
post-merge 合并操作完成后运行 可能用于重建项目依赖项、清理临时文件或触发自动化部署流程
pre-push 在将本地提交推送到远程仓库之前执行 通常用于执行更全面的测试套件,确保即将推送的代码质量
pre-receive / update 这两个钩子在远程仓库服务器上执行,而不是本地 pre-receive 在接收推送前一次性运行,可以拒绝整个推送;而 update 对每个要更新的引用分别运行,允许对各个分支进行单独控制

Commitlint

用于验证 Git 提交消息格式是否符合预定义规范的工具,结合 Husky 工具来设置 commit-msg 钩子。

安装

@commitlint/config-conventional 是一个预定义的配置包,与 @commitlint/cli 配合使用来验证 Git 提交消息格式是否符合 Conventional Commits 规范。

js 复制代码
npm install --save-dev @commitlint/cli @commitlint/config-conventional

配置

在根目录下创建commitlint.config.js,并配置:

js 复制代码
// commit-lint config
module.exports = {
    extends: ['@commitlint/config-conventional'],
    rules: {
      'type-enum': [
        2,
        'always',
        ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'types'],
      ],
    },
  };
  

常用配置Api

名称 说明 使用场景
extends 扩展默认规范 @commitlint/config-conventional
rules 校验规则 - 错误级别(severity level):0(禁用)、1(警告)、2(错误) - 规则应用情况(when):通常是 'always' 或 'never' - 规则值(value):根据具体规则而定,可以是字符串、数组或其他形式的数据结构
rules.type-enum 确保提交消息中的类型字段(type)在预定义的枚举列表中 { "type-enum": [2, "always", ["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test", "types"]]}
rules.subject-case 检查提交消息主题(subject)的大小写风格 {"subject-case": ["2", "always", "lower-case"]}
rules.scope-enum 限制提交消息中的作用域(scope)只能是预先定义的值之一 {"scope-enum": ["2", "always", ["core", "ui", "api"]]}
rules.subject-full-stop 控制提交消息的主题行末尾是否需要句号 {"subject-full-stop": ["2", "never"]}
rules.body-max-line-length 限制提交消息主体部分(body)每一行的最大字符数 {"body-max-line-length": ["1", "always", 72]}
rules.footer-leading-blank 强制提交消息的 footer 部分前面有一空行 {"footer-leading-blank": ["error", "always"]}

Conventional Commits

约定式提交规范是一种基于提交信息的轻量级约定。

它提供了一组简单规则来创建清晰的提交历史,这更有利于编写自动化工具。

提交说明的结构

arduino 复制代码
<type>[optional scope]: <description> // <类型>[可选 范围]: <描述>

[optional body] // [可选 正文]

[optional footer(s)] // [可选 脚注]

常用类型

type 说明
fix: 表示在代码库中修复了一个bug
feat: 表示在代码库中新增了一个功能
build: 用于修改项目构建系统,例如修改依赖库、外部接口或者升级 Node 版本等
chore: 用于对非业务性代码进行修改,例如修改构建流程或者工具配置等
ci: 用于修改持续集成流程
docs: 用于修改文档,例如修改 README 文件、API 文档等
style: 用于修改代码的样式,例如调整缩进、空格、空行等
refactor: 重构代码以提高内部质量,但不改变外部可见行为
perf: 用于优化性能,例如提升代码的性能、减少内存占用等
test: 用于修改测试用例,例如添加、删除、修改代码的测试用例等
revert: 回滚到以前的提交状态,通常用于撤销最近引入的问题或更改

常用提交结构示例

csharp 复制代码
// 包含了描述并且脚注中有破坏性变更的提交说明
feat: allow provided config object to extend other configs

BREAKING CHANGE: `extends` key in config file is now used for extending other config files

// 包含了 ! 字符以提醒注意破坏性变更的提交说明
feat!: send an email to the customer when a product is shipped

// 包含范围的提交说明
feat(lang): add polish language

Commitizen

Commitizen 是一个开源的命令行工具,旨在帮助前端(以及所有使用 Git 的项目)开发者遵循一种标准化的提交消息格式。这种规范化提交信息的方式对于维护项目的提交历史、自动化生成 CHANGELOG、以及配合持续集成流程等具有重要作用。

安装

js 复制代码
npm install -g commitizen

配置

js 复制代码
"scripts": {
    "commit": "cz"
}

执行

js 复制代码
git cz
// or
git commit

执行效果图,默认为英文交互

cz-conventional-changelog

cz-conventional-changelogCommitizen 的一个适配器(adapter),它专门为遵循 Conventional Commits 规范而设计。Conventional Commits 是一种社区广泛接受的提交消息格式规范,用于增强提交历史的可读性和自动化生成 CHANGELOG 文件。

配置

json 复制代码
// package.json 
{ 
    "config": { 
        "config": {
            "commitizen": {
                "path": "./node_modules/cz-conventional-changelog",
                "disableScopeLowerCase": false,
                "disableSubjectLowerCase": false,
                "maxHeaderWidth": 100,
                "maxLineWidth": 100,
                "defaultType": "",
                "defaultScope": "",
                "defaultSubject": "",
                "defaultBody": "",
                "defaultIssues": "",
                "types": {
                    ...
                    "feat": {
                        "description": "A new feature",
                        "title": "Features"
                    },
                    ...
                }
            }
        }
    }
}

配置项

说明
path 指定 cz-conventional-changelog 适配器的路径
config 更具体的自定义配置对象
config.disableScopeLowerCase 是否禁用将 scope 自动转为小写的功能,默认情况下是转换为小写。设置为 true 可以保持用户输入的 Scope 原始大小写格式。
config.disableSubjectLowerCase 类似于 disableScopeLowerCase,决定是否禁用提交主题(subject)字段自动转为小写。若设为 true,提交的主题行首字母可以大写或根据原始输入保持大小写状态。
config.maxHeaderWidth 提交信息中所有行的最大长度,包括主体(body)和 footer 部分。超过此宽度的内容同样会被按照指定的字符数进行折行。
config.defaultType 当用户在交互式提交过程中没有明确选择 commit 类型时,使用的默认类型值,如 "feat" 或 "fix" 等。
config.defaultScope 默认的作用域值,如果在提交时未指定作用域,则使用此默认值。
config.defaultSubject 提供一个默认的提交主题,通常只有在特殊情况下才会用到,比如脚本自动生成提交时。
config.defaultBody 默认的提交主体内容,可以用来填充提交信息的详细描述部分,但大多数情况下开发者需要手动填写这部分内容以确保其准确性。
config.defaultIssues 在提交消息中自动包含特定的 issue 关联前缀(如:Closes #123)。
config.types 定义项目所支持的 commit 类型及其描述。这对于提示用户选择合适的类型非常有用。

类型中英文提示示例

名称 英文提示说明 中文提示说明
feat Introduces a new feature or enhances an existing one 添加新的功能或改进现有功能
fix Fixes a bug or resolves a defect in the codebase 修复一个错误或者缺陷
docs Changes only documentation content without altering code logic or functionality 只修改了文档内容,不影响代码逻辑或功能
style Changes that do not affect the program's behavior, such as formatting, white-space changes, or indentation 代码格式、空白字符、缩进等不改变程序行为的变动
refactor Code restructuring without adding features or fixing bugs, but possibly improving internal structure 代码重构,不新增功能也不修复错误,但可能改进内部结构
perf Improves performance, e.g., optimizing algorithms, reducing memory usage, etc. 提升性能的改动,比如优化算法、减少内存占用等
test Adds missing tests or modifies existing tests for better coverage or other quality metrics 添加缺失的测试用例,或者修改现有测试以提高覆盖率或其他质量指标
build Changes related to the build system or external dependencies (like npm packages, compilers, etc.) 与项目构建系统或外部依赖(如 npm 软件包、编译器等)相关的更改
ci Changes to CI configuration files and scripts 对 CI 配置文件和脚本的更改
chore Maintenance tasks that don't modify source code or tests 不修改源码或测试的其他维护性任务
revert Reverts a previous commit 撤销以前的提交

配置后的执行效果图

最佳实践

使用场景

  • 代码提交

预期目标

  • 提交时进行提交规范校验,校验信息包括:
    • 类型:必填、类型在预设的配置中
    • 描述:必填
  • 提交时进行代码检测
    • 代码语法:检查语法是否正确,如果不正确抛出错误
    • 代码格式:自动格式化代码格式,使代码格式保持统一
  • 通过辅助工具帮助开发同学规范提交信息
    • 配置 Commitizen

分析

如果要实现上述的预期目标,肯定是要在代码提交前执行。所以要用到Git Hooks中的钩子。pre-commit常用于运行代码风格检查、commit-msg常用于验证提交消息格式是否符合团队规范。

配置pre-commit脚本

bash 复制代码
// .husky > pre-commit

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

if [[ "$OS" == "Windows_NT" ]]; then
  npx.cmd lint-staged
else
  npx lint-staged
fi
json 复制代码
// package.json
{
    "lint-staged": {
        "*.{js,jsx,vue,ts,tsx,html,vue,css,sass,less}": "eslint --fix"
    }
}

配置commit-msg脚本

bash 复制代码
// .husky > commit-msg

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

if [[ "$OS" == "Windows_NT" ]]; then
  npx.cmd --no-install commitlint -e $GIT_PARAMS
else
  npx --no-install commitlint -e $GIT_PARAMS
fi

脚本相关语法不再过多描述,主要是看if中执行的命令。

优势与不足

优势

  • 使项目规范化,代码风格保持统一
  • 易于后期的代码维护
  • 减少新人加入项目后的代码上手难度

不足

在使用Commitizen辅助提交时,要使用命令行的方式,source treegithub desktop 的可视化工具就不太好用了。除此之外,source treegithub desktop校验失败时都会抛出错误,不使用Commitizen时,使用两者工具是没有问题的。

技术清单

名称 版本 说明
node v18.16.0 -
husky ^9.0.7 -
commitlint ^18.6.0 -
@commitlint/cli ^18.6.0 -
@commitlint/config-conventional ^18.6.0 -
commitizen ^4.3.0 -
cz-conventional-changelog ^3.3.0 -
eslint ^8.56.0 进行代码校验,本文未展开介绍
lint-staged ^15.2.0 进行代码校验,本文未展开介绍
相关推荐
呆呆小雅2 分钟前
四、Vue 条件语句
前端·javascript·vue.js
LUwantAC13 分钟前
一篇文章学会HTML
前端·javascript·html
小林爱16 分钟前
【Compose multiplatform教程12】【组件】Box组件
前端·kotlin·android studio·框架·compose·多平台
风清云淡_A38 分钟前
【再学javascript算法之美】前端面试频率比较高的基础算法题
前端·javascript
xcLeigh41 分钟前
HTML5实现喜庆的新年快乐网页源码
前端·html·html5
DT——1 小时前
HTTPS验证流程
前端·https
Tirzano1 小时前
vue3 ts 动态表单原理
前端·javascript·vue.js
m0_748240251 小时前
vue3 前端实现pdf打印预览 printjs
前端·pdf·状态模式
晚时之秋2 小时前
vue3配置测试环境、开发环境、生产环境
前端·vue
火龙kess2 小时前
HTML制作一个普通的背景换肤案例2024版
开发语言·前端·javascript·html