在開發過程中,通常使用 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 # 保存修改並退出
