🚀有手就行,用commitlint+husky约束git的commit提交

1,083 阅读6分钟

这篇文章讲的是,在前端开发中,如何使用commitlint,husky来实现对git中commit信息的校验。这个在多人开发中是很有用的,规范团队中每个人提交信息的格式,方便管理

格式说明

在学习工具之前,了解工具用来解决什么问题很重要

在git中,commit message一般有三个部分:Header, Body, Footer

填写格式如下

<type>(<scope>): subject
//空行
<body>
//空行
<footer>

上面的圆括号、冒号、空行都是必须的,帮助第三方工具识别我们的message

  1. Header有三个部分:Type, scope, subject
  • Type表示代码提交的类型,大概有这么几种:
feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动
  • scope表示修改涉及到的范围

  • subject表示修改内容的简要概括

  1. Body(可选):通常是表示修改内容的详细说明
  2. Footer(可选):通常是些备注

一般在commit中直接填写的内容就是Header的部分,包括修改的类型,修改涉及到的模块,以及修改内容的简要概括

用commitlint + husky来约束commit的格式

当我们知道了commit message的一般格式,也就知道了,一个好的完整的message是什么样子,我们可以要求团队成员提交的commit message完全符合上述格式,也可以仅符合上述的部分格式,据情况而定。

而如何约束,就需要用到第三方的工具了。

安装

// 安装commitlint
npm install @commitlint/config-conventional @commitlint/cli -D

//安装husky
npm install huksy -D

commitlint是一个用来检查commit message格式是否符合要求的第三方工具,而 husky我们这里仅用来在我们提交commit的时候,commitlint可以自动进行检查

分工明确。

husky也可以勾住git中其他的hook,比如pre-commit,通常用于在提交commit之前,eslint对代码进行格式化

配置commitlint

  1. 在项目根目录下面新建一个配置文件:commitlint.config.js。也可以运行下面的代码来完成
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

如果不明白上面的代码,我们也完全可以手动创建配置文件

上面代码的好处就是在新建文件中,就自动加了module.exports = { extends: ['@commitlint/config-conventional'] };这样一句话

现在我们看到的配置文件是这样的:

我们再加上一句话:

详细的配置会在后文介绍。新加代码的作用是规范提交的type只能为fix和doc两种

好了,我们可以测试一下commitlint的约束功能了

echo 'foo: change' | npx commitlint

你大概会得到下面的报错:

problem的意思是,type必须是fix或者doc的其中一种

再换个测试语句:

echo 'fix: change' | npx commitlint

没有任何的输出信息,测试通过。

commitlint大概就是这样的运行逻辑,但有一个缺点,是我们需要输入像上面一样的命令,commitlint才会去检查。而当我们真正提交commit代码的时候,commitlint不会有任何反应的。要达到自动测试的目的,我们需要husky

配置husky

husky的作用就是给commit的动作加上一个hook,当commit动作触发的时候,执行commitlint检查

// 生成.husky文件夹
npx husky install

第一步完成之后,你会在项目根目录看见新生成的.husky文件夹;

.husky文件夹下面创建commit-msg文件(不要任何的后缀),并且附上下面的内容,保存

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

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

文件名就表示勾住git中的哪个hook(commit-msg)

OK,husky已经准备好了,让我们测试一下

git commit -m 'foo: change' 

你应该会看到和上面一样的报错,husky生效了😁

除此之外,husky还可以增加其他的hook

npx husky add .husky/pre-commit "npm test"

pre-commit,这个hook的效果是,在commit之前,跑一遍测试

commitlint配置文件

在配置文件加上自定义的约束,主要是在rule里面填写。格式大致按照 rule name : [0, 'never', value]填写

  1. rule name是规则的名字,上面的 type-enum 就是一个规则的名字
  2. 规则的描述主要是数组的形式,

其他的形式可以查看官方文档

  • 数组的第一项,可以填0、1、2,表示规则的等级。0表示不使用该规则,1表示一个warning,2表示一个error

  • 第二项可以填always 、never, 表示规则的反转

  • 第三项表示规则的具体值

下面来看具体示例

type-enum: type的枚举值

feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动

用法:

"type-enum": [2, 'always', ['fix', 'doc',]],

type-case: type的格式要求: 大小写之类的

文字格式的要求可填下面这些值:

[
  'lower-case', // default
  'upper-case', // UPPERCASE
  'camel-case', // camelCase
  'kebab-case', // kebab-case
  'pascal-case', // PascalCase
  'sentence-case', // Sentence case
  'snake-case', // snake_case
  'start-case' // Start Case
]

用法:

"type-case": [2, 'always', 'upper-case']

注: 如果同时用上了type-enum, type-case,commitlint会同时检测

rules: {
    "type-enum": [2, 'always', ['FIX', 'doc',]],
    "type-case": [2, 'always', 'upper-case']
}

上面的规则表示:type只能填FIX和doc两种,并且type的值要求全大写。

如果我们提交用doc作为type是不行的,虽然满足了type-enum,但不满足type-case。那换成DOC呢,嗯~~也是不行的,因为不满足type-enum。也就是说type-enum, type-case要大小写一致。

这是我们需要注意的地方

git commit -m 'doc: ...' // commit failed
git commit -m 'DOC: ...' // commit failed
git commit -m 'FIX: ...' // commit success
git commit -m 'fix: ...' // commit failed

type-empty: type是否可以为空

// type 不能为空
'type-empty': [2, 'never']
// type 可以为空
'type-empty': [2, 'always']

除了type,还可以对scope、subject、header、body、footer等进行约束,下面是他们的规则名称

// scope
scope-enum : scope的枚举值
scope-case: scope的格式
scope-empty: scope是否为空
scope-max-length
scope-min-length

//subject
subject-case
subject-empty
subject-full-stop
subject-min-length
subject-max-length

// header
header-case

//body 
body-leading-blank: body以空白行开始
body-empty: body是否为空
body-full-stop: body是否以句号结尾

还有一些特别的:

signed-off-by: 表示在commit message最后加上提交作者的名字

"signed-off-by": [2, 'always', 'Signed-off-by']

下面是符合signed-off-by规范的提交。需要放在footer的后面

FIX: test

Signed-off-by: zenos

更详细的rule可以去官网:commitlint

总结

  1. commit message的格式说明
  2. 用commit和husky来约束message的格式
  3. 简要地说明了commitlint的配置信息

参考文档: