ESLint Stylistic使用方法

前言

ESLint 是一個 JavaScript 和 TypeScript 的靜態程式碼分析工具。它可以幫助開發者找出並修正程式碼中的問題,例如語法錯誤、風格不一致、潛在的 bug 等。ESLint 透過可配置的規則來檢查程式碼,讓團隊能夠維持一致的程式碼品質和風格。

Eslint 從2013年開始到現在,網路上流傳很多版本的安裝方式,從筆者 2020 年踏入前端領域開始的 v6.8.0 一直到現在的 v9.28.0 ,幾乎可以說每一次改版都是一個非常大的改動,為了能夠兼容每次大改版的配置,設定檔的寫法也越來越複雜,導致其實入門難度不低,有些人成功甚至是靠運氣,剛好排列組合對了,會跳通知了就以為安裝成功,但其實不然(望向筆者前同事們的專案…

而在 v7 版官方其實有一個宏大的目標,就是移除現有的傳統配置,改為扁平配置(flat),並且移除格式化功能,讓 Eslint 回歸 Eslint,如果要格式化請使用 Prettier,如此一來 關注點分離 Eslint 不再需要管理格式化、配置設定變簡單了,更好入手了…嗎?

實際上並不然,因為整體破壞性改動太大 官方甚至在 5/21 的這份文章中 ESLint v9.0.0: A retrospective 寫到以下幾點

  1. 太多重大的破壞性改動同時發布,導致使用者在升級時遭遇錯,找到真正的問題並排除。尤其是在新的 flat 設定檔以及規則改動上,如果同時遭遇問題無法輕易判斷是設定檔的問題還是新規則的問題。
  2. 文件過多,但協助的工具過少:
    開發團隊認為,文件寫的相當詳細,使用者只要一步一步照著做就能夠完成此次升級,但他們卻忘了絕大多數的開發者並沒有這麼多時間閱讀文件,導致文件沒發會真正的效果,也沒有其他的工具可以協助開發者。
  3. 生態系迭代速度緩慢
    開發團隊即便很早就開始與生態系相關的團隊溝通,但多數的開發者其實都是到 v9 beta階段才開始進行迭代適配,以至於生態系的適配程度遠不及 v8.57 版本

第一點的問題,我在 2023 Vueconf Taiwan 聽尤雨溪大神講關於 Vue2 升級至 Vue3團隊遇到的痛,不能說是很像,只能說是一模一樣。

第三點,我認為開源生態就是這樣沒有辦法,以 Eslint 兩大規則標準 airbnb 與 standard 為例,前者因為人力不足(後面會提到),後者因為團隊意見分歧(後面也會提到),以至於到現在這兩個版本實際上都還沒有支持 v9 版的 Eslint。

而筆者在今天這篇文章之前也一樣是使用v8.57,原因是筆者有使用 airbnb 的規則,而相關套件 eslint-config-airbnb-base 仍然維持在 8.57版本,雖有升級 v9 的打算 文章連結,但因為維護人力不足,升級之路遙遙無期。

與 airbnb 比翼的 standard 也因為開發者之間的開發路線分歧 文章連結 ,導致原版的 standard 不再維護,願意繼續維護的開發者則轉向 neostandard 這個分支,而neostandard至今仍未正式release[註一],導致筆者不得不積蓄使用舊版本。

註一:後續 neostandard 開發者稱有取得 standard 作者的同意,未來會將兩線合併,但這已經是 2024 下半年講的事情,現在 2025 都過一半了,我認為暫時還是先不要指望。

今日因為公司新專案準備開始了,因為內容與金流有關,思考之後決定使用 vitest + typescript 進行開發,想說都這樣大破大力了,那乾脆把一直沒碰的 Eslint v9 一起弄一弄好了,於是就有了這一篇。

可能有人會問,那這樣原本的 airbnb 規則怎麼辦?
我只能說跟著大神走就對了

在 Vue 生態系領域有位大神 antfu ,我想有在關注 Vue 開源生態系的對這個人應該都不陌生。過去他曾發表一篇 為什麼我不使用 Prettier 的文章,討論為什麼他不使用 Prettier 作為他開發格式化的工具 为什么我不使用 Prettier

使用套件

typescript

@typescript-eslint/parser

ts-eslint提供的用來解析typescript

@vue/eslint-config-typescript

這邊我們可以看到@vue/eslint-config-typescript 解構出了defineConfigWithVueTs, vueTsConfigs 兩個函式,因為我們要先知道說哪些東西需要另外安裝,哪些已經整合,所以我們就一個一個套件打開來看吧
首先我們打開node_modules/@vue/eslint-config-typescript/dist/index.mjs,可以看到這裡他import幾個套件分別是
typescript-eslint
vue-eslint-parser
eslint-plugin-vue

typescript-eslint

就是typescript-eslint的套件,我們看typescript eslint官方文件會發現,除了typescript-eslint底下還有一個叫做@typescript-eslint/parser的套件,這是用來解析,讓eslint可以讀懂typescript的,但不論哪一個,這兩個都可以不用裝,因為@vue/eslint-config-typescript 已經幫我們整合了

接著我們可以看一下怎麼定義這個套件的規則標準
CONFIG_NAMES,這裡就是所有可以定義的標準,我們可以看一下自己的套件當初的預設值是多少,是vueTsConfigs.recommended,就代表他使用了typescript-eslint推薦的recommended,至於該用哪一種標準,就請各位依照需求設定,而我這邊會使用stylisticTypeChecked
而defineConfigWithVueTs 這就比較複雜,簡單而言就是將你在eslint.config.ts當中寫的設定轉成扁平化的結構

vue-eslint-parser

這個大家應該也都不陌生就是提供eslint解析 vue 的 template、script的結構,可以試試看把pluginVue、vueTsConfigs都註解掉(兩者底層依賴vue-eslint-parser),會發現.vue檔會出現紅字

eslint-plugin-vue

提供 eslint 有關 vue 的校驗規則,其中 eslint-plugin-vue 有提供多種等級的規則,包含”Base Rules”、”Strongly Recommended”、”Strongly Recommended”
這裡我們可以看到,@vue/eslint-config-typescript 所提供的是 “flat/base”,意思就是提供最基本的校驗

再裝一次 eslint-plugin-vue

為什麼上面 @vue/eslint-config-typescript 已經有安裝 eslint-plugin-vue,我們還需要另外再安裝呢?
理由是 @vue/eslint-config-typescript 所提供的是 base rule,僅提供最基本的vue校驗,這遠遠不能滿足我們的需求
@vue/eslint-config-typescript這個套件也沒有提供任何的接口允許我們去調整他的 eslint-plugin-vue rule level
因此我們需要另外自行安裝 eslint-plugin-vue ,不可以單純依賴@vue/eslint-config-typescript 提供的。

需自行安裝的套件

vite-plugin-eslint

vite-plugin-eslint 不要裝已經沒人維護

jiti

vue官方提供的eslint設定檔為 ts 所以預設會安裝jiti

@eslint/js

原本的eslint 針對javascript的驗證規則,如果沒有需要支援js的話可以不用安裝,但因為我的專案會有其他人接手,不確定其他人會不會撰寫typescrpit的情況下,我打算先安裝

globles

這個套件如果沒有安裝”@eslint/js”的話不需要安裝,這主要提供eslint 在驗證global函數比如window、node時不要報錯

globles 不用安裝也可以,因為他本身就作為eslint的依賴套件之一
但globles的官方文件寫道It’s just a JSON file, so you can use it in any environment.
This package is used by ESLint 8 and earlier. For ESLint 9 and later, you should depend on this package directly in your ESLint config.
所以我們還是手動安裝下來吧

stylistic

過去的eslint 是可以藉由格式化取代部分prettier 的功能,但在v8.57版本,eslint 開發團隊考量因為過去開發流程上的問題導致eslint 過於臃腫,且過多的配置方法導致配置不易,因此開發團隊在v9版本做了大量的破壞性改動,不只原本的配置方法改為扁平式配置,其中最大的改動莫過於移除eslint 格式化代碼的功能。

但很多人還是會想利用eslint 格式化,雖然prettier也是一個相當不錯的套件,但本身還是有些問題,比方說本身的 printwidth 強制開發者必須要限制每行的長度,但這本身會造成閱讀上跟程式碼長度上的困難,我想用過的應該都知道我在說什麼,有時候我們認為不要換行比較好看懂,但是 prettier會幫你通通format,反而變得更難閱讀,詳細可以閱讀 antfu大神的這篇文章https://antfu.me/posts/why-not-prettier-zh

也因為這樣而催生出另一個套件”stylistic”,簡單說就是格式化的功能被eslint 團隊切出去然後被antfu大神撿起來變成另一個套件,所以現在如果要繼續使用格式化功能就必須安裝這個套件。

原先的stylistic底下是有四個套件可以作選擇

@stylistic/eslint-plugin-ts stylistic 用以支援 ts的擴充套件
@stylistic/eslint-plugin-js stylistic 用以支援 js的擴充套件
@stylistic/eslint-plugin-jsx stylistic 用以支援 jsx的擴充套件
@stylistic/eslint-plugin-plus stylistic 額外補充的規則

但在 v5.0 將上述整合成 @stylistic/eslint-plugin,因此之後只要使用@stylistic/eslint-plugin就可以了

擴充功能 ESlint

這個是vscode的擴充套件,如果你沒有安裝的話,紅底線是不會跑出來的,之後也不會套用format on save

安裝完成後在根目錄檔案的.vscode/setting.json當中增下以下設定

1
2
3
4
5
6
7
8
9
10
11
12
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"json"
],

開始安裝

如果不確定可以在專案中新增一個test.js 並且輸入var foo = 1 console.log(foo) 便會發現console報錯
原因是console是屬於瀏覽器的,這時候把 eslint-plugin-vue @vue/eslint-config-typescript 其中一個打開就會發現錯誤不見了
window.alert(“hi”); // browser
process.exit(); // node

啟用 eslint 驗證

“editor.formatOnSave”: false,
“editor.codeActionsOnSave”: {
“source.fixAll”: “explicit”
},
“eslint.validate”: [
“javascript”,
“javascriptreact”,
“typescript”,
“typescriptreact”,
“vue”,
“json”
],

設定檔