版本

語言

從 ESLint v9.7.0 開始,您可以透過外掛程式使用其他語言擴充 ESLint。雖然 ESLint 最初是嚴格針對 JavaScript 的程式碼檢查工具,但 ESLint 核心是通用的,可用於檢查任何程式設計語言。每種語言都被定義為一個物件,其中包含檢查檔案所需的所有剖析、評估和遍歷功能。然後這些語言會分佈在外掛程式中,以便在使用者設定中使用。

語言要求

為了建立一種語言,您需要

  1. 一個剖析器。 剖析器是將純文字轉換為資料結構的部分。ESLint 沒有要求資料結構必須採用特定格式,因此您可以使用任何現有的剖析器,或編寫自己的剖析器。
  2. 一個 SourceCode 物件。 ESLint 透過 SourceCode 物件來處理 AST。每個 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) - 傳回指定節點或 Token 位置的方法。這必須符合 ESTree 使用的 loc 結構。
  • getRange(nodeOrToken) - 傳回指定節點或 Token 範圍的方法。這必須傳回一個陣列,其中第一個項目是起始索引,第二個是結束索引。
  • traverse() - 傳回用於遍歷 AST 或 CST 的可迭代物件的方法。迭代器必須傳回實作 @eslint/coreVisitTraversalStepCallTraversalStep 的物件。

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

  • visitorKeys - 僅限於此 SourceCode 物件的訪問者鍵。通常不需要,因為大多數時間都使用 Language#visitorKeys
  • applyLanguageOptions(languageOptions) - 如果您有需要在剖析後套用的特定語言選項,您可以在這個方法中執行。
  • getDisableDirectives() - 傳回程式碼中的任何停用指令。ESLint 使用它來套用停用指令並追蹤未使用的指令。
  • getInlineConfigNodes() - 傳回任何內嵌設定節點。啟用 noInlineConfig 時,ESLint 使用它來回報錯誤。
  • applyInlineConfig() - 將內嵌設定元素傳回 ESLint。ESLint 使用它來變更正在檢查的檔案的設定。
  • finalize() - 這個方法在檢查開始之前被呼叫,是您修改 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。在計算要檢查檔案的設定時,使用者指定的 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"
    }
];

有關更多詳細資訊,請參閱插件設定文件中的 指定語言

變更語言