iT邦幫忙

2022 iThome 鐵人賽

DAY 23
3
Modern Web

重造會 Slide 的輪子!深入 JavaScript、CSS 模組化設計系列 第 23

Day 23 - 程式碼品質工具:ESLint、StyleLint、Prettier

  • 分享至 

  • xImage
  •  

昨天我們已完成套件的命名,也建立了 GitHub 儲存庫,NPM 套件庫也先把套件要用的名字定下來了,準備開始開發 Slider 套件,不過在這之前還有些開發環境要用的套件要先安裝,這些都是幫助我們維護程式碼、增加佈署效率的工具。

ESLint

這是 JavaScript 程式碼品質管理工具,用來監視專案中程式碼是否有符合定義的規格,當不符合時提示我們進行修正,是開發者必備工具。

由於每個人的 coding 習慣不同,放到 GitHub 上有開發者想要 commit 他的貢獻,發起一個 PR (pull request) 到我們的套件儲存庫中,如果程式碼風格和我們定義的不同,可以在設定 GitHub Action 跑自動化測試時就先擋掉。

總之,這是一個強迫參與專案的每個人都使用同一個程式碼風格的好物。

安裝

npm install eslint --save-dev

--save-dev這個參數,會把安裝的套件規類在 package.json 的開發環境套件參數 devDependencies 中。

初始化

eslint --init

範例:
初始化 ESLint
圖 a: 初始化 ESLint

由於筆者指定了 airbnb 的規則,在提示是否使用「import」時回答 Yes,是否使用「React」時也回答 Yes,於是自動地裝了以下此規格的依賴套件。

"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0",

設定檔

在初始化的階段根據提示的問題選擇,會自動建立設定檔,至於是 JSON、JavaScript、YAML 檔案,決定於
「What format do you want your config to be in?」這個問題。

筆者選擇了 JSON,於是產生了 .eslintrc.json 檔案。

檔案內容:

{
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "plugin:react/recommended",
	"airbnb"
  ],
  "overrides": [
  ],
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": [
    "react",
    "jsx-a11y",
    "import"
  ],
  "rules": {}
}

.eslintrc 檔案接受內容是 JSON 或 YAML。於是把副檔名 .json 去掉,再加上 jsx-a11yimport 這兩個 plugin,就是以上的設定內容。

VSCode 擴充套件

安裝 VSCode (visual studio code) 編輯器的擴充套件,幫助我們在開發時可以即時提醒、立即修正,提高效率。

ESLint 的 VSCode 擴充套件
圖 b: ESLint 的 VSCode 擴充套件

如果您用的編輯器是 VSCode 的話,安裝這個擴充套件,啟用之後它會自動找尋專案根目錄下的 ESLint 設定檔。沒意外的話是開箱即用。

範例:

VSCode 中用 ESLint 修正程式碼
圖 c: VSCode 中用 ESLint 修正程式碼

之前的範例程式碼立即出現錯誤提示,原來是原本的縮排是 4 個空格,而套用 airbn2 規則之後則是 2 個空格。擴充套件更棒的地方是可以自動排版解決檔案中的風格問題。

早期 JavaScript 還沒有 Promise、Await 這些功能的時候,為了執行完某些功能後再呼叫其它功能,而讓程式碼變得非長地長,也就是俗稱的「callback hell」。社群的聲音希望程式碼短些,因此久而久之,JavaScript 文化就變成縮排為 2 個空格,這也是主流的程式碼風格都是如此的原因。

擴充套件無法運作

萬一 NPM 套件裝了,設定檔 .eslintrc 也設好了,VSCode 編輯器的擴充套件也安裝了,但什麼事都沒發生!?

範例:
VSCode 中查看 ESLint 運作情況
圖 d: VSCode 中查看 ESLint 運作情況

由於在 NPM 已裝好 ESLint,初始化 ESLint 設定檔了,裝了擴充套件後沒有正常運作,通常是找不到 ESLint 規則。確認一下 VSCode 編輯器的終端機模式下,ESLint server 輸出 (output) 的訊息,再作修正

StyleLint

StyleLint 和 ESLint 一樣是程式碼品值管理工具,它主要的用途是幫助我們檢查 CSS 的程式碼風格。

必須安裝的套件:

npm install stylelint --save-dev
npm stylelint-config-standard-scss --save-dev

其中 stylelint-config-standard-scss 已經內含了 stylelint-config-standardstylelint-scss 兩個依賴了,所以裝這一個就可以了。

筆者安裝時的版本如下:

"stylelint": "^14.12.1",
"stylelint-config-standard-scss": "^5.0.0",

設定檔內容

StyleLint 和 ESLint 一樣,支援各種格式,例如 JSON、YAML、JavaScript 物件。這邊筆者採用 JSON 格式,檔案內容簡潔好讀。

.stylelintrc

{
  "extends": "stylelint-config-standard-scss",
  "rules": {
    "indentation": 2,
    "at-rule-no-unknown": null,
    "scss/at-rule-no-unknown": true
  }
}

VSCode 擴充套件

不想單靠命令列模式來修正 CSS 語法,使用這個 VSCode 擴充套件就對了。

StyleLint 的 VSCode 擴充套件
圖 e: StyleLint 的 VSCode 擴充套件

安裝之後,會自動尋找專案根目錄的設定檔。對於 CSS 的部分是開箱即用,但對於 SCSS 需要再加上設定。

StyleLint 的 VSCode 設定補上 SCSS 設定
圖 f: VSCode 設定

在 VSCode 的 settings.json 中搜尋 stylelint.validate 再補上 scss 即可。

CSS 屬性排序

另外,有一個很不錯的 StyleLint 外掛「stylelint-order」,它可以幫我們把 CSS 的屬性排序,預設是照首字字母排序,也可以自定義。

