git commit 工具链
Lin. 切图仔

前言

如果你待过 大厂 或者看过一些 社区规范,会发现前端在 commit 时有对应的规范。

规范 一方面方便管理项目,一方面能让评审人员或者自己在看对应 commit 时,能快速定位到做的事情。

像一些社区的cli内置了 Eslint ,例如Vue cli、Vite、create react app等,可以根据你的需求选配。但是这里,我们自己来搭配 Eslint 。

代码规范

Eslint

用过的同学对它都不陌生,Eslint可以在你开发期间检测的你代码的是否按照规范写,如果不是,就会有报错提醒。

安装

1
npm i eslint -D

生成配置文件

1
npx eslint --init

eslint 检测风格

  • To check syntax only - 只检查语法

  • To check syntax and find problems - 检查语法和查找错误

  • To check syntax, find problems, and enforce code style - 检查语法,查找错误并加强代码风格

项目使用的模块规范

项目使用的框架

是否使用 TypeScript

代码运行环境

配置文件类型

是否用 npm 安装规范

选择你的 npm 镜像容器

选配完成后,会在根目录会自动生成 .eslintrc.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module.exports = {
env: {
browser: true,
node: true,
es2021: true,
},
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:@typescript-eslint/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["react", "@typescript-eslint"],
// 配置规则
rules: {},
};

Vscode eslint 自动格式化

我们可以在保存代码的时候,自动做 eslint 格式化

旧版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
//配置eslint
"eslint.autoFixOnSave": true, // 启用保存时自动修复,默认只支持.js文件
"eslint.validate": [
"javascript", // 用eslint的规则检测js文件
{
"language": "vue", // 检测vue文件
"autoFix": true // 为vue文件开启保存自动修复的功能
},
{
"language": "html",
"autoFix": true
}
]
}

新版(>1.41.0)配置

1
2
3
4
5
6
7
8
9
{
//autoFixedOnSave 设置已废弃,采用如下新的设置
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.format.enable": true,
//autoFix默认开启,只需输入字符串数组即可
"eslint.validate": ["javascript", "vue", "html"]
}

prettier

使用 prettier 插件, 通过配置 prettier 的配置文件,统一项目的格式化风格

安装

没有 eslint

1
npm i prettier -D

有 eslint

1
npm i prettier eslint-config-prettier eslint-plugin-prettier -D

测试是否安装成功

1
prettier - v;

文件格式

自定义文件的格式可以有多种

  • prettierrc 文件,支持 yaml 和 json 格式;或者加上扩展名也可以,可选的扩展名有 .yaml/.yml/.json

  • prettierrc.toml 文件

  • prettier.config.js or .prettierrc.js 返回一个对象

  • package.json 文件中加上 prettier 对象

json 配置文件写法

1
2
3
4
{
"semi": false,
"singleQuote": true
}

toml 文件写法

1
2
3
#  .prettierrc.toml
semi = false
singleQuote = true

yaml 文件写法

1
2
3
# .prettierrc
semi: false
singleQuote: true

js 写法

1
2
3
4
5
// prettier.config.js or .prettierrc.js 返回对象
module.exports = {
semi: false,
singleQuote: true,
};

配置文件

在根目录创建 .prettierrc, 配置格式化

1
2
3
4
5
6
7
8
// .prettierrc
{
"semi": false,
"tabWidth": 2,
"trailingComma": "none",
"singleQuote": true,
"arrowParens": "avoid"
}

prettier 配置大全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 常用配置相关解释
printWidth: 100, // 超过最大值换行
tabWidth: 4, // 缩进字节数
useTabs: false, // 缩进不使用tab,使用空格
semi: true, // 句尾添加分号
singleQuote: true, // 使用单引号代替双引号
proseWrap: "preserve", // 默认值。因为使用了一些折行敏感型的渲染器(如GitHub comment)而按照markdown文本样式进行折行
arrowParens: "avoid", // (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid:省略括号
bracketSpacing: true, // 在对象,数组括号与文字之间加空格 "{ foo: bar }"
disableLanguages: ["vue"], // 不格式化vue文件,vue文件的格式化单独设置
endOfLine: "auto", // 结尾是 \n \r \n\r auto
eslintIntegration: false, //不让prettier使用eslint的代码格式进行校验
htmlWhitespaceSensitivity: "ignore",
ignorePath: ".prettierignore", // 不使用prettier格式化的文件填写在项目的.prettierignore文件中
jsxBracketSameLine: false, // 在jsx中把'>' 是否单独放一行
jsxSingleQuote: false, // 在jsx中使用单引号代替双引号
parser: "babylon", // 格式化的解析器,默认是babylon
requireConfig: false, // Require a 'prettierconfig' to format prettier
stylelintIntegration: false, //不让prettier使用stylelint的代码格式进行校验
trailingComma: "es5", // 在对象或数组最后一个元素后面是否加逗号(在ES5中加尾逗号)
tslintIntegration: false // 不让prettier使用tslint的代码格式进行校验

