背景
团队协作中经常遇到这样的问题:
- 代码风格不统一
可以使用 linter 使代码风格统一。
- 使用 linter 检测之后有非常多的格式问题,手动修改很麻烦
可以使用 linter 命令来修复错误。比如 eslint 就可以 eslint --fix
。
- 使用命令修复的时候,不小心修改了他人代码,很容易造成冲突。
- 如果一个项目以前没有用过 linter,如何最方便地开始使用并且尽量不改动之前的代码?
解决以上问题的一个方案就是,在提交代码的时候,自动修复格式问题,并且只修复自己改动的代码。
具体实现可以借助于 husky + lint-staged + prettier 这几个工具。
最终效果如下图所示:
使用
首先安装包 eslint 相关的包,如:
# Node.js 可以使用 eslint-config-egg
$ tnpm i eslint eslint-config-egg babel-eslint -D
# 或 React 项目使用 eslint-config-airbnb
$ tnpm i eslint eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-config-airbnb -D
然后在项目根目录创建 .eslintrc
文件,并写入对应的配置,以 eslint-config-airbnb
为例:
.eslintrc
{
"extends": "airbnb"
}
接下来再安装 prettier
lint-staged
和 husky
:
$ tnpm i prettier lint-staged husky -D
简单介绍一下几个工具:
prettier
用来优化代码格式,比如缩进、空格、分号等等husky
用于实现各种 Git Hook。这里主要用到pre-commit
这个 hook,在执行 commit 之前,运行一些自定义操作lint-staged
用于对 Git 暂存区中的文件执行代码检测
接下来配置 package.json
:
"scripts": {
"lint": "eslint . --ext .js",
"prettier": "prettier --trailing-comma es5 --single-quote --write '**/*.{js,json,md}'",
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"**/*.js": [
"prettier --trailing-comma es5 --single-quote --write",
"eslint",
"git add"
]
},
scripts
lint
检测 js 代码的 eslint 错误prettier
使用 prettier 优化代码的格式
如果一个项目之前没有使用过 linter,现在加上了,并且需要处理所有的代码格式,就可以使用 tnpm run prettier
。
--trailing-comma es5
表示使用 ES5 支持的拖尾逗号;--single-quote
表示使用单引号。prettier 的所有参数详见 https://prettier.io/docs/en/options.html。
这些参数即可以在命令中配置,也可以使用配置文件 .prettierrc
来指定,如:
{
"singleQuote": true,
"trailingComma": "es5"
}
在优化代码格式的时候,有些文件不需要进行处理,则可以通过 .prettierignore
文件来配置:
dist/
node_modules
*.log
run
logs/
coverage/
husky
husky
里面定义了一些 Git 的钩子。
上面的示例中,"pre-commit": "lint-staged"
的含义就是在 pre-commit
阶段(也就是 commit 之前)执行 lint-staged
命令。
lint-staged
如上所述, lint-staged
在 pre-commit
的时候执行。lint-staged
里面定义了需要对 Git 暂存区中的文件执行的任务。
在该 package.json
示例中主要有一个任务: **/*.js
, 即对暂存区中所有 js 文件依次执行下面的操作:
prettier --trailing-comma es5 --single-quote --write
eslint
git add
也就是先优化暂存区中的 js 代码格式,再进行 eslint 检测,最后再执行 git add
,将优化后的代码添加到暂存区。暂存区中的代码文件,就是这几个命令的参数。
如果 eslint
步骤抛错了,则表示代码格式不符合 eslint 规范,进而导致 pre-commit
这个钩子就会抛错,最终导致 commit
操作失败。
因为 eslint
也只会检测 lint-staged
中的代码,也就是自己修改过的代码。所以即避免了影响他人代码,同时也避免了因他人代码格式问题造成自己的代码不能提交。
其他
husky
和 lint-staged
配合起来还有非常多的用处。
比如删除已经被 Git 追踪的文件。
比如 run/
目录是代码运行时生成的目录。如果一开始没有将 run/
添加到 .gitignore
里面,则每个人提交代码的时候都会提交自己的 run/
目录。由于每个人 run/
目录里面的文件很可能不一致,所以很容易造成冲突。
而且一旦文件已经被 Git 追踪,再将其添加到 .gitignore
里面,也无法在提交的时候忽略它。
这个时候,就可以在 pre-commit
阶段,利用 "lint-staged"
的任务删除暂存区里面的 run/
。
如下所示:
"lint-staged": {
"**/*.js": [
"prettier --trailing-comma es5 --single-quote --write",
"eslint",
"git add"
],
"run/*": [
"git rm --cached"
]
},
然后再在 .gitignore
里面添加上 run/
,这样以后再提交代码的时候,就再也不会将 run/
提交到 Git 仓库了。