前端面試必備——eslint與git鉤子

clipboard.png

引言

上篇文章前端面試必備-eslint篇在結尾處給了vue-cli配置eslint與git鉤子的代碼,但是估計你心中還是有很多疑問,爲什麼這麼配,怎麼自定義配置,爲什麼配置不能生效。莫急,看完這篇文章,估計你就真的會了。

git鉤子簡介

1.是什麼

和其它版本控制系統一樣,Git 能在特定的重要動作發生時觸發自定義腳本。 有兩組這樣的鉤子:客戶端的和服務器端的。 客戶端鉤子由諸如提交和合並這樣的操作所調用,而服務器端鉤子作用於諸如接收被推送的提交這樣的聯網操作。

2.爲什麼

隨心所欲地運用這些鉤子,能增加我們對程序的控制力,能實現更多的功能。

3.用法

在當前項目 .git/hooks下有很多鉤子.sample文件,這裏只講pre-commit鉤子

pre-commit 鉤子在鍵入提交信息前運行。 它用於檢查即將提交的快照,例如,檢查是否有所遺漏,確保測試運行,以及覈查代碼。 如果該鉤子以非零值退出,Git 將放棄此次提交

去掉.simple 再git commit的時候鉤子就會生效

4.編寫一個git hook小腳本

刪掉pre-commit裏面的內容,我們通過shell編程可以編寫腳本。

// pre-commit文件
echo "在git commit 之前執行腳本"

在控制檯輸入git commit 我們可以看到控制檯打印這句話
至此,我們完成了一個最簡單的鉤子腳本編寫

eslint與git鉤子

1.工程化

在開發團隊中爲了保持團隊所使用鉤子一致,維護起來算是比較複雜的,因爲 .git/hooks 目錄不隨你的項目一起拷貝,也不受版本控制影響。
簡單的解決辦法是把鉤子文件存放在項目的實際目錄中(在.git 外),這樣就可以像其他文件一樣進行版本控制,然後在.git/hooks中創建一個鏈接,或者簡單地在更新後把它們複製到.git/hooks目錄下。

具體做法是在根目錄下創建pre-commit可執行文件,在配置npm script
"hooks": "copy /y .\\.git_hooks\\*.* .\\.git\\hooks\\"
npm install 周後npm run hooks可以完成上述操作

2.直接編寫鉤子腳本

之前我們編寫的是最最簡單的腳本,瞭解了編寫腳本的原理
現在我們編寫一個能用到實際環境的pre-commit(eslint)腳本
顏色部分大家可以看這篇文章,雖然他有地方寫錯了系統默認顏色

//pre-commit

#!/bin/sh

#定義顏色的變量
RED_COLOR='\x1b[31;4m'   #紅

GREEN_COLOR='\x1b[32;4m' #綠
YELLOW_COLOR='\x1b[33;4m' #黃
BLUE_COLOR='\x1b[34;4m'  #藍
PINK='\x1b[1;35;4m'        #粉紅
LIGHT_BLUE='\x1b[1;36;4m'  #天藍
WHITE='\x1b[1;37;4m'  #天藍
RES='\x1b[0m'
# 下面這一行我確實看不懂,肯定和git add  commit文件有關係,有興趣的可以研究下
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".\(js\|vue\)$" | grep -v "node_modules" | grep -v "static")
# 沒有提交文件,退出
if [[ "$STAGED_FILES" = "" ]]; then
  exit 0
fi

PASS=true

echo  "\nValidating Javascript:\n"
# 這裏用變量代替特殊字符,所以不需要echo -e
# Check for eslint
which eslint &> /dev/null
if [[ "$?" == 1 ]]; then
  echo  "${RED_COLOR}Please install ESlint${RES}"
  exit 1
fi

# 獲取每個文件 執行eslint
for FILE in $STAGED_FILES   
do
  eslint "$FILE"

  if [[ "$?" == 0 ]]; then
    echo  "\t${GREEN_COLOR}ESLint Passed: $FILE${RES}"
  else
    echo  "${RED_COLOR}ESLint Failed: $FILE${RES}"
    PASS=false
  fi