有时候,某些文件/文件夹的文件并不需要格式化,我们可以通过配置 .prettierignore 来忽略不需要格式化的文件,常见配置如下:

1
2
3
4
5
6
7
8
9
// .prettierignore

/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*

运行 prettier

命令

1
2
3
4
npx prettier --write <文件路劲+文件名>

//例如,格式化当前路劲下的aaa.js文件
npx prettier --write ./aaa.js

格式化全部

1
npx prettier --write  .

格式化某个文件

1
npx prettier --write  ./文件夹路径/文件名

格式化某个文件夹

1
npx prettier --write  ./文件夹路径

VsCode 插件

git 规范

社区规范

社区认可的 commit 规范

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
feat: 新增 feature

fix: 修复 bug

docs: 仅仅修改了文档,比如 README, CHANGELOG, CONTRIBUTE等等

style: 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑

refactor: 代码重构,没有加新功能或者修复 bug

perf: 优化相关,比如提升性能、体验

test: 测试用例,包括单元测试、集成测试等

chore: 改变构建流程、或者增加依赖库、工具等

revert: 回滚到上一个版本

build: 更新包的内容

release: release版本更新

书写格式如下:

1
type(scope): <subject>

例子:

1
2
revert: feat(form): add 'validate' option
最简写法:feat: add 'validate' option

但是每次手动 commit 都要写上对应的 type ,挺麻烦的?我们也可以用对应的插件来帮我们做类似的事,往下看。

git hooks

git Hooks它是一些自定义的脚本,用于控制 git 工作的流程,分为客户端钩子和服务端钩子,这里我们主要介绍客户端钩子

客户端钩子分为很多种。 下面把它们分为:提交工作流钩子、电子邮件工作流钩子和其它钩子。主要介绍提交工作流钩子:pre-commit、prepare-commit-msg、commit-msg、post-commit。

  • pre-commit(常用)

在键入提交信息前运行。 它用于检查即将提交的快照。例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 git commit --no-verify 来绕过这个环节。 你可以利用该钩子,来检查代码风格是否一致(运行类似 lint 的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。

  • prepare-commit-msg

在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。 该钩子接收一些选项:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验。 它对一般的提交来说并没有什么用;然而对那些会自动产生默认信息的提交,如提交信息模板、合并提交、压缩提交和修订提交等非常实用。 你可以结合提交模板来使用它,动态地插入信息。

  • commit-msg(常用)

接收一个参数,此参数即上文提到的,存有当前提交信息的临时文件的路径。 如果该钩子脚本以非零值退出,Git 将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息

  • post-commit

在整个提交过程完成后运行。 它不接收任何参数,但你可以很容易地通过运行 git log -1 HEAD 来获得最后一次的提交信息。 该钩子一般用于通知之类的事情

git hooks 安装

当你用git init初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本,进入.git/hooks后会看到一些hooks的官方示例,他们都是以.sample结尾的文件名。

git hooks 存储位置

git hooks被存储在Git目录下的.hooks子目录中,即绝大部分项目中的.git/hooks

调用 git hooks

注意这些以.sample结尾的示例脚本默认是不会执行的,只有把一个正确命名(不带扩展名.sample)且可执行的文件放入 .git/hooks 目录中,才会激活该钩子脚本,生效且被git调用。像我们平常用的 git push、git commit 等命名都是用到了 hooks

本地.git/hooks 的缺陷

【不能共享】由于.git文件夹是不会被 git 跟踪的,所以.git/hooks目录下的 hooks 钩子无法提交,就不能和他人共享钩子脚本。

git 工具链

前面我们已经了解 社区规范 和 git hooks ,那我们可以利用一些 git 工具 来帮我们统一 git commit 规范。

  • husky
    • 操作 git 钩子的工具
  • lint-staged
    • 本地暂存代码检查工具
  • commitlint
    • commit 信息校验工具
  • commitizen
    • 辅助 commit 信息 ,就像这样,通过选择输入,规范提交信息

husky

安装 husky

1
npm install husky --save-dev

在 package.json 中添加脚本,自动启用 Git 钩子

1
npm set-script prepare "husky install" // 会在 package.json 中的 scripts 里新增一个 prepare 命令

启用 husky

1
2
3
npm run prepare
// 或
npx husky install

执行完上述命令,会发生几个变化:

  1. .git同级目录生成.husky文件夹

  2. package.json中的scripts中添加了"prepare": "husky install"

  3. 更改git配置项core.hooksPath.husky

配置完 husky 后,我们可以去配置 对应的一些 hook

配置 husky 的方式,默认使用的配置是 .husky文件夹里对应的 hooks

    1. 更改 hooks 脚本
1
2
3
4
5
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

// 脚本执行了 lint-staged 插件检测
npm run lint-staged
    1. 修改 package.json
1
2
3
4
5
6
7
8
9
10
11
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,vue}": [
"eslint --fix",
"git add ."
]
},

pre-commit

配置前置钩子,这里我们用 lint-staged 来做前置校验

