版本

自訂解析器

ESLint 自訂解析器可讓您擴充 ESLint,以支援程式碼中新的非標準 JavaScript 語言功能或自訂語法。解析器負責接收您的程式碼並將其轉換為抽象語法樹 (AST),然後 ESLint 可以分析和檢查該 AST。

建立自訂解析器

自訂解析器中的方法

自訂解析器是一個 JavaScript 物件,具有 parse()parseForESLint() 方法。 parse 方法僅傳回 AST,而 parseForESLint() 也會傳回額外的值,讓解析器可以進一步自訂 ESLint 的行為。

這兩種方法都應該是實例(自有)屬性,並將原始碼作為第一個引數,以及一個可選的設定物件作為第二個引數,該物件在設定檔中以 parserOptions 提供。

// customParser.js

const espree = require("espree");

// Logs the duration it takes to parse each file.
function parse(code, options) {
    const label = `Parsing file "${options.filePath}"`;
    console.time(label);
    const ast = espree.parse(code, options);
    console.timeEnd(label);
    return ast; // Only the AST is returned.
};

module.exports = { parse };

parse 的回傳物件

parse 方法應該只傳回 AST 物件。

parseForESLint 的回傳物件

parseForESLint 方法應傳回一個物件,其中包含必要屬性 ast 和可選屬性 servicesscopeManagervisitorKeys

  • ast 應該包含 AST 物件。
  • services 可以包含任何依賴解析器的服務(例如節點的類型檢查器)。 services 屬性的值可作為規則中的 context.sourceCode.parserServices 使用。預設值為空物件。
  • scopeManager 可以是 ScopeManager 物件。自訂解析器可以使用自訂範圍分析來處理實驗性/增強語法。預設值是 eslint-scope 建立的 ScopeManager 物件。
    • ESLint v4.14.0 中新增了對 scopeManager 的支援。支援 scopeManager 的 ESLint 版本將在 parserOptions 中提供 eslintScopeManager: true 屬性,可用於功能偵測。
  • visitorKeys 可以是一個物件,用於自訂 AST 遍歷。物件的鍵是 AST 節點的類型。每個值都是應該遍歷的屬性名稱陣列。預設值是 eslint-visitor-keys 的 KEYS
    • ESLint v4.14.0 中新增了對 visitorKeys 的支援。支援 visitorKeys 的 ESLint 版本將在 parserOptions 中提供 eslintVisitorKeys: true 屬性,可用於功能偵測。

自訂解析器中的 Meta 資料

為了更容易偵錯和更有效地快取自訂解析器,建議在您的自訂解析器根目錄的 meta 物件中提供名稱和版本,如下所示

// preferred location of name and version
module.exports = {
    meta: {
        name: "eslint-parser-custom",
        version: "1.2.3"
    }
};

meta.name 屬性應該與您的自訂解析器的 npm 套件名稱相符,而 meta.version 屬性應該與您的自訂解析器的 npm 套件版本相符。完成此操作的最簡單方法是從您的 package.json 中讀取此資訊。

AST 規格

自訂解析器應建立的 AST 是基於 ESTree。AST 需要一些關於原始碼詳細資訊的額外屬性。

所有節點

所有節點都必須有 range 屬性。

  • range (number[]) 是兩個數字的陣列。這兩個數字都是從 0 開始的索引,即原始碼字元陣列中的位置。第一個是節點的起始位置,第二個是節點的結束位置。 code.slice(node.range[0], node.range[1]) 必須是節點的文字。此範圍不包含節點周圍的空格/括號。
  • loc (SourceLocation) 不得為 nullESTree 將 loc 屬性定義為可為 null,但 ESLint 需要此屬性。 SourceLocation#source 屬性可以為 undefined。 ESLint 不會使用 SourceLocation#source 屬性。

所有節點的 parent 屬性必須可重寫。在任何規則存取 AST 之前,ESLint 會在遍歷時將每個節點的 parent 屬性設定為其父節點。

Program 節點

Program 節點必須具有 tokenscomments 屬性。這兩個屬性都是下面 Token 介面的陣列。

interface Token {
    type: string;
    loc: SourceLocation;
    // See the "All Nodes" section for details of the `range` property.
    range: [number, number];
    value: string;
}
  • tokens (Token[]) 是影響程式行為的標記陣列。標記之間可以存在任意空格,因此規則會檢查 Token#range 以偵測標記之間的空格。此陣列必須依 Token#range[0] 排序。
  • comments (Token[]) 是註解標記的陣列。此陣列必須依 Token#range[0] 排序。

所有標記和註解的範圍索引不得與其他標記和註解的範圍重疊。

Literal 節點

Literal 節點必須具有 raw 屬性。

  • raw (string) 是此文字的原始碼。這與 code.slice(node.range[0], node.range[1]) 相同。

封裝自訂解析器

若要將您的自訂解析器發佈到 npm,請執行下列操作

  1. 依照上述「建立自訂解析器」章節建立自訂解析器。
  2. 為自訂解析器建立 npm 套件
  3. 在您的 package.json 檔案中,將 main 欄位設定為匯出自訂解析器的檔案。
  4. 發佈 npm 套件。

如需更多關於發佈 npm 套件的資訊,請參閱 npm 文件

一旦您發佈了 npm 套件,您就可以將該套件新增到您的專案中來使用它。例如

npm install eslint-parser-myparser --save-dev

然後使用 parser 屬性將自訂解析器新增到您的 ESLint 設定檔中。例如

// .eslintrc.js

module.exports = {
  parser: 'eslint-parser-myparser',
  // ... rest of configuration
};

若要深入瞭解如何在您的專案中使用 ESLint 解析器,請參閱 設定解析器

範例

如需自訂解析器的複雜範例,請參閱 @typescript-eslint/parser 原始碼。

一個簡單的自訂解析器,可為規則提供 context.sourceCode.parserServices.foo() 方法。

// awesome-custom-parser.js
var espree = require("espree");
function parseForESLint(code, options) {
    return {
        ast: espree.parse(code, options),
        services: {
            foo: function() {
                console.log("foo");
            }
        },
        scopeManager: null,
        visitorKeys: null
    };
};

module.exports = { parseForESLint };

在 ESLint 設定檔中包含自訂解析器

// .eslintrc.json
{
    "parser": "./path/to/awesome-custom-parser.js"
}
變更語言