介绍
本文主要介绍学习在项目开发时,保持团队中的编码规范以及提交信息的规范,便于团队对代码的管理可追溯可管理的过程。主要分为编辑器的配置以及eslit规范和husky的集成,和后续在服务器进行验证的过程。
编辑器配置
不同的编辑器有不同的默认行为,同一款编辑器在不同的操作系统上也会有不同的表现。不同的开发者也会有自己的喜好。
如:
- 有的人习惯
Tab键缩进,有的人习惯使用4个空格。 - 缩进间距有的人习惯使用 2个空格,有的人习惯使用 4个空格。
- window系统中的换行符是
\r\n, Linux 系统中的换行符是\n。 - ....
.editorconfig消除编辑器之间的差异
推荐使用 EditorConfig。EditorConfig 可以在不同平台的不同编辑器之间维护一致的公共配置。
使用EditorConfig 需要在项目中提供.editorconfig文件。
在根目录下和子目录下可以同时存在.editorconfig文件,子目录的优先级更高。
而位于根目录的.editorconfig文件需要将root配置设置为 true(最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件)。
用于通配符匹配的节名中识别的特殊字符:
| 特殊字符 | 含义 | 示例 |
|---|---|---|
| * | 匹配任何字符串,除了路径分隔符(/) | *.html [*.js] |
| ** | 匹配任何字符串 | /** |
| ? | 匹配任何单个字符 | - |
| [name] | 匹配名称中的任何单个字符 | [pageage.json] 对该文件指定规则 |
| [!name] | 匹配任何不是名字的单个字符 | - |
| {s1,s2,s3} | 匹配给定的任何字符串(由逗号分隔)(自EditorConfig Core 0.11.0起可用) | {*.{js,html}} |
| {num1..num2} | 匹配num1和num2之间的任何整数,其中num1和num2可以为正或负 | - |
编辑器支持情况:
WebStorm默认支持 EditorConfig; VS Code 和 Sublime 要配置 EditorConfig 插件;例如:VS Code 需要配置 EditorConfig for VS Code

配置示例:
# EditorConfig is awesome: https://editorconfig.org
# top-most EditorCOnfig file
# 根目录的配置
root = true # 根目录的配置文件,编辑器会由当前目录向上查找,如果找到 `roor = true` 的文件,则不再查找
[*] # 匹配所有文件
indent_style = space # 空格缩进 缩进类型(tab是硬缩进,space为软缩进)
indent_size = 4 # 缩进空格为 4个
end_of_line = lf # 文件换行符是 linux 的 `\n`
charset = utf-8 # 文件编码是 utf-8
trim_trailing_whitespace = true # 不保留行末的空格
insert_final_newline = true # 文件末尾添加一个空行
curly_bracket_next_line = false # 大括号不另起一行
spaces_around_operators = true # 运算符两遍都有空格
indent_brace_style = 1tbs # 条件语句格式是 1tbs
spaces_around_brackets # 表示括号和括号之间应有空格:无空格,仅在括号内,仅在括号外或在括号的两侧 (none,inside,outside,both)
max_line_length # 在指定的字符数后强制换行。off关闭此功能
[*.js] # 对所有的 js 文件生效
quote_type = single # 字符串使用单引号
[*.{html,less,css,json}] # 对所有 html, less, css, json 文件生效
quote_type = double # 字符串使用双引号
[pageage.json] # 对 package.json生效
优点:
- 广泛性:对
vs code, webstorm, atom, ide, visualstudio ...等都支持; - 配置简单;
- 统一:规范常用的,基本的代码要求;
局限:
- 不够灵活;不能配置
trim_trailing_semicolon等; - 和其他格式化工具,例如: eslint, prettier 等配置容易冲突;
editorconfig 只能解决少数基本风格问题,实际在项目用很少使用这种方式;
代码风格格式化
使用Prettier
Prettier是什么?
- 一个
"有态度","有主见"的代码格式化工具;(这就意味着代码风格是设置好的) - 支持大量编程语言;
- 已集成到大多数编辑器中;
- 几乎不需要设置参数;
为什么使用Prettier?
- 按保存键,代码就被格式化了;
- 代码评审时无须争论代码样式;
- 节省时间和精力;
Prettier是一个代码格式化插件,它并不关心你的语法是否正确,只关心你的代码格式,比如是否使用单引号,语句结尾是否使用分号等。但是部分规则和ESLint有冲突?
前置工作
创建干净的demo工程(以vue create xxx)为例:选择不安装任何的 ()linter / formatter;后面我们自己手动安装prettier。
在项目工程中安装 prettier
npm install --save-dev --save-exact prettier || yarn add --dev --exact prettier
使用prettier格式化项目工程中所有文件。
npx prettier --write . || yarn prettier --write .
VS Code 编辑器
Prettier 几乎不需要配置,是开箱即用的,也不鼓励自定义样式,但是还是提供了少量的配置项可以更改。
如需配置则需要在 根目录下创建 .prettierrc.json;
创建 .prettierrc.json 可以制定规则,同时也告诉其他工具我们使用的是prettier;
创建 .prettierignore 让编辑器和CLI知道哪些文件不需要被格式化;
# .prettierignore
# Ignore artifacts:
build
coverage

使用 npx prettier --write . 或 yarn prettier --write . 格式化工程内的文件;

这样每写完一些代码都要去运行命令格式化代码,很麻烦,有没有在保存时自动格式化代码呢?
VS Code 集成 Prettier
使用 vs code 编辑器,有没有办法在写代码时,保存后自动按照 prettier的规则格式化?
ctrl + s保存时自动格式化代码:
- vscode中配置并启用了
Prettier - Code formatter扩展 文件 -- 首选 -- 设置 -- 工作区 -- 格式化 -- 勾选 Format On Save中勾选开启,此时在项目的根目录会生成.vscode/settings.json文件;- 在 .vscode/settings.json中配置:
"editor.defaultFormatter","editor.formatOnPaste", "esbenp.prettier-vscode"

{
"editor.formatOnSave": true, // 在保存时格式化文件
"editor.formatOnPaste": true, // 控制编辑器是否自动格式化粘贴的内容。
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
配置结束后,保存时会自动格式化代码

虽然编辑器自动格式化可以提升编程体验,但是不能保证代码风格一致,存在编辑器可能不支持Prettier的情况,如果用户使用的编辑器和设置的不一样等,除了可以和编辑器集成,Prettier还可以和Git集成,在使用 Git 提交时,可以将提交文件自动格式化。
Webstorm 中 Prettier 配置
使用webstorm为编辑器,如何在开发时保存代码自动格式化? git提交代码时自动格式化呢?在保存时根据prettier自动格式化代码
第1步:下载 Prettier 插件

第2步:配置Prettier

此时在编写代码保存时就能自动格式化;如果需要自定义配置项,需要在项目根目录.prettierrc.json中配置;其余 Git Hooks 配置和上述 pretty-quick方式;
Prettier方式的Git Hooks
npm: pretty-quick,也可以使用 npm 介绍的方式安装。
原理:
其原理是Git自身提供的hook功能。每次在提交之前,Git都会检查是否存在 pre-commit hook,如果存在,则会自动执行其中的命令。在 pre-commit hook 中加入格式化的命令,就可以实现提交时自动格式化。
但是现在存在以下两个问题:
- 问题一:
直接运行npx prettier --write .命令会将这个工程项目格式化。比较好的做法是只格式化本次提交的文件,pretty-quick工具可以实现选择性格式化,其有很多参数,--staged可以实现只格式化待提交的文件。 - 问题二:
需要添加 pre-commit hook,并加入格式化的代码,这可能需要对hook 和命令行有一些了解,还要处理跨平台的问题,同时需要将写好的hook让每一名用户都安装。husky是一个包,只需要简单安装,就可以给Javascript项目带来使用hook的功能。
前置工作:
先执行 git init 在目录中创建新的 Git 仓库; 会生成 .git 隐藏文件夹;
第1步: husky安装
husky4.x 和 husky7.x的安装方式有非常大的差异。 husky支持自动 和 手动 两种安装方式。
husky 是一个 git hook 工具,可以帮助我们在git 操作之前与之后可设置自动执行的脚本,像:pre-commit、commit-msg、pre-push等等支持的 git hooks。
以 安装 husky7.x 为例:
自动安装只需要运行下面一条快捷安装命令即可:
# 自动安装方式:
npx husky-init
手动安装需要3个步骤:
# 1. 安装依赖
npm install husky --save-dev
# 2. 初始化 husky配置
npx husky install
# 3. 设置 prepare. 这样就会自动执行 2
npm set-script prepare "husky install"
选择上面任意一种安装方式完成 husky 的安装后,会在 package.json 中会添加如下代码:
{
"scripts": {
"prepare": "husky install"
}
}
同时会多出一个 .husky目录,其中的 pre-commit 就是我们要用到的 Git hook; husky 会将 Git 的 hooksPath配置从 .git/hook 修改为 .husky。如果其他流程有依赖Git hook,则可能需要注意 hook 的路径变化问题,可以看到 hooksPath的配置。
在 .git/config中查看:
husky-init 前:
husky-init 后:

第2步:preety-quick安装配置
preety-quick 安装命令:
# preety-quick 安装命令:
npm install --save-dev pretty-quick
# 使用 yarn
yarn add --dev pretty-quick
通过如下命令将 pretty-quick 添加到 hook 中。
# 通过如下命令将 pretty-quick 添加到 hook 中。
npx husky set .husky/pre-commit "npx pretty-quick --staged"
此时打开 .husky/pre-commit 文件,该文件中的内容如下,也可以不使用 "husky set"命令,直接修改这个文件
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# npm test
npx pretty-quick --staged
使用文本编辑器修改了代码;提交代码,即可体验提交时自动格式化的效果(提交代码自动格式化)。
commit时,自动修复格式化:

集成 Git Hooks 遇到的问题:
- 用命令commit的描述 "要用双引号" -->
错误X:git commit -m 'xxx'; 正确: git commit -m "xxx" - 如果commit提交失败或者没有格式化效果; -- 检查
.husky/pre-commit,是否存在npx pretty-quick --staged以及package.json中的scripts: {prepare: "husky install"}
使用ESLint
ESLint 可组装插件化的JavaScript和JSX检查工具, ESLint是在ECMAScript/JavaScript代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。
- ESLint 使用 Espree 解析JavaScript。
- ESLint 使用 AST 去分析代码中的模式。
- ESLint 是完全插件化的。每一个规则都是一个插件并且你可以在运行时添加更多的规则。
前置工作
创建干净的demo工程(以vue create xxx)为例:选择不安装任何的 ()linter / formatter;后面我们自己手动安装eslint。
首先安装 ESLint 。
# 安装 ESLint
npm install eslint --save-dev
初始化eslint配置(会生成对应的配置文件)
# 初始化 eslint配置
npx eslint --init
# 或者
npm init @eslint/config
PS: 如果全局安装了eslit ,可以直接运行 eslint --init

初始化成功后,会在项目的根目录生成一个 .eslintrc.js 文件(这边是json还是js还是yml)要看你在init时候选择的配置文件类型。

VS Code 中配置ESLint
在 VS Code编辑器中 配置 ESLint
第1步:下载 ESLint 插件(必须)
Error Lens(可选的);可以显示错误信息在当前代码行后

第2步:编辑器配置
设置 --> 打开 settings.json 或者 直接打开 .vscode/settings.json
添加如下配置:
{
// eslint配置:
"eslint.enable": true,
"eslint.run": "onType",
"eslint.options": {
"extensions": [
".vue",
".js",
".jsx",
".tsx",
".ts"
]
}
}
webstorm 启用eslint配置
在webstorm编辑器中启用eslint配置规则

parserOptions配置
parserOptions 告诉ESLint 我们希望支持的ECMAScript语法,
认情况下,ESLint支持ECMAScript5;如果代码中使用的语法和配置的语法不一致,那么ESLint在解析的时候就会报错。
env配置
env配置环境预置的全局变量,例:在env中设置
"browser":true; ESLint 就会支持在代码中使用浏览器环境的全局变量,而在把 browser 配置删除后,在代码中使用浏览器环境变量时,ESLint 就会报错。
rule检验规则的报错等级
每个检验规则有3个报错等级,
0代表关闭,1代表警告,2代表错误,
例:下列配置开启了两个规则,一个是警告,另外一个是报错:
module.exports = {
rules: {
quotes: 1,
eqeqeq: 2
}
}
己选择要使用的规则并手动配置 rules 会比较麻烦,可以直接使用社区成熟的规则集。
目前,使用较多的是 ESLint(eslint:recommended) 官方的规范和 Airbnb的规范;
可以像下面这样通过 extends关键引入:
module.exports = {
extends: ['eslint:recommended']
}
设置好 .eslintrc.js 文件后,运行如下的 "npx eslint ." 命令即可对代码进行检测:

从上面的结果可以发现,dist目录报错较多。dist目录存放编译后的代码,并不需要被检测。
解决办法: 白名单 和 黑名单 的方式:
白名单方式:ESLint支持目录校验,修改命令,只校验指定的文件即可。例: npx eslint 指定目录;

黑名单方式:新建.eslintignore 文件,要被eslint忽略的文件配置在其中即可;

发现每次运行 npx eslit . 很麻烦,把这个命令配置到 package.json中;
{
"scripts": {
"lint": "eslint src"
}
}

ESLint的校验规则``可以分 为两类,分别是 代码风格 和 代码质量;
Prettier 更关心代码风格的(简单的理解是代码怎么写的横平竖直),ESLint 重点在于 管理代码质量的;关注代码的语法和质量;
在 VS Code 中启用 ESLint --> 搜索"ESLint" --> Settings.json中配置如果下代码,eslint生效:
{
"eslint.enable": true, // 开启eslint检查
"editor.codeActionsOnSave": {
// 使用eslint来fix,包括格式化会自动fix和代码质量检查会给出错误提示
"source.fixAll.eslint": true
}
}
同时使用 Prettier+ESLint 它们规则冲突了,怎么办?
ESLint + Airbnb config 和 ESLint + Standard config都是成熟的 ESLint 规则集,如果 ESLint + Prettier是两种规则,如果配置规则冲突了怎么办?
场景:在 .prettierrc.json 中 修改配置规则:使用单引号:在 .eslintrc.js 中配置规则:默认是使用双引号;它们的规则冲突了;
修改 .prettierrc.json 中修改校验规则:"singleQuote": true 使用单引号规则;
配置 eslint的 quotes 报错等级;
eslint的quotes规则默认需要使用双引号。后面的数字代表校验规则的报错等级(0代表关闭,1代表警告,2代表错误)
此时使用 Prettier 来格式化代码 运行: npx prettier --write . 会格式化成单引号,但是 eslint 规则又要求使用 双引号,此时代码看起来是:prettier格式化成单引号成功了。但是eslint又要求是双引号,又报错了;

解决:使用 eslint-plugin-prettier + eslint-config-prettier;
下面介绍两款可以解决规则冲突的 ESLint 插件,分别是 eslint-plugin-prettier 和 eslint-config-prettier。
eslint-plugin-preitter 可以让 ESLint 对 Prettier 的代码风格进行检查,如果发现不符合 Prettier 代码风格的地方就会报错,其原理是先使用Prettier对代码进行格式化,然后与代码格式化之前的代码进行对比,如果不一致,就会报错。
eslint-config-prettier是一个规则集,其作用是把ESLint中 和 Prettier 的规则冲突的规则都关闭。
第1步:首先安装 eslint-plugin-prettier 和 eslint-config-prettier
npm install --save-dev eslint-plugin-prettier eslint-config-prettier
第2步:修改 ESLint 配置文件 .eslintrc.js
如果有带, 'plugin:vue/vue3-essential' 先去除,全部使用 eslint 和 prettier规则。
// .eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: ['eslint:recommended', 'prettier'], // ++++++
overrides: [],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['vue', 'prettier'], // ++++++
rules: {
'prettier/prettier': 'error', // ++++++
},
};
eslint-config-prettier提供了一种简洁配置:
module.exports = {
extends: ['eslint:recommended', 'plugins:prettier/recommended'],
}
此时使用 npx prettier --write .格式化代码,eslint就不会报错了;
Git提交时自动运行ESLint
如果能够在Git提交时自动运行ESLint,就可以多一层代码质量保证;
直接使用前面提到的 husky,如果在 .husky/pre-commit 文件中添加 npm run lint 命令,就可以在每次提交时都校验整个项目。但是如果项目较大,则执行校验会非常缓慢,从而导致提交时会卡住很近,而且不在本次提交的代码可能还未开发完成。这时解决ESLint问题是没有意义的。
注: npm run lint, lint命令需要在 package.json中配置 eslint 要检测的目录
如果只对本次提交的代码进行校验呢?可以使用LintStaged工具,LintStaged不仅可以对指定文件运行指定命令,还可以根据命令结果终止提交。
LintStaged工具
ESLint的Git Hooks使用 lint-staged工具;npm: lint-staged
前置工作:
先执行 git init 在目录中创建新的 Git 仓库; 会生成 .git 隐藏文件夹;
第1步:安装 husky 和 lint-staged
# npm 方式安装 如果已经安装了 husky 安装 lint-staged即可
npm install --save-dev husky lint-staged
# yarn 如果已经安装了 husky 安装 lint-staged即可
yarn add --dev husky lint-staged
第2步:在项目的根目录下新建LintStaged配置文件, .lintstagedrc.js 并做相关配置
**/*.js指定为 js 文件;**/*:所有文件
module.exports = {
'**/*': ['eslint --cache'],
}
第3步:修改 .husky/pre-commit文件,在该文件中添加lint-staged校验。
如果没有该文件使用 npx husky-init 初始化; 运行命令:(注意node版本不同命令也会略有区别):
# 生成 .husky 文件夹
npx husky install
# 在 pageage.json中的 scripts 添加 prepare命令(即 npm run prepare)
# <= node 16 运行:
npm set-script prepare "husky install"
# >= node16+ 运行:
npm pkg set scripts.prepare="husky install"
# 运行了 npm pkg 其实已经在package.json中的scripts 写入了 "prepare": "husky install" 命令
# 我们也可以运行 npm run prepare 生成 .husky 文件夹
# 往 .husky下添加pre-commit,并写入 npx lint-staged
npx husky add .husky/pre-commit "npx lint-staged"
.husky/pre-commit 文件最终内容:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# 安装了pretty-quick
npx pretty-quick --staged
npx lint-staged

