在开发过程中,通常使用 eslint
来规范团队的代码风格。但是 eslint
只能在开发服务器启动的时候才去检验代码。如果一个人在不启动开发服务器的情况下,修改了代码直接提交到git,那么别人pull下来的代码肯定会报错,我们需要把错误遏制在提交之前。
唯一的麻烦可能是地震的时候commit不太方便
------- 一位成都前端开发者留言说
git hooks 是什么
git hooks
是git的一种钩子机制,可以让用户在git操作的各个阶段执行自定义的逻辑。
git hooks
在项目根目录的 .git/hooks
下面配置,配置文件的名称是固定的,使用shell
语法编写。
里面包含 pre-commit
, pre-push
, commit-msg
等多种钩子,具体可以查看 Git 钩子。
从头编写如此多的 shell脚本
太难,所以我们使用 husky
来帮我们自动生成这些 shell脚本
。
husky是什么
husky 就是一款用于处理 git hooks
的npm包包。
安装好 husky
,他会自动在项目的 .git/hooks
文件夹下面生成各种配置文件。
如果你在git init
之前已经安装了 husky
,那么需要卸载掉再重装才能使用。
pre-commit 举例
不推荐使用 husky
来管理 pre-commit
,因为他只是简单的运行 npm run lint
命令来检测当前的文件状态,而无法检测仅仅暂存区的文件。推荐使用以下配置通过检测暂存区文件,来阻止不规范代码的提交。
这是 .git/hooks/pre-commit
文件的源码:
#!/bin/bash
# 如果在commit时有未添加到暂存区的文件,拒绝提交
diff=$(git diff)
if [[ $diff !=0 ]];then
echo "some files is changed but not add to stash, git commit denied"
exit 1
fi
# 读取git暂存区的.js 和 .vue文件
files=$(git diff --cached --name-only | grep -E '.js$|.vue$')
# 在控制台打印文件列表
echo $files
# Prevent ESLint help message if no files matched
# 如果文件列表为空,退出执行环境,继续执行commit操作
if [[ $files = "" ]] ; then
exit 0
fi
failed=0
# 循环文件列表
for file in ${files}; do
# 判断文件是否存在(-e 表示 exists)
if [ ! -e $file ] ; then
continue
fi
# 在控制台打印该文件的eslint检验结果,如果通过,则返回空
git show :$file | ./node_modules/.bin/eslint $file --color --fix
# 文件未通过eslint检验,标记为失败
if [[ $? != 0 ]] ; then
failed=1
fi
done;
# 有文件未通过检验,退出执行环境,中断commit操作
if [[ $failed != 0 ]] ; then
echo "❌ ESLint failed, git commit denied"
exit $failed
fi
从文件源码可以看出,git 将会在你将文件添加到暂存区后,执行eslint操作,通不过操作的时候,这次操作将被取消 (shell exit 1
)。
注意,需要使用npm而不是yarn安装node_modules
通过测试发现,如果通过 yarn add
的方式安装 eslint
, babel-eslint
的话,这句代码将会报错:
git show :$file | ./node_modules/.bin/eslint $file --color --fix
只用用npm重新安装上面提到的一些包,才能在 ./node_modules/.bin
目录下找到eslint,不知道你们有没有遇到这样的问题。
注意,需要使用unix文件编码
git hooks
需要的 shell脚本
,需要是unix文件格式才能正常运行。
否则windows10系统会抛出换行符错误,而macOS则会抛出 pre-commit
不是文件或者文件夹的错误。
需要打开bash,使用如下命令修改,方可正常使用。
vi ./.git/hooks/pre-commit # 打开配置文件
:set ff-unix # 设置文件格式为unix文件,(ff意为fileformat)
:wq # 保存修改并退出