使Prettier一鍵格式化WXSS(下集)

本文將會結合 ESLint、Prettier、husky、lint-stage、gulp.js 等工具使得項目一鍵化操做,減小在格式化、代碼檢查等操做上浪費時間,由於大前端真的太多東西學了,不學會「偷懶」的話,咱們就要落後更多了。css

本系列文章的示例 Demo 在這裏 👉 GitHub: wechat_applet_demohtml

分爲三篇文章介紹:前端

上一篇文章介紹瞭如何一鍵格式化 wxss 文件。git

今天介紹利用 Git Hooks 鉤子實現提交代碼自動執行此前的 ESLint、Prettier 命令,以保證咱們提交的代碼是不醜的。github

1、Git 鉤子

Git 提供了一些鉤子,能在特定的重要操做發生時觸發自定義腳本。npm

當咱們執行 git init 初始化一個 Git 版本庫時,Git 會默認在 .git/hooks 目錄中放置一些示例腳本(Shell 腳本)。這些示例腳本都是以 .sample 結尾,若是你想啓用它們,得先移除這個後綴。json

把一個正確命名(不帶擴展名)且可執行的文件放入 .git/hooks 目錄下,便可激活該鉤子腳本。 這樣一來,它就能被 Git 調用。gulp

2、經常使用鉤子

  • pre-commit

該鉤子在鍵入提交信息前運行。 它用於檢查即將提交的快照,例如,檢查是否有所遺漏,確保測試運行,以及覈查代碼。 若是該鉤子以非零值退出,Git 將放棄這次提交,不過你能夠用 git commit --no-verify 來繞過這個環節。 你能夠利用該鉤子,來檢查代碼風格是否一致、尾隨空白字符是否存在,或新方法的文檔是否適當等等。segmentfault

3、husky

husky 是一個爲 Git 客戶端增長 hook 的工具。當其安裝到所在倉庫時,它會自動在 .git/hooks 增長相應的鉤子實如今 pre-commit 階段就執行一系列保證每個 commit 的正確性。數組

固然,pre-commit 階段執行的命令,固然要保證其速度不要太慢,每次 commit 都等好久也不是好的體驗。

1. 安裝 npm-run-all

它用於同步或者並行執行 npm script 腳本。

$ yarn add --dev npm-run-all@4.1.5

因而乎,結合以前的 npm script,再經過 npm-run-all 來把幾個命令串起來。

{
  "scripts": {
    "format:all": "npm-run-all -p prettier:wxss:acss prettier:fix -s eslint:fix"
  }
}

這行命令作了什麼:首先並行執行 prettier:wxss:acssprettier:fix 兩個命令,等到執行完以後纔會執行 eslint:fix 命令。

  • npm-run-all -p 表示並行操做。
  • npm-run-all -s 表示按順序操做。
  • 它同時提供了上面兩條命令的簡寫版 API,分別對應 run-prun-s

由於 prettier:wxss:acssprettier:fix 匹配的文件沒有重合的,因此能夠並行操做。至於爲何先進行 Prettier 格式化,再進行 ESLint 檢查,由於它們兩個是存在衝突的。

雖然咱們能夠在 .eslintrc.js 引入相關插件進行配置,使其當 Prettier 規則不符合 ESLint 規則時進行報錯提醒,但沒有解決咱們的痛點,它須要咱們手動去修復。

還有,老是可能會存在先執行 ESLint,再進行 Prettier 的狀況。因此我就想着整合這個腳本,使其按照咱們預期方向走:當二者有衝突的狀況時,採用 ESLint 的規則。

完整腳本以下:

{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "eslint": "eslint ./ --ext .js",
    "eslint:fix": "eslint --fix ./ --ext .js",
    "prettier:fix": "prettier --config .prettierrc.js --write './**/*.{js,css,less,scss,json}'",
    "prettier:wxss": "gulp wxss",
    "prettier:acss": "gulp acss",
    "prettier:wxss:acss": "gulp all",
    "format:all": "npm-run-all -p prettier:wxss:acss prettier:fix -s eslint:fix"
  }
}
2. 安裝 husky
$ yarn add --dev husky@4.3.0

package.json 添加配置,使其在進行 git commit -m 'xxx' 代碼提交時,進行格式化操做,以保證咱們提交的代碼是不醜的。

若是過程當中出現錯誤(如 ESLint 校驗不經過),將會中止 commit 操做,即 pre-commit 返回非零結果以退出。

