語言
從 ESLint v9.7.0 開始,您可以透過外掛程式使用其他語言來擴充 ESLint。雖然 ESLint 最初是嚴格用於 JavaScript 的 linter,但 ESLint 核心是通用的,可用於 lint 任何程式語言。每種語言都定義為一個物件,其中包含 lint 檔案所需的所有解析、評估和遍歷功能。然後,這些語言會在外掛程式中發布,以供使用者設定使用。
語言需求
為了建立語言,您需要
- 解析器。 解析器是將純文字轉換為資料結構的部分。ESLint 沒有規定資料結構必須採用的特定格式,因此您可以使用任何現有的解析器,或編寫您自己的解析器。
SourceCode
物件。 ESLint 使用 AST 的方式是透過SourceCode
物件。每個SourceCode
上都有一些必需的方法,您也可以新增更多您想要向規則公開的方法或屬性。Language
物件。Language
物件包含有關語言本身的資訊,以及用於解析和建立SourceCode
物件的方法。
語言的解析器需求
若要開始使用,請確保您有一個可以從 JavaScript 呼叫的解析器。解析器必須傳回代表已解析程式碼的資料結構。大多數解析器會傳回抽象語法樹 (AST) 來表示程式碼,但它們也可以傳回具體語法樹 (CST)。傳回 AST 或 CST 對 ESLint 而言並不重要,重要的是有一個資料結構可以遍歷。
雖然 AST 或 CST 沒有必須遵循的特定結構,但當樹狀結構中的每個節點都包含以下資訊時,更容易與 ESLint 整合
-
類型 - 每個節點上代表節點類型的屬性是必需的。例如,在 JavaScript 中,
type
屬性包含每個節點的此資訊。ESLint 規則使用節點類型來定義訪問器方法,因此每個節點都可以透過字串識別非常重要。屬性的名稱並不重要(稍後會討論),只要存在即可。此屬性通常由大多數解析器命名為type
或kind
。 -
位置 - 每個節點上代表節點在原始原始碼中位置的屬性是必需的。位置必須包含
- 節點開始所在的行
- 節點開始所在的欄
- 節點結束所在的行
- 節點結束所在的欄
與節點類型一樣,屬性名稱並不重要。兩個常見的屬性名稱是
loc
(如 ESTree 中)和position
(如 Unist 中)。ESLint 使用此資訊來回報錯誤和規則違規。 -
範圍 - 每個節點上代表節點原始碼在原始碼內位置的屬性是必需的。範圍表示找到第一個字元的索引和最後一個字元之後的索引,因此呼叫
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/core
的VisitTraversalStep
或CallTraversalStep
的物件。
以下選用成員可讓您自訂 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"
}
];
如需更多詳細資訊,請參閱外掛程式設定文件中的指定語言。