前端規範之Git工作流規範(Husky + Comminilint + Lint-staged)

Yellow_ice發表於2021-10-08

    程式碼規範是軟體開發領域經久不衰的話題,幾乎所有工程師在開發過程中都會遇到或思考過這一問題。而隨著前端應用的大型化和複雜化,越來越多的前端團隊也開始重視程式碼規範。同樣,前段時間,筆者所在的團隊也開展了一波開源治理,而其中程式碼規範就佔據了很重要的一項。接下來的幾篇文章,將會對JS程式碼規範、CSS規範、Git提交規範、Git工作流規範以及文件規範進行詳細的介紹~

    系列文章:

  •     前端規範之JS程式碼規範(ESLint + Prettier)
  •     前端規範之CSS規範(Stylelint)
  •     前端規範之Git提交規範(Commitizen)
  •     前端規範之Gti工作流規範(Husky + Commitlint + Lint-staged)
  •     前端規範之文件規範

    本文主要介紹了前端規範之Git工作流規範(Husky + Commitlint + Lint-staged),將會對Husky、Commitlint和Lint-staged的使用進行介紹,歡迎大家交流討論~

 

1. 背景

    在前面的幾篇文章中,我們已經介紹瞭如何在專案中安裝並配置ESLint、Prettier、Stylelint和Commitizen。有了這些工具,可以很好的幫助我們格式化程式碼並提示錯誤。

    

    然而,有些同學可能會把ESLint、Stylelint或Commitizen提示的錯誤忽視不見,直接將程式碼提交到程式碼倉庫中。這樣做的話,那麼其他同學在pull程式碼並diff程式碼時可能會出現大段程式碼標紅,同時在進行CI時又可能因為程式碼風格或規範問題被打回重改。

    那麼,有沒有一種方法,讓大家在提交程式碼時需要確保本地的程式碼或Commit Message已經通過檢查才能夠push到程式碼倉庫,從而更好的保障程式碼質量呢?接下來,將會介紹如何使用Husky + Commintlint + Lint-staged打造規範的Git檢查工作流,確保我們的程式碼只有符合規範才能提交到程式碼倉庫。

    

2. Husky

    首先,先來介紹一下Husky的安裝和相關配置。

2.1 什麼是git hook

    在介紹Husky之前,我們先來看什麼是git hook,也就是常說的Git鉤子。

    和其它版本控制系統一樣,Git能在特定的重要動作發生時觸發自定義指令碼。有兩組這樣的鉤子:客戶端的和伺服器端的。 客戶端鉤子由諸如提交和合並這樣的操作所呼叫,而伺服器端鉤子作用於諸如接收被推送的提交這樣的聯網操作。 你可以隨心所欲地運用這些鉤子。

    其中,客戶端鉤子我們可能用的比較多,客戶端鉤子通常包括了提交工作流鉤子、電子郵件工作流鉤子和其它鉤子。這些鉤子通常儲存在專案的.git/hooks目錄下,我們需要關注的主要是提交工作流鉤子。提交工作流鉤子主要包括了以下四種:

  • pre-commit:該鉤子在鍵入提交資訊前執行。 它用於檢查即將提交的快照。如果該鉤子以非零值退出,Git 將放棄此次提交,你可以利用該鉤子,來檢查程式碼風格是否一致。
  • prepare-commit-msg:該鉤子在啟動提交資訊編輯器之前,預設資訊被建立之後執行。 它允許你編輯提交者所看到的預設資訊。 
  • commit-msg:該鉤子接收一個引數,此引數存有當前提交資訊的臨時檔案的路徑。 如果該鉤子指令碼以非零值退出,Git 將放棄提交,因此,可以用來在提交通過前驗證專案狀態或提交資訊。
  • post-commit:該鉤子一般用於通知之類的事情。

    在上面的鉤子中,我們需要關注pre-commit和commit-msg鉤子。