它能夠經過 git commit --no-verify 命令進行忽略。

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "yarn run format:all"
    }
  }
}
3. 看效果

咱們隨便修改一個文件,而後進行提交。如圖,能夠看到是按照預期執行的,好了。
🎉

4、lint-staged

看到上面的結果,彷佛一切順利。但沒有完...

從上圖咱們看出來,咱們只提交了一個文件的變更,可是它對全部文件進行了掃描,這裏是存在體驗性問題的。

假如咱們有 N 多個暫存文件,那麼每當咱們 git commit 一次就全部檢查全部文件一遍,這致使咱們的體驗很是很差,過程很慢,顯然不是咱們想要的。

那麼如何解決呢?咱們須要用到它 👉 lint-staged

$ yarn add --dev lint-staged@10.3.0

自 v3.1 版本開始,能夠有多種不一樣的方式進行配置,這裏很少說。

在項目根目錄建立一個 .lintstagedrc.js 的配置文件,而後經過 --config 或者 -c 指定。

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged --config .lintstagedrc.js"
    }
  }
}
// .lintstagedrc.js
const path = require('path')

module.exports = {
  '*.js': ['prettier --config .prettierrc.js --write', 'eslint --fix --ext .js'],
  '*.json': 'prettier --config .prettierrc.js --write',
  '*.wxss': absolutePaths => {
    // 獲取相對路徑
    // const cwd = process.cwd()
    // const relativePaths = absolutePaths.map(file => path.relative(cwd, file))
    // return `gulp wxss --path ${relativePaths.join(' ')}`

    return 'gulp wxss'
  },
  '*.acss': 'gulp acss'
}
注意,咱們不將路徑做爲命令調用時的參數傳遞。這一點很重要,由於 lint-staged 將爲咱們完成這一點。

lint-staged 採用的是 glob 匹配模式。從上面的配置中,經過匹配不一樣的文件類型執行相應的操做。

*關於 lint-staged 相關使用說明,建議查看官方文檔或者較瘦的這篇文章,我就再也不詳說。

不知道有沒有人好奇,上面 lint-staged 配置文件中,我在匹配 .wxss 文件時採用的是函數形式。

其實這裏是存在一個問題沒解決的,就是在提交 .wxss 暫存文件時,不是隻處理該 .wxss 文件,而是將項目全部的 .wxss 文件(包含未提交至暫存區的 .wxss 文件)。

緣由大概以下:
1️⃣ 在前面我介紹了,因爲 Prettier 沒有解析器去處理 .wxss 擴展名的文件,因此咱們使用了 Gulp.js 經過轉換文件類型的方式去處理。而對應 Gulp 任務是匹配當前項目下全部 .wxss 文件的,使用 gulp.dest(__dirname) 是正常導出到源文件路徑下。

2️⃣ 按照 lint-staged 的思想,只處理提交的暫存文件。意味着咱們在執行 gulp wxss 任務時應該要傳遞一個文件路徑,而後再修改 wxssPrettier 任務,使其既能匹配全部的,也能夠匹配個別或多個的(而非全部).wxss 文件。而後我嘗試了不少幾種方法,都沒能獲得預期效果。

3️⃣ 我踩坑思路大體是:在執行 gulp wxss 時傳遞一個或者多個路徑參數(如上配置文件註釋部分),經過 process.argv 獲取 NPM 腳本參數,接着在 wxssPrettier 任務中對獲取的參數作處理,往 gulp.src() 傳遞一個數組,到這來我以爲思路應該是沒錯的。可是現實是殘酷的,在 gulp.dest() 時導出的路徑老是不對,全部的 .wxss 文件都被導出到項目根目錄下了,這顯然不是咱們想要的結果。

4️⃣ 目前我還沒找到更好的解決方案,歡迎大佬們賜教。

就是由於這個問題,我以爲我這個 wechat_applet_demo 還不是很完美(我有強迫症),若後續有解決方案了,會回來更新的。

有解決方案了,快去看 結局篇

至此

到這裏基本就結束了,但可能還會加入 Commit Message 提交說明的規範,由於一個清晰明瞭的提交說明,可讓人很清楚本次代碼提交的目的或者解決了什麼具體問題。目前使用最廣的應該是 Angular 規範了,比較合理和系統化,並且有配套的工具。能夠看下這篇文章 git commit 規範指南

如有不足之處,歡迎留言指正。

The end.

相關文章
相關標籤/搜索