【大厂企业级项目架构】之提交规范

本篇主要讲解如何落地git提交规范,实际上很多的团队也不会对提交做规范或限制,所以我单独拎出来一篇文章,如果你的团队没有硬性规定,你也可以直接跳过这一篇,感兴趣的可以往下看。

项目里面需不需要规范提交就看各自需要了,但是如果是规模大一点的团队,还是建议接入一下。规范提交肯定是有它的好处的,毕竟多人协作,可能有的人的提交描述就是随便写的,比如说就写了个bug fix,其他人一看根本就不知道干了啥,不利于后期的维护。好的提交描述可以让我们快速定位到相应的提交里面,也有利于我们通过工具生成变更日志。

选择规范

首先要确定我们用什么规范,是自己制定还是第三方的?这里我们选择开源社区最流行的Angular团队的提交规范。虽然自己制定也行,但是性价比不高,且很可能没有社区的通用和完善。所以我们选择社区的力量。

Angular提交规范

这里简单介绍一下Angular提交规范要遵循哪些内容。

要遵循的格式如下:

变更类型[变更范围(可选)]: 对这次变更的简要描述

对这次变更的详细描述(这个是可选的)

Footer(假如你这次变更是break change或者关闭缺陷,Footer就是必填的,否则Footer也可以省略)

先看一下如下例子:

#变更类型如下
#feat: 新增功能
#fix:  修复bug
#docs: 文档变更
#style: 代码格式(如空格、分号等修改)
#refactor: 代码重构
#perf: 性能优化
#test: 添加、修改测试用例
#build: 构建流程、外部依赖变更
#chore: 对构建过程或辅助工具
#revert: 回滚 commit库的更改

#括号里面的是变更范围,具体要看你修改了哪里,以这个例子为例,就是修改了Components目录下的xxx组件,所以变更范围就是Components
feat(Components): xxx组件新增xxx功能

xxx组件新增了如下特性:
- 特性一
- 特性二
- ...

这是一个大版本更新,老版本的组件不支持此功能

commitizen

从上面的例子可以看出,要写一个符合规范的提交信息,还是有一定的麻烦的,为了减少团队成员的负担,这个时候就可以借助commitizen这个工具来辅助我们生成提交信息。 commitizen给我们提供了一个交互式命令行工具,我们只需要按照提示填写好信息就可以了

安装

我们需要先全局安装commitizen

pnpm i -g commitizen 

安装完commitizen之后,我们还需要安装commitizen的适配器才能工作。

commitizen适配器

什么是适配器,commitizen认为每个项目的需求是不同的,不同项目可能希望遵循不同的提交规范,会需要定制不同的交互式命令的问题和选项。所以commitizen提供了不同的适配器来支持不同的需求,当然,你也可以自定义自己的适配器。

我简单介绍几个我们可能用得到的适配器:

  • cz-conventional-changelog 官方比较早期的适配器,支持自定义的配置比较少
  • cz-customizable 这是用的比较多的适配器,支持的自定义配置相对多一点,使用时需要增加.cz-config.js配置文件
  • cz-git 这个适配器可能相对用的没那么多,使用的时候无需增加.cz-config.js,如果是配合commitlint使用,则配置直接写在commitlint.config.js里就好。而且也支持在命令行模糊搜索,提交信息支持emoji表情等特性。

commitizen搭配cz-customizable

这里我们选择cz-customizable来讲解如何使用

首先是安装

pnpm i -D cz-customizable 

然后在package.json中增加如下配置

// package.json
{
    "config": {
        "commitizen": {
            // 这里指定cz-customizable为适配器
            "path": "node_modules/cz-customizable"
        }
    }
}

以上两步,你也可以通过如下命令完成,效果是一样的

npx commitizen init cz-customizable --save-dev

后面我们就可以写我们的自定义配置了,在根目录下新增.cz-config.js文件,内容如下:

module.exports = {
    // types就是我们上面说的格式里面的变更类型
    // 定义types之后,我们在命令行就可以通过上下键选择类型,而不是自己手输了
    // name里面的信息可以按自己的喜好来自定义
    types: [
        { value: 'feat', name: 'feat: 新增功能' },
        { value: 'fix', name: 'fix: 修复bug' },
        { value: 'docs', name: 'docs: 文档变更' },
        { value: 'style', name: 'style: 代码格式' },
        { value: 'refactor', name: 'refactor: 代码重构' },
        { value: 'perf', name: 'perf: 性能优化' },
        { value: 'test', name: 'test: 添加、修改测试用例' },
        { value: 'build', name: 'build: 构建流程、外部依赖变更' },
        { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
        { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改' },
        { value: 'revert', name: 'revert: 回滚 commit' },
    ],
    // scope对应的就是上面格式里的变更范围了
    // 定义了之后,你就可以在命令行通过上下键选择变更范围
    // 也可以不定义scopes,直接用customScope字段,然后自己填scope信息
    // 你甚至可以针对每一个type去定义相应的scope,通过scopeOverrides这个字段去配置即可
    scopes: [
        { value: 'components', name: '组件相关'},
        { value: 'service', name: '公共服务'},
        { value: 'constants', name: '常量'},
        { value: 'views', name: 'views'},
        // ...
        // 如果选择 custom,后面会让你再输入一个自定义的 scope。也可以不设置此项,把后面的 allowCustomScopes 设置为 true
        { value: 'custom', name: '以上都不是?我要自定义'},
    ],
    // 命令行提示信息
    // 就是说当你输入git cz命令来触发commit的时候,会先提示你选择类型,再提示你选择修改范围,如此类推
    messages: {
        type: '请选择提交类型:',
        scope: '请选择修改范围(可选):',
        // 选择 scope: custom 时会出下面的提示
        customScope: '请输入修改范围(可选):',
        subject: '请填写简要的变更描述(必填):',
        body: '填写详细的变更描述(可选):',
        footer: '请输入可以关闭的issue(可选):',
        confirmCommit: '确认提交?',
    },
    // 跳过要询问的步骤
    // 上面messages里面的步骤是可以跳过的,假如说有些步骤你不想填,且不想它每次都询问你,就在这里定义需要跳过的步骤
    skipQuestions: ['body', 'footer'],
    // 限制变更简要描述的长度
    subjectLimit: 100,
};

写完上面的配置之后,你就可以提交一下试一下效果了。需要注意的是,此时你不能用git commit来提交,而是要用git cz这个命令来提交,当你执行git cz之后,就会有如下命令行提示:

命令行效果

此时我们只需要跟着提示一步步填写信息,commitizen就可以帮我们生成出规范的提交信息。

commitlint

上面已经配置好了提交规范,但是你并不能保证每个人都会遵循这个规范,所以我们还需要通过git hooks + commitlint对提交作限制,只有符合规范的才能commit。

配置commitlint

使用commitlint需要先安装@commitlint/cli@commitlint/config-conventional这两个包。

  • @commitlint/cli – 类似于eslint的命令行工具
  • @commitlint/config-conventional – 类似于eslint的规则集,通过extends去继承这个规则集,就可以校验我们的commit信息了
pnpm i -D @commitlint/cli @commitlint/config-conventional

安装好之后,在根目录下新增commitlint.config.js如下:

module.exports = {
    // 继承@commitlint/config-conventional这个规则集
    extends: ['@commitlint/config-conventional'],
    rules: {
        // 关闭这条规则,你如果有其他想关闭的,自行关闭即可
        'subject-case': [0],
        // 变更类型的枚举,跟我们上面的types对应,不在这些枚举之内就报错
        'type-enum': [
            2,
            'always',
            [
                'feat',
                'fix',
                'perf',
                'style',
                'docs',
                'test',
                'refactor',
                'build',
                'ci',
                'chore',
                'revert',
                'types',
                'release',
            ],
        ],
    }
}

配置git hooks

上面commitlint配置好之后,我们还需要通过git hooks来触发git commit时对commit message的校验。

执行如下命令:

npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"

执行完之后,就会在.husky目录下增加commit-msg这个脚本,脚本里面的内容就是这个命令npx --no-install commitlint --edit $1

到此,就配置完了,这个时候就可以验证一下,你随便写提交信息是不会让你提交的。后面都建议用git cz命令来辅助我们生成符合规范的提交信息了

总结

其实接入提交规范,总结起来就是三步

  • 使用commitizen及其适配器去辅助生成符合规范的提交信息
  • 使用git cz命令来触发commitizen的交互式命令
  • 通过commitlint去校验提交信息,限制不合规范的提交
  • 通过git hooks去触发commitlintcommit message做校验