版本

語言

從 ESLint v9.7.0 開始,您可以透過外掛程式使用其他語言來擴充 ESLint。雖然 ESLint 最初是嚴格用於 JavaScript 的 linter,但 ESLint 核心是通用的,可用於 lint 任何程式語言。每種語言都定義為一個物件,其中包含 lint 檔案所需的所有解析、評估和遍歷功能。然後,這些語言會在外掛程式中發布,以供使用者設定使用。

語言需求

為了建立語言,您需要

  1. 解析器。 解析器是將純文字轉換為資料結構的部分。ESLint 沒有規定資料結構必須採用的特定格式,因此您可以使用任何現有的解析器,或編寫您自己的解析器。
  2. SourceCode 物件。 ESLint 使用 AST 的方式是透過 SourceCode 物件。每個 SourceCode 上都有一些必需的方法,您也可以新增更多您想要向規則公開的方法或屬性。
  3. Language 物件。 Language 物件包含有關語言本身的資訊,以及用於解析和建立 SourceCode 物件的方法。

語言的解析器需求

若要開始使用,請確保您有一個可以從 JavaScript 呼叫的解析器。解析器必須傳回代表已解析程式碼的資料結構。大多數解析器會傳回抽象語法樹 (AST) 來表示程式碼,但它們也可以傳回具體語法樹 (CST)。傳回 AST 或 CST 對 ESLint 而言並不重要,重要的是有一個資料結構可以遍歷。

雖然 AST 或 CST 沒有必須遵循的特定結構,但當樹狀結構中的每個節點都包含以下資訊時,更容易與 ESLint 整合

  1. 類型 - 每個節點上代表節點類型的屬性是必需的。例如,在 JavaScript 中,type 屬性包含每個節點的此資訊。ESLint 規則使用節點類型來定義訪問器方法,因此每個節點都可以透過字串識別非常重要。屬性的名稱並不重要(稍後會討論),只要存在即可。此屬性通常由大多數解析器命名為 typekind

  2. 位置 - 每個節點上代表節點在原始原始碼中位置的屬性是必需的。位置必須包含

    • 節點開始所在的行
    • 節點開始所在的欄
    • 節點結束所在的行
    • 節點結束所在的欄

    與節點類型一樣,屬性名稱並不重要。兩個常見的屬性名稱是 loc(如 ESTree 中)和 position(如 Unist 中)。ESLint 使用此資訊來回報錯誤和規則違規。

  3. 範圍 - 每個節點上代表節點原始碼在原始碼內位置的屬性是必需的。範圍表示找到第一個字元的索引和最後一個字元之後的索引,因此呼叫 code.slice(start, end) 會傳回節點代表的文字。再次強調,不需要特定的屬性名稱,此資訊甚至可以與位置資訊合併。ESTree 使用 range 屬性,而 Unist 將此資訊連同位置資訊一起包含在 position 上。ESLint 使用此資訊來套用自動修復。

SourceCode 物件

ESLint 將原始碼的資訊保存在 SourceCode 物件中。此物件是 ESLint 內部和規則(透過 context.sourceCode)用於處理程式碼的 API。SourceCode 物件必須實作 @eslint/core 套件中定義的 TextSourceCode 介面。

基本的 SourceCode 物件必須實作以下項目

  • ast - 包含原始碼的 AST 或 CST 的屬性。
  • text - 原始碼的文字。
  • getLoc(nodeOrToken) - 傳回給定節點或符號位置的方法。這必須符合 ESTree 使用的 loc 結構。
  • getRange(nodeOrToken) - 傳回給定節點或符號範圍的方法。這必須傳回一個陣列,其中第一個項目是開始索引,第二個項目是結束索引。
  • traverse() - 傳回用於遍歷 AST 或 CST 的可迭代物件的方法。迭代器必須傳回實作來自 @eslint/coreVisitTraversalStepCallTraversalStep 的物件。

以下選用成員可讓您自訂 ESLint 與物件互動的方式

  • visitorKeys - 僅特定於此 SourceCode 物件的訪問器金鑰。通常不是必要的,因為大多數時候都會使用 Language#visitorKeys
  • applyLanguageOptions(languageOptions) - 如果您有需要在解析後套用的特定語言選項,您可以在此方法中執行。
  • getDisableDirectives() - 傳回程式碼中的任何停用指令。ESLint 使用此方法來套用停用指令並追蹤未使用的指令。
  • getInlineConfigNodes() - 傳回任何內嵌設定節點。啟用 noInlineConfig 時,ESLint 使用此方法來回報錯誤。
  • applyInlineConfig() - 將內嵌設定元素傳回給 ESLint。ESLint 使用此方法來變更正在 lint 的檔案的設定。
  • finalize() - 此方法在 lint 開始之前呼叫,並且是您修改 SourceCode 的最後機會。如果您已定義 applyLanguageOptions()applyInlineConfig(),則在 SourceCode 物件準備就緒之前,您可能還有其他變更要套用。

