作者: 王振州 时间: 2020-12-18
由于每个人的编译器或代码风格不同, 而在协同开发项目的时候, 经常出现由于代码风格而出现的冲突, 或则 commit 信息杂乱不能分辨提交的代码解决了哪些问题和影响范围是哪些, 因此需要保证 git 上的代码和 commit 信息的风格一致性, 以减少 Bug,方便互相修改,短时间内能上手,而因此诞生了许许多多的工具。下面主要介绍下目前主流的前端代码格式化的工具。
Husky是 Git hooks 工具,可以防止使用 Git hooks 的一些不好的 commit 或者 push。
npm install husky --save-dev
or
yarn add husky --dev
// package.json
{
"husky": {
"hooks": {
// commit 之前触发
"pre-commit": "npm run test",
// push 之前触发
"pre-push": "npm run test",
"...": "..."
}
}
}
在1.0.0
之后的版本支持了使用.huskyrc
,.huskyrc.json
,.huskyrc.js
配置文件,可以不放在package.json
中。Husky 支持的Git hooks还是很全面的,如常用的pre-commit
、pre-push
。这样我们就能再一些特定的时间点做一些事情。
在有了 Husky 赋能之后,我们有能力在 Git 的钩子里做一些事情,首先不得不提的是代码的提交规范和规范的校验,优雅的提交,方便团队协作和快速定位问题。首推Commitlint
yarn add @commitlint/config-conventional @commitlint/cli --dev
// 生成配置文件commitlint.config.js,当然也可以是 .commitlintrc.js
echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js
{
"husky": {
"hooks": {
"pre-commit": "npm run test",
"commit-msg": "commitlint -e $HUSKY_GIT_PARAMS"
}
}
}
<type><scope>: <subject>
常用的 type 类别
upd:更新某功能(不是 feat, 不是 fix)
feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动
例子:
git commit -m 'feat: 增加 xxx 功能'
git commit -m 'bug: 修复 xxx 功能'
scope 影响范围
subject subject 是 commit 目的的简短描述,可以做一些配置,如最大长度限制。
rule 配置说明::rule 由 name 和配置数组组成,如:'name:[0, 'always', 72]'
,数组中第一位为 level,可选0,1,2
,0 为 disable,1 为 warning,2 为 error,第二位为应用与否,可选always|never
,第三位该 rule 的值。具体配置例子如下:
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [
2,
"always",
["upd", "feat", "fix", "refactor", "docs", "chore", "style", "revert"],
],
"type-case": [0],
"type-empty": [0],
"scope-empty": [0],
"scope-case": [0],
"subject-full-stop": [0, "never"],
"subject-case": [0, "never"],
"header-max-length": [0, "always", 72],
},
};
这里列出了大部分常用的配置,其它的可以参考 Commitlint 网站,具体使用例子:
这里我们使用错误的提交方式,最上面的是自动测试的脚本,大家可以忽略,husky 给出了 commit-msg 的 input 为 xxx,触发了 subject-empty,type-empty 两个规则,提交不符合规范,被拦了下来。如果是正确的提交,例子如下:
module.exports = {
types: [
{
value: "docs",
name: "docs: 仅仅修改了文档,比如README, CHANGELOG, CONTRIBUTE等等",
},
{ value: "chore", name: "chore: 改变构建流程、或者增加依赖库、工具等" },
{ value: "feat", name: "feat: 新增feature" },
{ value: "fix", name: "fix: 修复bug" },
{ value: "merge", name: "merge: 合并" },
{ value: "perf", name: "perf: 优化相关,比如提升性能、体验" },
{ value: "refactor", name: "refactor: 代码重构,没有加新功能或者修复bug" },
{ value: "revert", name: "revert: 回滚到上一个版本" },
{
value: "style",
name: "style: 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑",
},
{ value: "test", name: "test: 测试用例,包括单元测试、集成测试等" },
],
scopes: [{ name: "cli" }, { name: "工具" }, { name: "模块" }],
messages: {
type: "选择要提交的更改类型:",
scope: "\n此更改影响的范围(可选):",
customScope: "此更改影响的范围:",
},
allowCustomScopes: true,
allowBreakingChanges: ["feat", "fix"],
};
下面我们就可以使用 git-cz 进行提交代码了
在我们介绍了 Husky、Commitlint 之后,来看一个前端文件过滤的工具Lint-staged,代码的格式化肯定会涉及到文件系统,一般工具会首先读取文件,格式化操作之后,重新写入。对于较大型的项目,文件众多,首先遇到的就是性能问题,虽然如 Eslint 之类的也有文件过滤配置,但毕竟还是对于匹配文件的全量遍历,如全量的.js
文件,基本达不到性能要求,有时还会误格式化其他同学的代码,因此我们引入 Lint-staged,一个仅仅过滤出 Git 代码暂存区文件(被 committed 的文件)的工具。
npm install --save-dev lint-staged husky
首先明确一下,Lint-staged 仅仅是文件过滤器,不会帮你格式化任何东西,所以没有代码规则配置文件,需要自己配置一下,如:.eslintrc
、.stylelintrc
等,然后在package.json
中引入。
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": ["eslint --fix", "git add"]
}
}
当文件变化,我们git commit
它们,pre-commit
钩子会启动,执行lint-staged
命令,我们对于lint-staged
如上文配置,对本次被 commited 中的所有.js
文件,执行eslint --fix
命令和git add
,命令,前者的的目的是格式化,后者是对格式化之后的代码重新提交。
除了在package.json
中配置,也可以在.lintstagedrc
、lint-staged.config.js
文件中,lint-staged
的常用选项除了liners
之外,还有ignore
、concurrent
等,具体参考文档:
{
"lint-staged": {
"linters": {
"*.{js,scss}": ["some command", "git add"]
},
"ignore": ["**/dist/*.min.js"]
}
}
对于文件的过滤,lint-staged
的格式如下:
{
// 项目中以 .js 结尾的文件
"*.js": "eslint",
// 项目中以 .js 结尾的文件
"**/*.js": "eslint",
// .js文件在src目录中
"src/*.js": "eslint",
// .js文件在src目录内和下面的任何位置
"src/**/*.js": "eslint"
}
lint-staged
提供的功能远不止于此,它只是平台,具体的格式化工具的搭配有很多,如对于图片的、样式的、.tsx
、.md
等文件的。
Prettier是一个支持多语言的代码格式工具,如常用的:js
、jsx
、Vue
、Flow
、Ts
、HTML
、CSS
等,非常全面,将代码解析为 AST,然后重新组装,目的是最终输出风格统一的代码,对比 eslint 对 error 的 fix 要强一些,如最大长度的改动,eslint 只是对有问题的地方进行格式化修改,不改动源代码风格,而 prettier 是对全量的代码进行格式化。
npm install --save-dev prettier
or
yarn add prettier --dev
// package.json
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,json,css,md}": ["prettier --write", "git add"]
}
}
这里我们结合之前用到的husky
、lint-staged
,默认 prettier 是直接标准输出到终端的,--write
,这个配置代表直接改写文件。
prettier 让我们专注于业务逻辑,无需再纠结代码风格,配合其它工具,实现了代码提交到仓库前,统一格式化。