结果:
此时修改 src/main.js,写入一行代码 const a = "1"; 会报两个错误:1. 定义的变量a未被使用;2. 是双引号,应该使用单引号;
尝试的去commit代码,看看是否会触发 git hooks,代码是否被改变?
为了防止vscode自动保存格式化;我们使用文本编辑器写入代码并保存;

运行commit,并查看输出结果:提交失败,并提示ESLint校验失败,此时 src/main.js 已经从双引号 被格式化成 单引号了。

vue create 命令已集成 lint
现代的cli工具已经集成了 linter / formatter Config,不用再去关心繁琐的配置过程了;
以 vue create xxx cli创建项目为例:会让我们选择 linter / formatter,有如下三种方式:
我们选择 ESLint + Prettier:
选择 In dedicated config files 定义专用的配置文件,在根目录下生成对应的配置文件;
会在根目录下生成 .eslintrc.js

linter 预设规则有如下几种:
-
ESLint + Airbnb config:
Airbnb 规范的 eslint 实现: 是其中一个最流行的 JavaScript 代码规范,它差不多包含所有 JavaScript 的角度。校验比较严格。
以vue项目为例:.eslintrc.js中的配置如下:
-
ESLint + Standard config:
Standard 规范:标准的 JavaScript 代码规范,自带 linter & 代码自动修正;
以vue项目为例:.eslintrc.js中的配置如下:
-
ESLint + Prettier:
Prettier是代码格式化插件:,它不关心语法,只关心代码格式是否统一规整;配合ESLint管理代码质量。prettier和eslint的部分规则有冲突;