2.2 什麼是husky

    husky是常見的git hook工具,使用husky可以掛載Git鉤子,當我們本地進行git commit或git push等操作前,能夠執行其它一些操作,比如進行ESLint檢查,如果不通過,就不允許commit或push。

2.3 安裝husky

    安裝husky,可以使用npm進行安裝。

npm install husky --save-dev

2.4 配置husky

    安裝好husky之後,還需要對husky進行配置。不同版本的husky配置方法有些不同,這裡主要對4.3.8版本的配置進行介紹。

    首先,我們需要先安裝配置好ESLint或Stylelint,並且在package.json中加入以下程式碼。

"husky": {
  "hooks": {
    "pre-commit": "eslint src/**/*.{js,jsx,ts,tsx}",
  }
 }

    接著,當我們執行git commit時,就會觸發pre-commit鉤子,並且執行對應命令,這裡將會指定目錄下的檔案進行ESLint檢查,如果ESLint檢查不通過,是無法進行commit的。

    

    如果ESLint檢查通過,就可以正常進行commit。

    

    在安裝並配置好husky之後,如果發現在commit時不能觸發pre-commit,可以試著重新安裝husky,並且重啟VSCode。

2.5 只使用husky的問題

    使用husky雖然能夠幫助我們在commit或push前執行一些指令,但是如果只使用husky,仍然存在下面這些問題:

  • 在某次提交時,我們只修改了某個檔案,但是隻使用husky會把所有的檔案都執行一遍Lint檢查,時間成本太高。此外,有些專案會在中途才加上husky,但是在commit時husky也會對其它未修改的歷史程式碼進行檢查,可能會一下子報了很多錯誤,這個時候我們更希望只對當前修改過的檔案進行檢查,而不是對專案中的程式碼都進行檢查。
  • husky的鉤子只能執行一個指令,但是有時候我們希望能夠在git commit之前執行多個指令,比如執行ESLint、Stylelint或Commitlint等操作。

    為了解決上面的問題,就需要結合Lint-staged一起使用。

 

3. Lint-staged

    接下來,將會對Lint-staged的安裝和配置進行介紹。

3.1 什麼是Lint-staged

    Lint-staged可以在git staged階段的檔案上執行Linters,簡單說就是當我們執行ESlint或Stylelint命令時,可以通過設定指定只檢查我們通過git add新增到暫存區的檔案,可以避免我們每次檢查都把整個專案的程式碼都檢查一遍,從而提高效率。

    其次,Lint-staged允許指定不同型別字尾檔案執行不同指令的操作,並且可以按步驟再額外執行一些其它shell指令。

3.2 安裝Lint-staged

    安裝Lint-staged,可以使用npm進行安裝。

npm install lint-staged --save-dev

3.3 配置Lint-staged

    安裝好了Lint-staged之後,就需要配置Lint-staged。我們可以在package.json中加入以下程式碼,這裡需要先安裝配置好husky,ESLint和Stylelint。

"husky": {
  "hooks": {
    "pre-commit": "lint-staged",
  }
},
"lint-staged": {
  "*.vue": [
    "eslint --fix",
    "stylelint --fix",
    "git add"
  ],
  "*.{js,jsx,ts,tsx}": [
    "eslint --fix",
    "git add"
  ],
  "*.{htm,html,css,sss,less,scss,sass}": [
    "stylelint --fix",
    "git add"
  ]
}

    當我們執行git commit時,就會觸發husky的pre-commit鉤子,呼叫lint-staged命令。而lint-staged包含了對*.vue,*.{js,jsx,ts,tsx},*.{htm,html,css,sss,less,scss,sass}型別檔案的操作。以*.vue為例,當匹配到字尾名為.vue的檔案時,就會分別執行以下操作:

  • 首先會執行eslint --fix命令,對.vue檔案執行ESLint檢查,並且自動修復一些JS格式問題
  • 接著會執行stylelint --fix命令,對.vue檔案的CSS執行Stylelint檢查,並且自動修復一些CSS格式問題
  • 最後,若前面的指令都執行通過,那麼將通過git add命令將檔案重新加入到本地的git commit中,如果沒有執行通過,那麼將不能commit

 

