自定义处理器

你还可以创建自定义处理器,告诉 ESLint 如何处理标准 JavaScript 以外的文件。例如,你可以编写一个自定义处理器来从 Markdown 文件中提取和处理 JavaScript(eslint-plugin-markdown 为此包含一个自定义处理器)。

¥You can also create custom processors that tell ESLint how to process files other than standard JavaScript. For example, you could write a custom processor to extract and process JavaScript from Markdown files (eslint-plugin-markdown includes a custom processor for this).

定制处理器规范

¥Custom Processor Specification

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

¥In order to create a custom processor, the object exported from your module has to conform to the following interface:

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 返回代码块数组。代码块将被单独检查,但仍会注册到文件名中。

¥The preprocess method takes the file contents and filename as arguments, and returns an array of code blocks to lint. The code blocks will be linted separately but still be registered to the filename.

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

¥A code block has two properties text and filename. The text property is the content of the block and the filename property is the name of the block. The name of the block can be anything, but should include the file extension, which tells ESLint how to process the current block. ESLint checks matching files entries in the project’s config to determine if the code blocks should be linted.

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

¥It’s up to the plugin to decide if it needs to return just one part of the non-JavaScript file or multiple pieces. For example in the case of processing .html files, you might want to return just one item in the array by combining all scripts. However, for .md files, you can return multiple items because each JavaScript block might be independent.

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

¥The postprocess method takes a two-dimensional array of arrays of lint messages and the filename. Each item in the input array corresponds to the part that was returned from the preprocess method. The postprocess method must adjust the locations of all errors to correspond to locations in the original, unprocessed code, and aggregate them into a single flat array and return it.

报告的问题在每条 lint 消息中具有以下位置信息:

¥Reported problems have the following location information in each lint message:

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;
}

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

¥By default, ESLint does not perform autofixes when a custom processor is used, even when the --fix flag is enabled on the command line. To allow ESLint to autofix code when using your processor, you should take the following additional steps:

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

    ¥Update the postprocess method to additionally transform the fix property of reported problems. All autofixable problems have a fix property, which is an object with the following schema:

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

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

    ¥The range property contains two indexes in the code, referring to the start and end location of a contiguous section of text that will be replaced. The text property refers to the text that will replace the given range.

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

    ¥In the initial list of problems, the fix property will refer to a fix in the processed JavaScript. The postprocess method should transform the object to refer to a fix in the original, unprocessed file.

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

    ¥Add a supportsAutofix: true property to the processor.

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

¥You can have both rules and custom processors in a single plugin. You can also have multiple processors in one plugin. To support multiple extensions, add each one to the processors element and point them to the same object.

meta 对象帮助 ESLint 缓存处理器并提供更友好的调试消息。meta.name 属性应与处理器名称匹配,meta.version 属性应与处理器的 npm 包版本匹配。完成此操作的最简单方法是从你的 package.json 读取此信息。

¥The meta object helps ESLint cache the processor and provide more friendly debug message. The meta.name property should match the processor name and the meta.version property should match the npm package version for your processors. The easiest way to accomplish this is by reading this information from your package.json.

在配置文件中指定处理器

¥Specifying Processor in Config Files

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

¥In order to use a processor from a plugin in a configuration file, import the plugin and include it in the plugins key, specifying a namespace. Then, use that namespace to reference the processor in the processor configuration, like this:

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

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

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

¥See Specify a Processor in the Plugin Configuration documentation for more details.

ESLint 中文网
粤ICP备13048890号