规则越多,产生的冲突可能性也会多。vue项目默认还好继承 vue3-essential 的规则,这时候需要多个规则去平衡调和代码风格和质量,例如 .prettier.json, .eslintrc.js ;
规范提交信息的意义
Git每次提交代码,都要写提交信息。一般来说,提交信息需要清晰明了,说明本次提交的目的,但是不同的人对"清晰明了" 会有vu容妃守卫理解和习惯,对于多数人协作的项目来说,这可能会成为一个挑战。
统一提交信息格式可以带来很多好处,示例如下:
- 规范的约束作用,避免出现毫无意义的提交信息,如update、commit、temp等。
- 规范的提交信息,在对log分类、检索时更方便。
- 当生成变更日志时,可以直接从提交信息中提取。
统一提交信息,首先需要一个统一规范。规范来源于实践,社区中存在一些最佳实践,使用比较多的是Conventional Commits 中文叫约定式提交是一种用于给提交信息添加可读含义的规范。
约定式提交规范是一种基于提交信息的轻量级约定,它提供了一个组简单规则来创建清晰的提交记录。
约定式提交规范推荐的提交信息的结构如下:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
上述规范中常用的部分包括 type、description 和 body。
一个典型的提交信息示例如下:
feat: 添加ESLint环境
1. 添加ESLint环境
2. 支持VS Code ESLint插件
3. 支持Git 提交时自动执行ESLint
type 用来对提交进行分类,Conventional Commits 规范只提到了 fix 和 feat,
@commitlint/config-conventional 是 Angular 团队在使用的 基于 Conventional Commits 规范的扩展规则,其中带来了更多语义的type值。
常用的type值如下:
- feat: 开发新的功能
- fix: 修复bug,不改变功能
- docs: 修改文档
- style: 修改代码样式,不修改逻辑
- refactor: 重构代码逻辑,不修改功能
- test: 修改测试代码
Conventional Commits 规范和语义化版本是兼容的,对应关系如下:
| SemVer | Conventional Commits |
|---|---|
Patch(修订号),向下兼容的问题修改正 | type的值为 fix |
Minor(次版本号),向下兼容的功能性新增 | type的值为 feat |
Major(主版本号),不兼容的API修改 | type的值最后加 !或脚注中包含 BREAKING CHANGE |
根据上述对应关系,示例提交信息如下:
修改 Patch 版本号,对应的提交信息,示例如: fix: 修改utils中的对象拷贝bug
修改 Minor 版本号,对应的提交信息,示例如: feat: 修改拷贝函数添加参数控制
修改 Major 版本号,对应的提交信息,示例如:
# 例子1:
feat!: 功能改变了,会影响已经引用的。
# 例子2:
feat: 功能改变了,不兼容以前的代码。
BREAKING CHANGE: 拷贝传参改变了
有了规范,大家都遵守才有意义,我们引入校验工具 commitlint 来校验提交信息。
Lint检查和规范提交(完整版)
使用eslint规范开发过程代码质量,提交的时候怎么保持统一的提交格式规则呢 ?
分为两部分进行:
第一部分:使用 lint-staged,做提交前(pre-commit)的lint校验;
第二部分:使用 commitizen + commitlint规范提交信息(commit-msg);
上面讲了:
husky 是一个 git hook 工具,可以帮助我们在 git 操作之前与之后可设置自动执行的脚本,像:pre-commit、commit-msg、pre-push 等等支持的 git hooks。
原理:其实就是使用 husky 来创建2个钩子(pre-commit 和 commit-msg),
- pre-commit提交前钩子,然后执行lint-staged进行代码eslit校验;
- 创建commit-msg,进行提交信息的规范校验
准备创建示例项目
node版本: 16.15.1;
使用 vue create 命令创建项目:vue create xxxx;
linter formatter 选择:eslint + Airbnb config;
第一部分:使用 lint-staged,做提交前(pre-commit)的lint校验;
第1步:安装 husky 和 lint-staged:
# 安装 husky 和 lint-staged:
npm install --save-dev husky lint-staged
第2步:创建 lint-staged配置文件:
lint-staged 支持多种格式,例:
.lintstagedrc.json,.lintstagedrc.yaml,lint-staged.config.jsor.lintstagedrc.js等;根据自己的项目路径和需要配置。具体看npm package。
module.exports = {
"src/**/*.{js,vue}": ['eslint --cache']
}

