紀錄工作經驗、相關知識,解決技術相關問題。

Javascript, 新手 Jamp Holes

ESLint 是什麼?JavaScript 程式碼檢查工具的用途、規則與設定檔入門

ESLint 是什麼?JavaScript 程式碼檢查工具的用途、規則與設定檔入門 特色圖片

ESLint 是什麼? ESLint 是一個檢查 JavaScript 程式碼的工具(Linter):它讀你的原始碼,依照一組規則找出可能的錯誤與不一致的寫法,在程式執行之前就回報。第一次接觸多半是在 React 或 Next.js 專案裡看到 react/require-default-props、jsx-a11y/alt-text 這類警告,或是存檔時編輯器跳出紅色底線,卻不知道訊息從哪來。本文說明 ESLint 的用途、規則(rules)與 off、warn、error 三種嚴重度、設定檔 eslint.config.js 怎麼寫、--fix 能修什麼,以及它跟 Prettier 的分工。

ESLint 是什麼:在執行前找出可疑寫法的 Linter

ESLint 官方文件的定義是:ESLint 是用來辨識並回報 ECMAScript/JavaScript 程式碼中特定模式的工具,目標是讓程式碼更一致、避免錯誤。

這類工具稱為靜態分析(程式不用執行就能檢查)。ESLint 的每一條檢查都是一個規則(rule),例如:

  • no-unused-vars:禁止宣告了卻沒使用的變數。
  • eqeqeq:要求使用 === 與 !==,而不是 == 與 !=。
  • no-undef:使用了沒宣告的變數時回報(下面的範例輸出會看到它)。

ESLint 不會自己決定要檢查什麼。官方文件寫明,除非你 extend 一組共用設定,或在設定檔裡明確開啟規則,否則 ESLint 不會檢查你的程式碼。所以「ESLint 的行為」其實就是「設定檔的內容」。

安裝與建立設定檔

官方的快速開始,是在專案資料夾執行這行指令:

npm init @eslint/config@latest

它會問你幾個問題(例如程式碼跑在瀏覽器還是 Node.js),回答完會在專案目錄產生 eslint.config.js(或 eslint.config.mjs)。官方文件也列出 Node.js 的版本需求:^20.19.0、^22.13.0 或 >=24(以官方 latest 文件為準,版本會隨 ESLint 更新而變)。

檢查檔案的指令是:

npx eslint yourfile.js

如果你是在 VS Code 裡讓 ESLint 存檔時自動修正,安裝擴充套件與設定方式可前往〈使用 VSCode ESLint 進行自動排版,讓coding排版變統一〉,本文只講 ESLint 本身。

設定檔 eslint.config.js:決定檢查什麼

官方文件列出的設定檔檔名有 eslint.config.js、eslint.config.mjs、eslint.config.cjs,以及需要額外設定的 .ts、.mts、.cts 版本。檔案放在專案根目錄,匯出一個「設定物件的陣列」。這種格式稱為 flat config。

下面是一份可以直接放進專案的設定,開啟官方 recommended 規則,再另外指定三條規則:

import { defineConfig } from "eslint/config";
import globals from "globals";
import js from "@eslint/js";

export default defineConfig([
  {
    files: ["**/*.js"],
    languageOptions: { globals: globals.browser },
    plugins: { js },
    extends: ["js/recommended"],
  },
  {
    rules: {
      eqeqeq: "error",
      "no-unused-vars": "warn",
      "prefer-const": "error",
    },
  },
]);

每個設定物件常用的欄位如下:

欄位用途
filesglob 陣列,指定這個設定物件套用到哪些檔案
ignoresglob 陣列,指定不套用的檔案
rules規則物件,鍵是規則名稱,值是嚴重度
languageOptions語言相關設定,例如 globals 宣告瀏覽器或 Node.js 的全域變數

