版本

自定义处理器

您还可以创建自定义处理器,以告知 ESLint 如何处理标准 JavaScript 以外的文件。例如,您可以编写一个自定义处理器来从 Markdown 文件中提取和处理 JavaScript(@eslint/markdown 包括一个用于此目的的自定义处理器)。

自定义处理器规范

为了创建自定义处理器,从您的模块导出的对象必须符合以下接口

const plugin = {

    meta: {
        name: "eslint-plugin-example",
        version: "1.2.3"
    },
    processors: {
        "processor-name": {
            meta: {
                name: "eslint-processor-name",
                version: "1.2.3"
            },
            // takes text of the file and filename
            preprocess(text, filename) {
                // here, you can strip out any non-JS content
                // and split into multiple strings to lint

                return [ // return an array of code blocks to lint
                    { text: code1, filename: "0.js" },
                    { text: code2, filename: "1.js" },
                ];
            },

            // takes a Message[][] and filename
            postprocess(messages, filename) {
                // `messages` argument contains two-dimensional array of Message objects
                // where each top-level array item contains array of lint messages related
                // to the text that was returned in array from preprocess() method

                // you need to return a one-dimensional array of the messages you want to keep
                return [].concat(...messages);
            },

            supportsAutofix: true // (optional, defaults to false)
        }
    }
};

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

preprocess 方法 接受文件内容和文件名作为参数,并返回要 lint 的代码块数组。代码块将被单独 lint,但仍将注册到文件名。

一个代码块有两个属性 textfilenametext 属性是块的内容,filename 属性是块的名称。块的名称可以是任何名称,但应包括文件扩展名,这会告诉 ESLint 如何处理当前块。ESLint 检查项目配置中匹配的 files 条目,以确定是否应 lint 代码块。

是否只需要返回非 JavaScript 文件的一部分或多个部分取决于插件。例如,在处理 .html 文件的情况下,您可能希望通过组合所有脚本在数组中仅返回一个项目。但是,对于 .md 文件,您可以返回多个项目,因为每个 JavaScript 块可能是独立的。

postprocess 方法 接受 lint 消息的二维数组数组和文件名。输入数组中的每个项目对应于从 preprocess 方法返回的部分。postprocess 方法必须调整所有错误的位置,以对应于原始、未处理代码中的位置,并将它们聚合到一个扁平数组并返回它。

报告的问题在每个 lint 消息中都包含以下位置信息

type LintMessage = {

  /// The 1-based line number where the message occurs.
  line?: number;

   /// The 1-based column number where the message occurs.
  column?: number;

  /// The 1-based line number of the end location.
  endLine?: number;

  /// The 1-based column number of the end location.
  endColumn?: number;

  /// If `true`, this is a fatal error.
  fatal?: boolean;

  /// Information for an autofix.
  fix: Fix;

  /// The error message.
  message: string;

  /// The ID of the rule which generated the message, or `null` if not applicable.
  ruleId: string | null;

  /// The severity of the message.
  severity: 0 | 1 | 2;

  /// Information for suggestions.
  suggestions?: Suggestion[];
};

type Fix = {
    range: [number, number];
    text: string;
}

type Suggestion = {
    desc?: string;
    messageId?: string;
    fix: Fix;
}

默认情况下,即使在命令行上启用了 --fix 标志,当使用自定义处理器时,ESLint 也不会执行自动修复。要允许 ESLint 在使用您的处理器时自动修复代码,您应该采取以下附加步骤

  1. 更新 postprocess 方法以额外转换报告问题的 fix 属性。所有可自动修复的问题都有一个 fix 属性,它是一个具有以下模式的对象

    {
        range: [number, number],
        text: string
    }
    

    range 属性包含代码中的两个索引,分别指向要替换的连续文本部分的开始和结束位置。text 属性指向将替换给定范围的文本。

    在问题初始列表中,fix 属性将引用已处理 JavaScript 中的修复。postprocess 方法应转换对象以引用原始的、未处理的文件中的修复。

  2. 向处理器添加 supportsAutofix: true 属性。

您可以在单个插件中同时拥有规则和自定义处理器。您也可以在一个插件中拥有多个处理器。要支持多个扩展名,请将每个扩展名添加到 processors 元素,并将它们指向同一对象。

meta 对象如何使用

meta 对象帮助 ESLint 缓存使用处理器的配置,并提供更友好的调试消息。

插件 meta 对象

插件 meta 对象 提供有关插件自身的信息。当使用字符串格式 plugin-name/processor-name 指定处理器时,ESLint 会自动使用插件 meta 来生成处理器的名称。这是处理器最常见的情况。

示例

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

export default [
    {
        plugins: {
            example
        },
        processor: "example/processor-name"
    },
    // ... other configs
];

在此示例中,处理器名称为 "example/processor-name",这将是用于序列化配置的值。

处理器 meta 对象

每个处理器还可以指定自己的 meta 对象。当处理器对象直接传递到配置中的 processor 时,此信息将被使用。在这种情况下,ESLint 不知道处理器属于哪个插件。meta.name 属性应与处理器名称匹配,meta.version 属性应与您的处理器的 npm 包版本匹配。完成此操作的最简单方法是从您的 package.json 中读取此信息。

示例

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

export default [
    {
        processor: example.processors["processor-name"]
    },
    // ... other configs
];

在此示例中,直接指定 example.processors["processor-name"] 会使用处理器自己的 meta 对象,必须定义该对象以确保在未通过插件名称引用处理器时进行正确处理。

为什么需要两个 Meta 对象

建议插件和每个处理器都提供各自的 meta 对象。这确保了依赖于 meta 对象的功能(例如 --print-config--cache)在配置中如何指定处理器时都能正确工作。

在配置文件中指定处理器

为了在配置文件中使用来自插件的处理器,请导入插件并将其包含在 plugins 键中,指定命名空间。然后,使用该命名空间在 processor 配置中引用处理器,如下所示

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

export default [
    {
        plugins: {
            example
        },
        processor: "example/processor-name"
    }
];

有关更多详细信息,请参阅插件配置文档中的指定处理器

更改语言