第3步:修改 .husky/pre-commit文件,在该文件中添加lint-staged校验。
如果通过命令无法写入 npx lint-staged, 也可直接找到该文件,在该文件中修改亦可;

# 生成 .husky 文件夹
npx husky install
# 在 pageage.json中的 scripts 添加 prepare命令(即 npm run prepare)
# <= node 16 运行:会在package.json中的scripts 写入了 "prepare": "husky install" 命令
npm set-script prepare "husky install"
# >= node16+ 运行:
npm pkg set scripts.prepare="husky install"
# 运行了 npm pkg 会在package.json中的scripts 写入了 "prepare": "husky install" 命令
# 我们也可以运行 npm run prepare 生成 .husky 文件夹
# 往 .husky下添加pre-commit,并写入 npx lint-staged
npx husky add .husky/pre-commit "npx lint-staged"
.husky/pre-commit 文件最终内容:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# 安装了pretty-quick
npx pretty-quick --staged
npx lint-staged
我们尝试定义一个没有被使用的变量,根据在.lint-staged中配置的指定文件和eslint策略去检测。
结果如下:

第二部分:使用commitizen + commitlint规范提交信息;
commitizen专注于提交信息的录入;commitlint 专注于提交信息的校验。
commitlint安装配置: 让 commitlint 专注于提交信息的校验。
第1步: 安装 commitlint
# 安装 commitlint
npm install --save-dev @commitlint/config-conventional @commitlint/cli
第2步:根目录新建配置文件 commitlint.config.js,并添加相关内容:
module.exports = {
extends: ['@commitlint/config-conventional'],
};
注意:LF 和 CRLF 的选择

