語言
從 ESLint v9.7.0 開始,您可以透過外掛程式使用其他語言擴充 ESLint。雖然 ESLint 最初是嚴格針對 JavaScript 的程式碼檢查工具,但 ESLint 核心是通用的,可用於檢查任何程式設計語言。每種語言都被定義為一個物件,其中包含檢查檔案所需的所有剖析、評估和遍歷功能。然後這些語言會分佈在外掛程式中,以便在使用者設定中使用。
語言要求
為了建立一種語言,您需要
- 一個剖析器。 剖析器是將純文字轉換為資料結構的部分。ESLint 沒有要求資料結構必須採用特定格式,因此您可以使用任何現有的剖析器,或編寫自己的剖析器。
- 一個
SourceCode
物件。 ESLint 透過SourceCode
物件來處理 AST。每個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)
- 傳回指定節點或 Token 位置的方法。這必須符合 ESTree 使用的loc
結構。getRange(nodeOrToken)
- 傳回指定節點或 Token 範圍的方法。這必須傳回一個陣列,其中第一個項目是起始索引,第二個是結束索引。traverse()
- 傳回用於遍歷 AST 或 CST 的可迭代物件的方法。迭代器必須傳回實作@eslint/core
的VisitTraversalStep
或CallTraversalStep
的物件。
以下選用成員可讓您自訂 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"
}
];
有關更多詳細資訊,請參閱插件設定文件中的 指定語言。