4. Commitlint

      除了在commit前對JS和CSS執行ESLint和Stylelint檢查之外,也可以對Commit Message進行檢查。接下來,將會介紹Commitlint的安裝和配置方法。

4.1 什麼是Commitlint

    在使用Git提交程式碼時,通常都需要填寫提交說明,也就是Commit Message。在前面的文章中,已經介紹瞭如何使用Commitizen或視覺化工具編寫符合規範的Commit Message。然而有些同學可能還是會使用git commit方式提交一些不符合規範的Commit Message。為了禁止不符合規範的Commit Message的提交,我們就需要採用一些工具,只有當開發者編寫了符合規範的Commit Message才能夠進行commit。而Commitlint就是這樣一種工具,通過結合husky一起使用,可以在開發者進行commit前就對Commit Message進行檢查,只有符合規範,才能夠進行commit。

4.2 安裝Commitlint

    使用npm安裝Commitlint相關依賴包。

npm install @commitlint/cli @commitlint/config-conventional --save-dev

4.3 配置Commitlint

    安裝好Commitlint之後,就需要配置Commitlint,可以在根目錄建立commitlint.config.js檔案進行配置。

    

    在comminlint.config.js中加入以下程式碼,表示使用config-conventional規範對提交說明進行檢查。具體的規範配置可以檢視:https://github.com/conventional-changelog/commitlint

module.exports = { extends: ['@commitlint/config-conventional'] };

    接下來,需要在package.json中加入commit-msg鉤子。

"husky": {
  "hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" } }

    配置好了之後,當我們進行git commit時,就會觸發commit-msg鉤子,執行commintlint命令,並且讀取commitlint.config.js中的規則對我們的提交說明進行檢查,如果校驗不通過,將不能提交。

 

5. Git檢查工作流

    在介紹完Husky,Commitlint和Lint-staged之後,接下來,我們就可以將這幾個工具結合起來,打造完整的Git檢查工作流。下面給出了一份示例程式碼,其中,該專案採用了Vue-cli進行構建,下面是該專案對應的package.json檔案。

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@commitlint/cli": "^12.1.4",
    "@commitlint/config-conventional": "^12.1.4","@vue/cli-plugin-babel": "^4.5.0",
    "@vue/cli-plugin-eslint": "^4.5.0",
    "@vue/cli-service": "^4.5.0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-vue": "^6.2.2",
    "husky": "^4.3.8",
    "less": "^3.0.4",
    "less-loader": "^5.0.0",
    "lint-staged": "^11.0.0",
    "prettier": "^2.2.1",
    "stylelint": "^13.13.1",
    "stylelint-config-prettier": "^8.0.2","stylelint-config-standard": "^22.0.0",
    "stylelint-order": "^4.1.0",
    "stylelint-webpack-plugin": "^2.2.2",
    "vue-template-compiler": "^2.6.11"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "lint-staged": {
"*.vue": [
"vue-cli-service lint",
"stylelint --fix",
"git add"
],
"*.{js,jsx,ts,tsx}": [
"vue-cli-service lint"
"git add"
],
"*.{htm,html,css,sss,less,scss,saas}":[
"stylelint --fix"
"git add"
]
}
}

     配置好package.json之後,當我們進行git commit提交時,首先將會觸發pre-commit鉤子,呼叫lint-staged命令,並且會對不同字尾的檔案執行不同的檢查。接著,還將會觸發commit-msg鉤子,呼叫commitlint對我們的提交說明進行檢查。如果其中一個無法通過檢查,將無法提交。

    

    當校驗通過時,就可以放心的將程式碼提交到程式碼倉庫中,而不用再擔心程式碼風格等問題啦~

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

 

 

 

 

 

相關文章