安裝:

npm install stylelint-order --save-dev

範例:

在 VSCode 使用 StyleLint 修正程式碼
圖 g: 在 VSCode 使用 StyleLint 修正程式碼

它會自動幫我們修正 CSS 屬性的排序。

設定:

{
  "extends": "stylelint-config-standard-scss",
  "plugins": ["stylelint-order"],
  "rules": {
    "indentation": 2,
    "at-rule-no-unknown": null,
    "scss/at-rule-no-unknown": true,
    "order/order": [
        "custom-properties",
        "declarations"
    ],
    "order/properties-alphabetical-order": true
  }
}

plugns 欄位加入 stylelint-orderrules 也補上相關規則,為 order/ 開頭的欄位。

規則二選一

  • 依字母排序:order/properties-alphabetical-order
  • 依自定義屬性順序來排序:order/properties-order

注意這兩個排序規則,只能擇一使用。而且使用自定義排序後,裡面的列表要補齊,不然會有排序不到的情況發生。

例如官網的範例:

"order/properties-order": [
	"width",
	"height"
]

如果只設這兩個,就這兩個 CSS 屬性 widthheight 會排序而已。

存檔時自動修正

  • ESLint
  • StyleLint

在 VSCode 的 settings.json 中搜尋 editor.codeActionsOnSave,在之中可以加入存檔時自動修正程式碼的功能。

設定值:

"editor.codeActionsOnSave": {
	"source.fixAll.eslint": true,
	"source.fixAll.stylelint": true
},

為了方便起見,兩種都可以設定存檔時自動修正程式碼,如此一來日積月累,可以節省很多寶貴的時間。

Prettier

Prettier 是用來排版程式碼,如果不符合規則,就會提示錯誤,使用 Prettier 修正程式碼,會自動排版成符合設定檔規則的程式碼風格。

因此同時使用 ESLint 和 Prettier,會發生 Prettier 修正過的程式碼,ESLint 提示錯誤,用 ESLint 修正後,Prettier 又出現錯誤的衝突情況。那既然如此,為什時很多開發者們會同時使用這兩種?Prettier 在程式碼排版上更好用會是主要原因,第二個原因是兩者的規格在解決衝突後,能夠互補。

實務上,我們通常會使用 ESLint 作為程式碼檢查,Prettier 用來排版程式碼。

安裝主套件

npm install prettier --save-dev

安裝 ESLint 外掛

npm install eslint-plugin-prettier  --save-dev

這個外掛套件用來解決兩者之間衝突的地方。

ESLint 設定檔

.eslintrc 中,plugins 欄位加入 prettier

"plugins": [
	"prettier"
]

rules 欄位加入以下規則。

"rules": {
	"prettier/prettier": "error"
}

Prettier 規則檔

把需要調整的規則,以 JSON 格式,放進 .prettierrc 檔案中。

例如:

{
  "arrowParens": "always",
  "bracketSpacing": false,
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "jsxBracketSameLine": false,
  "printWidth": 100,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "endOfLine": "auto",
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "useTabs": false
}

主要的檢查雖然是 ESLint 的工作,但是這一份 Prettier 規格檔可用來統整最後決定的程式碼風格。

設定值一覽表

選項 說明
printWidth 例:100 換行的字元數
tabWidth" 例:2 程式碼縮排的字元數
useTabs true / false 設為 false 使用空格縮排,true 使用 TAB
semi true / false 行尾是否加上分號
singleQuote true / false 是否只使用單引號
proseWrap preserve 預設值
arrowParens avoid / always 箭頭函式只有一個參數時,是否要有括號
bracketSpacing true / false 在物件中,大括號語字串之間是否加上空格,例如:{ foo: bar }
disableLanguages ["vue"] 不格式化 vue 檔案
endOfLine auto 结尾是 \n \r \n\r auto
eslintIntegration true / false 設為 false 時,Prettier 不使用 ESLint 的規則進行檢查
htmlWhitespaceSensitivity strict / css / ignore 是否對 HTML 的空白敏感,例如換行
ignorePath .prettierignore 不使用 Prettier 的檔案路徑列表放在 .prettierignore 檔案中
jsxBracketSameLine true / false 在 jsx 中把是否把 > 獨立放一行
jsxSingleQuote true / false 在 jsx 中把是否把單引號取代雙引號
parser babylon 格式話的解析器,預設值
stylelintIntegration true / false 設為 false 時,Prettier 不使用 StyleLint 的規則進行檢查
trailingComma es5 / none / all 是否在陣列或物件的最後一行後面加上逗號
tslintIntegration true / false 設為 false 時,Prettier 不使用 TsLint 的規則進行檢查

範例:

在 VSCode 使用 Prettier 修正程式碼
圖 h: 在 VSCode 使用 Prettier 修正程式碼

設定之後 Prettier 會接手 ESLint 的工作,幫程式碼進行排版。上圖是行數字元超過限制進行換行,以及把雙引號換成單引號的排版。

總結

東北有三寶,人蔘、貂皮、烏拉草。前端也有三寶,ESLint、StyleLint、Prettier。(不好笑 XD)

只要善用這三個工具,程式碼就能排版的美美地,在編寫程式的過程中,語法錯誤的提醒,也能避免一些低級失誤發生。

今天的文章沒有實體網站範例,不過之前的範例可在 GitHub Page 閱讀。
原始碼可在 2022 鐵人賽專用 GitHub Repo 下載。


上一篇
Day 22 - 套件命名與建立 Git 儲存庫 (Repository)
下一篇
Day 24 - 程式碼打包工具:Webpack
系列文
重造會 Slide 的輪子!深入 JavaScript、CSS 模組化設計30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言