前言
公司一个老我的项目,没有做代码提交前的校验,我拿到后,想着老我的项目嘛也没工夫帮它弄这些,反正就是改一点点小东西;尽量跟着它的代码格调写,写完提交就行;
直到某一天,又有一个人退出了进来。好家伙,间接干出事了。
很多个文件一起提交的,而后 commit-msg 不标准,代码缩进也不标准,换行符也不统一,外面还有很多没用的代码,可读性极差;
当你某一天 fetch 代码时,发现很多文件是这样的 👆 你是不是很解体?
但问题终归是得去解决的;治理污水的最好办法就是从能污水产生的中央开始整治。我来帮它加上吧。🥰
上面我将带大家一起,先通过husky
+eslint
实现一个最简略的代码标准校验,而后逐渐优化,最初通过husky
+eslint
+lint-stage
+commitlint
+prettier
实现一个强有力的限度。最初再配合commitizen
,通过commitlint-config-cz
+cz-customizable
实现自定义的提交模板和限度规定来实现团队最终的我的项目提交限度规约
。
eslint+prettier
这里我为该我的项目适配了一套 eslit 规定,依照这套规定提交的代码不会有抵触。
eslint 和 prettier 大家平时我的项目应该都用到过,应该都很相熟了,这里将不占用篇幅。(想看的能够私聊我,我能够独自出一篇 eslint 和 prettier 主题的文章)
🦄 在这篇文章中,次要解说如何在团队协同工作时,在 git 提交代码更改前,对不标准的代码和提交信息进行校验,修复,并限度不标准的提交。
husky
首先要介绍的是husky
,搞工程化,咱们必定都少不了 husky
,它能很不便的帮咱们阻挡小可爱们的防御,不,是为咱们的我的项目增加git hooks
具体方法
首先咱们将 husky
装置到开发依赖中
npm i husky -D
# or
yarn add husky -D
留神
目前我所装置的版本是
husky@7.0.4
,因为husky@6.0.0
后做了breaking change
,所以在6.0.0
版本之前的那种设置钩子的办法曾经不实用了,这里咱们只介绍最新的形式。
装置完后,咱们须要在以后我的项目中创立一个.husky
目录并指定该目录为 git hooks
所在的目录。
应用以下命令疾速创立 👇
#--no-install 参数示意强制npx应用我的项目中node_modules目录下的husky依赖包
npx --no-install husky install
为了让其他人在此我的项目中装置依赖后也能主动创立.husky
目录并指定该目录为 git hooks
所在的目录,咱们须要在 package.json
外面增加一条脚本"prepare": "husky install"
应用以下命令疾速增加 👇
npm set-script prepare "husky install"
prepare
脚本会在npm i
或者其余yarn or yarn add
之后主动执行。也就是说当咱们装置依赖后会主动执行husky install
命令,从而主动创立.husky
目录并指定该目录为git hooks
所在的目录。
应用以下命令疾速创立 👇
npx --no-instal husky add .husky/pre-commit "npm run [你要执行的命令]"
实现后能够看到.husky
目录下新增了一个pre-commit
文件,其中的内容为 👇
这里我用的是npm run lint
,这样咱们就能够配合 Eslint 的代码校验,来限度不标准代码的提交了
能够看到,不合乎 Eslint 校验规定的代码是没法提交的;
当然,这里的报错问题只是因为缩进不标准引起的,相似这种的问题还有引号,句尾分号,换行符等等…都能够通过 eslint
的参数 --fix
来主动修复,这样就能够在提交前,先将能实现主动修复的简略代码格调问题后 commit。简单的状况还是要本人去手动解决的。
说到换行符,这里咱们须要理解的是:在 Windows 上默认的是回车换行(Carriage Return Line Feed, CRLF),然而,在 Linux/MacOS 上则是换行(Line Feed, LF)。
咱们能够试一下将原先换行符为crlf
的文件格式化为换行符为lf
后,执行git add .
的状况。
能够看到最终 LF 换行符还是被 CRLF 转化了;
如果你们不会跨平台合作(都在 Mac/Linux,或者都在 Windows 上协同),只须要在以后我的项目中通过git config core.autocrlf false
来阻止这种状况的产生。
为了保险起见,你须要新建一个.gitattributes
文件(次要用于定义每种文件的属性,以不便 git 帮咱们对立治理。),设置 eol(end of line)为指定的换行符(lf/crlf),这里我把所有文件*.*
的换行符都设置为了 LF,并且将一些非文本文件进行了标记(排除它们),你也能够对每一种文件类型别离设置对应的属性 => *.js eol=lf
,*.ts eol=lf
…
*.* eol=lf
*.jpg -text
*.png -text
...
# 或者👇
*.js eol=lf
*.ts eol=lf
*.json eol=lf
...
文件内容如下 👇
这样,咱们不论在什么平台上开发,文件换行符都对立为 LF。
能够看到应用.gitattributes
配置文件后执行git add
,所有不是指定换行符的文件都会被主动更换为你指定的换行符,例如我这里指定了lf
,那么 git add .
后,不是以 lf
换行的文件都会被转换为 lf
,并在终端输入warning: CRLF will be replaced by LF in xxxx/filename
,如图 👇
.gitattributes
有很多用途,具体能够查看 👉gitattributes。
🥰 到这里,一个最简略的代码格调限度办法就曾经实现了。
既然做了,就必定要做一套残缺的,且好用的。上面咱们来持续欠缺其余性能 ~
lint-staged
什么是lint-staged
?顾名思义,借助这个工具只是用来查看 git 暂存区文件的,就是在你git add file1,2,3...
后的暂存区文件中运行 lint
的一个工具。
每次提交一两个文件,却都要 lint
所有文件话,是很没有必要的,咱们只对须要提交的代码进行 lint
,这样能够缩小很多没必要的工夫开销。(如果你每次批改一个文件,都要去 lint
所有文件,这个工具对你来说就没有什么意义了,husky
就管够 🤐)
应用办法
咱们将.husky/pre-commit
中之前写代码改为 👇
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
- npm run lint
+ npx --no-install lint-staged
而后在 package.json 中增加以下代码,lint-staged
对象中采纳键值对的形式进行配置,键名是你想解决的单个文件或一个文件类型,多个类型能够写在{}
中,用逗号分隔;键值是一个数组,数组中为 lint 时须要执行的命令组。
{
"lint-staged": {
"*.{ts,js,vue}": ["eslint", "echo '没问题!'"]
}
}
增加玩上述代码后,咱们通过测试,将两个文件的缩进改为不符合规范的状况,而后将其中一个文件暂存后,咱们运行git commit
后发现终端的报错中,只有一个文件的 lint
报错信息,另一个文件的报错并没有呈现。
当所有暂存区代码都符合规范时 👇,才会通过校验执行提交。
✔ Preparing lint-staged...
✔ Hiding unstaged changes to partially staged files...
✔ Running tasks for staged files...
✔ Restoring unstaged changes to partially staged files...
✔ Cleaning up temporary files...
commitizen
Commitizen 是一个撰写合乎下面 Commit Message 规范的一款工具。通过它能够实现交互式撰写标准的 Commit Message。
如果只在本仓库应用 👇
npm install commitizen -D
如果你想全局都用 commitizen 来帮你做 commit
npm install commitizen -g
装置实现后,个别咱们都采纳合乎 Angular 的 Commit message 格局的提交标准(当然也能够自定义,前面会讲到~),运行以下命令生成合乎 Angular 提交标准格局的 Commit message。
如果你我的项目用的是 npm 👇
# 如果你我的项目用的是npm
npx --no-install commitizen init cz-conventional-changelog --save-dev --save-exact
如果你我的项目用的是 yarn 👇
# 如果你我的项目用的是yarn
npx --no-install commitizen init cz-conventional-changelog --save-dev --save-exact
运行了上述命令后,它将为你我的项目装置 cz-conventional-changelog 适配器模块,把 config.commitizen 的密钥增加到文件的根目录增加到 package.json
中
能够在package.json
中看到,主动的新增了以下内容 👇
{
...
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
...
}
实现后,通过命令yarn cz
,你如果是全局装置的 commitizen
,那你间接 git cz
,都能够通过以下交互式的撰写 commit messag 而后提交
限度 commitlint
因为 commitizen 并不是强制应用的,依然能够通过git commit
来提交,所以咱们必须在不论是通过cz
还是git commit
提交前,都要对 commit messag 进行一次校验,不符合规范的状况下是不容许进行 commit 的
首先咱们须要装置commitlint
,commitlint/config-conventional
yarn add @commitlint/cli @commitlint/config-conventional -D
应用以下命令疾速创立 git hooks 的 commit-msg 钩子 👇
这样每次 commit 的时候都会由 commitlint 对 commit message 进行一次测验
npx --no-instal husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
而后咱们创立一个 commitlint 配置文件到我的项目根目录 👇
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
以上将会在我的项目目录中生成 commitlint.config.js
,代码如下,他将继承@commitlint/config-conventional
中的 Commit message 标准。(”feat”, “fix”, “perf”, “refactor”…)
module.exports = {
extends: ["@commitlint/config-conventional"],
};
而后咱们在终端进行测试
echo 'feat: bar' | npx --no-install commitlint
如果你执行下面这个行命令后呈现了以上这种报错。
将文件更改问 UTF-8 的格局即可解决;这个问题目前曾经在 👉 Issues中,有不少人遇到了(我也是 😂)。
最简略的办法就是,把文件用记事本关上,抉择另存为,而后在弹窗的右下角更改字符编码为 UTF-8 (Windows 用户运行echo "xxx" > xx.js
时,文件编码可能为 UTF-16 LE),更改好后,把原来的commitlint.config.js
文件替换掉即可。
解决以上问题后,咱们再测试一下,能够看到,不符合规范的 commit-msg 是会导致报错的,也就 commit 不了了,阐明咱们的 commitlint 曾经失效了~ 👏👏👏
到此,commit-msg 的校验也曾经实现 ✔
如果,你想自定义 commitlint 的交互文本(不必 feat,fix…,很多人都喜爱在 commit message 后面加一个 emoji 表情符号),当然也能够。
咱们须要装置 cz-customizable
来实现自定义 commit message 规定,以及装置对应的commitlint-config-cz
来配套校验(间接从自定义的文件里读取规定)
运行以下命令 👇
yarn add commitlint-config-cz cz-customizable -D
在我的项目根目录,创立一个.cz-config.js
文件,并复制cz-config-EXAMPLE.js 中的内容到其中。而后改成你本人想要的规定即可。
当然,你也能够用我写好的:
module.exports = {
types: [
{ value: "feat", name: "feat: 一个新的个性" },
{ value: "fix", name: "fix: 修复一个Bug" },
{ value: "docs", name: "docs: 变更的只有文档" },
{ value: "style", name: "style: 代码格调,格局修复" },
{ value: "refactor", name: "refactor: 代码重构,留神和feat、fix辨别开" },
{ value: "perf", name: "perf: 码优化,改善性能" },
{ value: "test", name: "test: 测试" },
{ alue: "chore", name: "chore: 变更构建流程或辅助工具" },
{ value: "revert", name: "revert: 代码回退" },
{ value: "init", name: "init: 我的项目初始化" },
{ value: "build", name: "build: 变更我的项目构建或内部依赖" },
{ value: "WIP", name: "WIP: 进行中的工作" },
],
scopes: [],
allowTicketNumber: false,
isTicketNumberRequired: false,
ticketNumberPrefix: "TICKET-",
ticketNumberRegExp: "\\d{1,5}",
// 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: "简短阐明(最多40个字):",
body: '长阐明,应用"|"换行(可选):\n',
breaking: "非兼容性阐明 (可选):\n",
footer: "关联敞开的issue,例如:#12, #34(可选):\n",
confirmCommit: "确定提交?",
},
allowCustomScopes: true,
allowBreakingChanges: ["feat", "fix"],
// skip any questions you want
skipQuestions: ["scope", "body", "breaking"],
// limit subject length
subjectLimit: 100,
// breaklineChar: '|', // It is supported for fields body and footer.
// footerPrefix : 'ISSUES CLOSED:'
// askForBreakingChangeFirst : true, // default is false
};
创立完.cz-config.js
文件后,咱们须要回到 package.json 文件中,将 config.commitizen.path 更改为"node_modules/cz-customizable"
,如果你的.cz-config.js
文件在我的项目根目录下,那么能够不配置上面这条,commitlint-config-cz 会主动在我的项目根目录下寻找: .cz-config.js
或 .config/cz-config.js
...
{
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
},
// 如果你的.cz-config.js文件在我的项目根目录下,那么能够不配置上面这条,commitlint-config-cz会主动在我的项目根目录下寻找: .cz-config.js 或 .config/cz-config.js
"cz-customizable": {
"config": "你的文件门路/xxxconfig.js"
}
}
}
...
对于commitlint-config-cz
更高级的用法能够查看 👉commitlint-config-cz
最初咱们将之前创立过的commitlint.config.js
中的代码进行更改 👇
module.exports = {
- extends: ["@commitlint/config-conventional"],
+ extends: ["cz"],
};
或者你也能够在commitlint.config.js
中手动增加自定义的规定 👇,他将笼罩 extends 中的规定
module.exports = {
extends: ["@commitlint/config-conventional","cz"],
rules: {
"type-enum": [
2,
"always",
[
"init",
"build",
"ci",
"chore",
"docs",
"feat",
"fix",
"perf",
"refactor",
"revert",
"style",
"test",
],
],
},
};
到这里,自定义的 commit message 的校验也 ok 了 ✅
最初
揭示:我的项目的代码格调和规定要和团队一起制订哦 ~
至此,在团队协同的我的项目中,不符合规范的提交就被扼杀在摇篮外面了。咱们大家不论是从书写代码还是提交代码最好都要标准哦~ 不给本人惹麻烦的同时,也不会给别人或公司带来麻烦。这就是本篇的全部内容啦~如果对你有帮忙,记得点赞激励 ~
我是荣顶,一个面向高兴编程的前端开发 🥰
如果你也十分酷爱前端相干技术!扫描二维码~ 退出前端超人技术交换群 🦄
回复 [加群],将拉你进学习交换群,与其余前端爱好者共同进步!
回复 [书籍],获取大量前端pdf书籍。
朋友圈不定期举办送书流动。一起加油,冲!
发表回复