添加 pre-commit 钩子

1
npx husky add .husky/pre-commit "npx lint-staged"

输完命令后,会在 .husky 下新增一个 pre-commit 文件,里面执行了 npx lint-staged 命令

配置 lint-staged,有两种配置方法

  • .lintstagedrc.json

在根目录下新建 .lintstagedrc.json,运行 npx lint-staged 会读取这个文件里边的配置,配置如下

1
2
3
4
5
// 这里是全局匹配了,可以指定对应文件夹,例如 src/**/*.{ts,vue}
{
"*.{js,jsx,ts,tsx}": ["prettier --write .", "eslint --fix"],
"*.md": ["prettier --write"]
}

这个配置做了什么? 匹配 git add 暂存区里对应后缀名的文件,然后执行 prettier 格式化,eslint 检测

  • package.json
1
2
3
4
5
6
7
8
9
10
11
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": ["prettier --write .", "eslint --fix"],
"*.md": ["prettier --write"]
}
}

commit-msg

添加 commit-msg,这里用的是 commitlint,添加钩子使用 husky add 命令

1
2
// 添加 commitlint hook
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

配置 commitlint 提交规范,新增 commitlint.config.js

1
2
// commitlint.config.js
module.exports = { extends: ["@commitlint/config-conventional"] };

做的事情,跟上边差不多。 commitlint 会校测你提交的 commit message 是否符合规范,默认是**Angular**的提交规范

类型描述
build编译相关的修改,例如发布版本、对项目构建或者依赖的改动
chore其他修改, 比如改变构建流程、或者增加依赖库、工具等
ci持续集成修改
docs文档修改
feat新特性、新功能
fix修改 bug
perf优化相关,比如提升性能、体验
refactor代码重构
revert回滚到上一个版本
style代码格式修改, 注意不是 css 修改
test测试用例修改

也可以自己写校验方法,来检验校验内容,例如我写的校验在 verifyCommit.js,那添加的时候设置一下就行,代码如下

1
npx husky add .husky/commit-msg 'node [dir]/verifyCommit.js' # 指定目录文件

或者改 package.json 的配置

1
2
3
4
5
6
7
{
"husky": {
"hooks": {
"commit-msg": "node [dir]/verifyCommit.js"
}
}
}

commitlint-config-cz

通过 commitlint-config-cz 可以定义commitlint 的提交规范

安装

1
npm i -D commitlint-config-cz  cz-customizable

修改 commitlint.config.js 提交规范,改为 cz

1
2
// 采用 cz 自定义的提交规范, > .cz-config.js
module.exports = { extends: ["cz"] };

增加 .cz-config.js

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
"use strict";
module.exports = {
types: [
{ value: "✨feat", name: "新增: 新的内容" },
{ value: "🐛fix", name: "修复: 修复一个Bug" },
{ value: "📝docs", name: "文档: 变更的只有文档" },
{ value: "💄style", name: "格式: 空格, 分号等格式修复" },
{ value: "♻️refactor", name: "重构: 代码重构,注意和特性、修复区分开" },
{ value: "⚡️perf", name: "性能: 提升性能" },
{ value: "✅test", name: "测试: 添加一个测试" },
{ value: "🔧chore", name: "工具: 开发工具变动(构建、脚手架工具等)" },
{ value: "⏪revert", name: "回滚: 代码回退" },
{ value: "🏆build", name: "打包: 更新包内容" },
{ value: "🌀release", name: "更新: 版本更新" }
],
scopes: [
{ name: "leetcode" },
{ name: "javascript" },
{ name: "typescript" },
{ name: "Vue" },
{ name: "node" }
],
// it needs to match the value for field type. Eg.: 'fix'
/* scopeOverrides: {
fix: [
{name: 'merge'},
{name: 'style'},
{name: 'e2eTest'},
{name: 'unitTest'}
]
}, */
// override the messages, defaults are as follows
messages: {
type: "选择一种你的提交类型:",
scope: "选择一个scope (可选):",
// used if allowCustomScopes is true
customScope: "Denote the SCOPE of this change:",
subject: "短说明:\n",
body: '长说明,使用"|"换行(可选):\n',
breaking: "非兼容性说明 (可选):\n",
footer: "关联关闭的issue,例如:#31, #34(可选):\n",
confirmCommit: "确定提交说明?(yes/no)"
},
allowCustomScopes: true,
allowBreakingChanges: ["特性", "修复"],
// limit subject length
subjectLimit: 100
};

在 package.json 中, 新增 config 配置,修改 commitizen 使用的容器

1
2
3
4
5
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
},

新增命令 commit 命令

1
2
3
4
// package.json
"scripts": {
"commit": "git-cz"
},

执行命令, npm run commit

  • 本文标题:git commit 工具链
  • 本文作者:Lin.
  • 创建时间:2022-05-18 20:43:02
  • 本文链接:http://www.linzefan.top/hexo-blogs2022/05/18/git commit 工具链/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论