官方文件說明,沒有指定 files 時,ESLint 預設檢查 **/*.js、**/*.cjs、**/*.mjs。node_modules/ 與 .git/ 預設就會被忽略。

js/recommended 會開啟 ESLint 規則頁標示為 recommended 的所有規則,所以上面這份設定裡,沒有寫出來的 no-undef 也會生效。

規則嚴重度:off、warn、error

每條規則要設定嚴重度,官方有三種,文字與數字都可以:

寫法意義
"off" 或 0關閉規則
"warn" 或 1以警告開啟,不影響 exit code
"error" 或 2以錯誤開啟,觸發時 exit code 為 1

規則如果有額外選項,改用陣列寫法,陣列第一項永遠是嚴重度,例如 eqeqeq: ["error", "always"]("always" 是 eqeqeq 的預設選項,要求所有情況都用 ===)。官方文件也說,規則通常會設成 error,用在持續整合(CI)、commit 前檢查與 pull request 合併前,因為這樣會讓 ESLint 以非零的 exit code 結束,流程才會被擋下來。

實際執行:看輸出與 exit code

用上面那份設定,對下面這個 sample.js 執行 ESLint:

let limit = 10;
let total = 0;
const unused = 5;

function add(a, b) {
  if (a == b) {
    console.log("same");
  }
  return a + b + count;
}

total = add(1, 2);
console.log(total);
ESLint v9.39.5、Windows 11 以 flat config 檢查 sample.js 的輸出:no-unused-vars 兩個警告、prefer-const、eqeqeq、no-undef 三個錯誤,exit code 為 1(圖中為指令輸出內容)

輸出裡每一行由左到右是「行:欄、嚴重度、訊息、規則名稱」,規則名稱就是你要到設定檔調整或查官方規則頁的關鍵字。這份輸出共 5 個問題:

  • limit 與 unused 宣告後沒使用:no-unused-vars,我們設成 warn,所以是警告。
  • limit 從未重新指派:prefer-const,設成 error。
  • a == b:eqeqeq,設成 error。
  • count 沒有宣告:no-undef,來自 js/recommended。

最後一行 1 error and 0 warnings potentially fixable with the --fix option 表示有 1 個問題可以自動修,下一節說明。

exit code:警告不會讓指令失敗

官方文件的 exit code 定義:0 是檢查成功且沒有 lint 錯誤;1 是至少有一個錯誤,或警告數超過 --max-warnings;2 是設定問題或內部錯誤。只有警告的檔案會是 0,要把警告也當成失敗,要加 --max-warnings:

ESLint v9.39.5、Windows 11 檢查只有一個警告的 warn.js:不加參數 exit code 為 0,加 --max-warnings 0 後輸出 ESLint found too many warnings 且 exit code 為 1(圖中為指令輸出內容)

在 CI 或 pre-commit 腳本裡用 exit code 判斷成敗,所以「警告」適合用在你想看到、但不想擋住流程的規則。

–fix:自動修正能修的問題

官方文件對 --fix 的說明是:嘗試盡可能修正多的問題,修改直接寫進檔案,輸出只剩下無法修正的問題。

npx eslint sample.js --fix
ESLint v9.39.5、Windows 11 對 sample.js 執行 --fix 後的輸出與檔案內容:第 1 行 let 被改成 const,其餘 eqeqeq、no-undef 與兩個警告仍需手動處理(圖中為指令輸出內容)

結果:prefer-const 的問題被自動修好,let limit 變成 const limit;其餘 4 個問題還在。ESLint 規則頁用扳手圖示標示「部分問題可用 --fix 修正」的規則,沒有標示的規則,例如這裡輸出中未列入可修正的 eqeqeq 與 no-undef,只回報問題,要自己決定怎麼改。所以 --fix 是方便工具,不是把整份程式碼自動改對。

不想檢查某一行:eslint-disable

官方文件提供註解停用規則。下面這行用 eslint-disable-next-line 只停用下一行的 eqeqeq:

const a = 1;
const b = "1";
// eslint-disable-next-line eqeqeq
console.log(a == b);

這段檢查時沒有任何輸出,exit code 為 0;拿掉註解那行,同一份程式碼會出現 Expected '===' and instead saw '=='。官方也提醒,單獨寫 /* eslint-enable */ 而不指定規則,會把所有已停用的規則重新開啟。停用規則要節制,每次用都代表你在繞過一條規則。

ESLint 與 Prettier:檢查品質與排版是兩件事

很多新手教學把 ESLint 當成「自動排版工具」,但 ESLint 的核心是找出可能的錯誤。ESLint 官方部落格宣布:從 v8.53.0 起,正式棄用空白、分號、字串格式這類只管程式碼外觀的格式化規則,並建議改用程式碼格式化工具(Formatter),例如 Prettier。

實務上的分工:

工具負責
ESLint找可能的錯誤與可疑寫法,例如未使用變數、==、未宣告變數
Prettier 等格式化工具統一縮排、換行、引號等外觀

ESLint 若要自行處理格式,官方部落格另外提到 @stylistic/eslint-plugin 系列套件。

.eslintrc 與 eslint.config.js:舊教學的差別

網路上很多舊教學還在教建立 .eslintrc、.eslintrc.json、.eslintrc.js,這是舊的設定格式,官方稱為 eslintrc。官方遷移文件寫明:flat config(eslint.config.js)自 ESLint v9.0.0 起是預設格式。ESLint v9 還能用環境變數 ESLINT_USE_FLAT_CONFIG 設為 false 暫時啟用舊格式,但 ESLint v10.0.0 的遷移文件寫明 eslintrc 已不再支援。

照舊教學做出現「找不到 eslint.config.js」之類的錯誤時,多半是版本與設定格式對不上。舊格式要搬到 flat config,官方提供 npx @eslint/migrate-config .eslintrc.json 這個設定遷移工具。

常見規則警告:在專案裡看到的訊息

專案裡常看到的 ESLint 訊息,通常來自「規則名稱/外掛名稱」:

官方文件說明,外掛的規則名稱是「外掛命名空間/規則名稱」,例如 example/rule1 來自名為 eslint-plugin-example 的外掛;要使用外掛規則,設定檔必須先在 plugins 載入該外掛。

ESLint 重點整理

項目說明
定位靜態檢查 JavaScript 程式碼的 Linter,找可能的錯誤與不一致
設定檔專案根目錄的 eslint.config.js(flat config),匯出設定物件陣列
預設行為沒有 extend 共用設定、也沒開規則時不會檢查任何東西
嚴重度off/0、warn/1(不影響 exit code)、error/2(exit code 為 1)
--fix只修可自動修正的規則,其餘仍需手動處理
停用規則// eslint-disable-next-line 規則名稱
與格式化的關係格式化規則已棄用,排版交給 Prettier 之類的工具
舊設定格式.eslintrc* 是舊格式,v9.0.0 起預設為 flat config

參考資料與延伸閱讀

發佈留言