此外,以下成員在 SourceCode 物件上很常見,建議實作

  • lines - 原始碼的個別行,以字串陣列形式表示。
  • getParent(node) - 傳回給定節點的父節點;如果節點是根節點,則傳回 undefined
  • getAncestors(node) - 傳回節點的祖先陣列,其中第一個項目是樹狀結構的根節點,後續每個項目都是根節點的後代,並導向 node
  • getText(node, beforeCount, afterCount) - 傳回代表給定節點的字串,以及(選擇性)節點範圍前後指定數量的字元。

請參閱 JSONSourceCode 作為基本 SourceCode 類別的範例。

Language 物件

Language 物件包含有關程式語言的所有資訊,以及用於與以該語言編寫的程式碼互動的方法。ESLint 使用此物件來判斷如何處理特定檔案。Language 物件必須實作 @eslint/core 套件中定義的 Language 介面。

基本的 Language 物件必須實作以下項目

  • fileType - 應為 "text"(未來,我們也將支援 "binary"
  • lineStart - 0 或 1,表示 AST 如何表示檔案中的第一行。ESLint 使用此方法來正確顯示錯誤位置。
  • columnStart - 0 或 1,表示 AST 如何表示每行中的第一欄。ESLint 使用此方法來正確顯示錯誤位置。
  • nodeTypeKey - 指示節點類型的屬性名稱(通常為 "type""kind")。
  • validateLanguageOptions(languageOptions) - 驗證語言的語言選項。當預期的語言選項沒有正確的類型或值時,此方法應擲回驗證錯誤。應以靜默方式忽略非預期的語言選項,且不應擲回任何錯誤。即使語言未指定任何選項,此方法也是必需的。
  • parse(file, context) - 將給定檔案解析為 AST 或 CST,並且還可以包含用於規則的其他值。由 ESLint 內部呼叫。
  • createSourceCode(file, parseResult, context) - 建立 SourceCode 物件。在 parse() 之後由 ESLint 內部呼叫,第二個引數是 parse() 的確切傳回值。

以下選用成員可讓您自訂 ESLint 與物件互動的方式

  • visitorKeys - 特定於 AST 或 CST 的訪問器金鑰。這用於最佳化 ESLint 內部 AST 或 CST 的遍歷。雖然不是必需的,但強烈建議使用,特別是對於與 ESTree 格式顯著不同的 AST 或 CST 格式。
  • defaultLanguageOptions - 使用語言時的預設 languageOptions。在計算正在 lint 的檔案的設定時,使用者指定的 languageOptions 會與此物件合併。
  • matchesSelectorClass(className, node, ancestry) - 允許您指定選取器類別,例如 :expression,以比對多個節點。每當 esquery 選取器包含 : 後面接著識別碼時,就會呼叫此方法。
  • normalizeLanguageOptions(languageOptions) - 採用經過驗證的語言選項物件並將其值正規化。當語言選項屬性變更時,這有助於向後相容性。

請參閱 JSONLanguage 作為基本 Language 類別的範例。

在外掛程式中發布語言

語言在外掛程式中發布,類似於處理器和規則。在外掛程式中定義 languages 金鑰作為物件,其名稱為語言名稱,值為語言物件。以下範例

import { myLanguage } from "../languages/my.js";

const plugin = {

    // preferred location of name and version
    meta: {
        name: "eslint-plugin-example",
        version: "1.2.3"
    },
    languages: {
        my: myLanguage
    },
    rules: {
        // add rules here
    }
};

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

為了在設定檔中使用外掛程式中的語言,請匯入外掛程式並將其包含在 plugins 金鑰中,指定命名空間。然後,使用該命名空間在 language 設定中參考語言,如下所示

// eslint.config.js
import example from "eslint-plugin-example";

export default [
    {
        plugins: {
            example
        },
        language: "example/my"
    }
];

如需更多詳細資訊,請參閱外掛程式設定文件中的指定語言

變更語言