版本

自定义处理器

您还可以创建自定义处理器,告诉 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 方法接受文件内容和文件名作为参数,并返回一个要检查的代码块数组。代码块将分别进行检查,但仍会注册到文件名。

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

插件需要决定它是否需要返回非 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 对象有助于 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 对象,该对象必须定义才能确保在处理器未通过插件名称引用时正确处理。

为什么需要两个元对象

建议插件和每个处理器都提供它们各自的元对象。这可确保依赖元对象的特性(如 --print-config--cache)无论处理器在配置中如何指定都正常工作。

在配置文件中指定处理器

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

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

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

请参阅插件配置文档中的 指定处理器 以获取更多详细信息。

更改语言