第3步:使用命令 测试 commitlint 校验结果; 命令行运行 echo aaa | npx commitlint

第4步:运行命令,将 commitlint 和 husky 集成。
运行这个明白之前,必须 安装了 husky, 项目内安装husky:
npm install husky --save-devtypicode.github: husky文档
# 先尝试执行
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
# 如果上条命令没效果或出现 Usage: xxx ,再尝试执行这个
node node_modules/husky/lib/bin add .husky/commit-msg 'npx --no -- commitlint --edit $1'
如果以上两条命令都没效果:
在window下运行命令出现了如下情况,请尝试重新手动安装Manual(手动安装):

node node_modules/.bin/husky add Manual(手动安装):
npm install husky --save-dev
npx husky install
npm pkg set scripts.prepare="husky install"
# 看看package.json的scripts中是否有 prepare
npm run prepare
# 尝试执行下
node node_modules/.bin/husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
如果还是出现错误或帮助信息,则把 node node_modules/.bin/husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"' 拆分为 node node_modules/.bin/husky add .husky/commit-msg 执行,会在 .husky 生成 commit-msg;
package.json的scripts下有 prepare 字段:

可以npm run prepare 会在根目录下 生成 .husky 文件夹
然后打开 ./husky/commit-msg, 把最下方的undefined替换成 npx --no -- commitlint --edit "$1"即可:

随便写个描述信息,会提示提交信息校验不通过

输入提交信息后再校验,虽然能够保证提交信息符合规范,但是体验并不友好,而如果能够再输入时给出友好的提示,这样不仅可以提高通过率,还可以提高提交效率。
优化一:
commitlint 提供了 @commitlint/prompt-cli 询问式的交互录入命令。
- 安装:
npm install --save-dev @commitlint/prompt-cli 修改package.json中的scripts字段,新增 ci命令,使用npm run ci命令替换git commit命令,再次提交时会有结构化的提醒和校验提示信息。
{
"scripts": {
"ci": "commit"
}
}
运行 npm run ci 结果如下:

commitlint的交互虽然勉强够用,但是不是特别好用, commitizen 是一款专注于交互式的录入提交信息的工具,
优化二:,
commitizen使用配置:commitizen专注于提交信息的录入
第1步:安装
# 安装 commitizen
npm install --save-dev @commitlint/cz-commitlint commitizen
第2步:修改package.json并配置 scripts 和 config :
# package.json中添加:
{
"scripts": {
"cz": "git-cz"
},
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
}
}
第3步:使用npm run cz命令进行提交,commitizen提供了更丰富、友好的交互界面,提交结果如下:

这样每次使用命令提交的时候都会被要求要输入规范的提交信息才能提交。那如果我想用编辑器自带的git工具提交呢,或者想使用原始的git命令提交呢?
拓展:WebStorm编辑器插件
实际的开发中我们
很少会使用 npm run xx脚本命令来提交代码的,都是在图形化的编辑器中直接点击或者快捷键提交的;如果我们使用编辑器自带的git来提交呢?
用 webstorm打开项目,我们删除了 package-locak.json, 不按规范填写提交下:
这时肯定会被./husky/commit-msg检查到,是 一个不符合规范的描述 提交
强烈推荐一个 webstorm的 Git 提交模板插件: Git Commit Template:
使用 Git Commit Template 插件快捷提交:
安装插件:
创建提交信息:
OK 之后,会自动帮我填入 Commit Message中:
commit成功后:
生成了规范的commit信息:

记录变更日志
每次发布新版本时都需要记录变更日志。历史提交信息是记录变更日志时的重要参考,在发布新版本之前需要手动查阅提交记录,整理变更日志。符合 Conventional Commits 规范的信息,可以使用 Standard Version 工具自动生成变更日志。
使用standard-version 工具可以自动生成变更日志。
第1步: 安装 standard-version
# local安装
npm install --save-dev standard-version
第2步: 使用 git log --oneline 查看提交记录如下:

第3步:测试安装后的情况: 运行 npx standard-version --dry-run;
执行 standard-version 命令查看效果,参数 --dry-run 代表测试运行,并不会 修改 CHANGELOG.md 文件中的内容,控制台会输出 standard-version 命令整理的变更日志。

如果不加参数--dry-run, 那么standard-version的命令会进行如下操作:
(1) 修改版本号
🟢 修改 package.json 和 package-lock.json文件。
🟢 会根据type来决定升级哪个版本号。
🟢 因为有feat,所以将版本从1.0.0,升级到1.1.0.
(2) 修改CHANGELOG.md文件。
(3) 提交内容。
(4) 添加Git tag.
注意:
对我们有用的是操作(2),需要注意的是,CHANGELOG.md文件中只包含符合 Conventional Commits 规范的提交信息,不符合 Conventional Commits规范的提交信息会被自动过滤。
CHANGELOG.md是 standard-version 用来记录变更命令的,运行命令会自动生成的。
第4步:为了方便执行脚本,在 package.json中配置 release 命令:
配置后,就可以 运行; 例:
npm run release --dry-run
{
"scripts": {
"release": "standard-version"
}
}
第5步:为你的第一个版本生成你的更新日志,
npm run release -- --first-release

更多standard-version的命令和使用,请查看 standard-version;
后话
规范需要和检查配合才能发挥更大的作用。目前在本地进行校验,依赖 Git hook 功能,然后使用 Git hook 校验存在被绕过的风险,本地校验的另一个问题是,协作时无法知道对方提交的代码是否符合规范,只有将代码下载到本地执行校验才可以获得校验结果。
Git 提交时会执行hook校验,如果添加参数 --no-verify, 则可以跳过 hook校验。
git commit -m "xxx" --no-vertify 就会跳过 git hook的校验;

如果能够在服务上运行校验,既解决了 Git hook 校验可能被绕过的问题。
社区中有很多在服务器上运行测试和校验的服务。社区提供的服务叫做 持续集成服务。
持续集成(Continuous Integration, CI) 是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成,每次集成都通过自动化的构建(包括编译、发布、自动化测试)来验证,从而尽早的发现集成错误。
后续持续集成...
参考:
EditorConfig官网
Prettier官网
ESLint中文官网
typicode.github: husky
npm package: pretty-quick
npm package: lint-staged
npm package: @commintlint/cli
npm package: @commintlint/config-conventional
npm package: standard-version