done

if ! $PASS; then
  echo  "${RED_COLOR}COMMIT FAILED:${RES} eslint校驗未通過。請修復eslint錯誤,然後重試.\n"
  exit 1
else
  echo  "${YELLOW_COLOR}COMMIT SUCCEEDED${RES}"
fi
# $? 爲上一次的執行結果
exit $?  

3.通過pre-commit

上面這個是我們項目裏面使用的,真實可跑,由我們老大編寫,shell編程。
但是我等菜雞前端並不會這麼高端的東西,咋整呢?...
莫怕,有pre-commit能自動在git commit之前調用我們的npm run test (可以指定)

pre-commit is a pre-commit hook installer for git. It will ensure that your npm test (or other specified scripts) passes before you can commit your changes. This all conveniently configured in your package.json.
"scripts": {
    "test": "echo \"Error: I SHOULD FAIL LOLOLOLOLOL \" && exit 1",
    "foo": "echo \"fooo\" && exit 0",
    "bar": "echo \"bar\" && exit 1"
  },
  "pre-commit": [
    "foo",
    "bar", //遇到1停止
    "test"
  ]

在安裝完以後,可以按上面這個配置一下。應該會正常執行foo->然後執行bar的時候返回1,報錯,停止
實際上我們有這個工具之後我們再也不用編寫令人厭煩的shell腳本了
聰明的你估計已經想出來了,可以直接按上篇文章所說,執行配置的lint腳本即可

"scripts": {
    "lint": "eslint --ext .js .jsx .vue src"
  },
  "pre-commit": [
    "lint" //標記1
    "foo"
  ]

eslint校驗不通過返回1,正好使程序在標記1處停止,不會執行foo

4.用lint-stage優化

上面的配置其實已經能滿足絕要求了,但是聰明的你發現每次lint的時候都是lint的src文件夾,但是我們實際只想lint提交的問題,這時候我們就需要請出我們另外一個庫了,lint-stage,它只幫我們處理git stage裏面的文件(也就是每次git add的文件)

Linting makes more sense when run before committing your code. By doing so you can ensure no errors go into the repository and enforce code style. But running a lint process on a whole project is slow and linting results can be irrelevant. Ultimately you only want to lint files that will be committed.

本麼總結了文檔中的標準寫法,有如下業務寫法
注意這裏我沒驗證過,加husky這個玩意是否有用,因爲我的項目在vue-cli裏面,不用加husky

{
  "scripts": {
    "lint": "eslint --fix --ext .js .jsx .vue src"
    "lint-staged": "lint-staged"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,jsx,vue}": ["npm run lint","git add"] //標記2
  }
}

這裏說一下爲什麼標記2處要加上git add,這是因爲我們selint 後面加了參數--fix 會自動修復文件,修復後的屬於新產生的文件,我們自動git add添加到staged裏面

5.vue-cli下的配置

vue-cli官方文檔寫的是

{
  "gitHooks": {
    "pre-commit": "lint-staged"
  }
}

但是我發現這種寫法是錯的,如果有gitHooks這個屬性vue會一直執行test腳本,而且會報錯。

下面這個寫法我項目里正在用,肯定沒問題,大家放心的copy吧

 "scripts": {
    "dev": "vue-cli-service serve",
    "build": "vue-cli-service build ",
    "test": "vue-cli-service build --mode productionTest",
    "lint": "vue-cli-service lint --fix --quiet",
    "lint-staged": "lint-staged"
  },
  "pre-commit": "lint-staged",
  "lint-staged": {
    "*.{js,jsx,vue}": ["npm run lint","git add"]
  },

總結

本文對eslint和git鉤子的聯繫做了詳細介紹,希望能給大家的項目帶來幫助。
很久沒寫文章了,罪過罪過。今天一口氣寫了兩篇,希望能一掃往日頹廢,重新振作起來,,,加油!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章