创建插件

ESLint 插件通过附加功能扩展了 ESLint。在大多数情况下,你将通过创建封装要在多个项目之间共享的附加功能的插件来扩展 ESLint。

¥ESLint plugins extend ESLint with additional functionality. In most cases, you’ll extend ESLint by creating plugins that encapsulate the additional functionality you want to share across multiple projects.

创建插件

¥Creating a plugin

插件是一个 JavaScript 对象,它向 ESLint 公开某些属性:

¥A plugin is a JavaScript object that exposes certain properties to ESLint:

  • meta - 有关插件的信息。

    ¥meta - information about the plugin.

  • configs - 包含命名配置的对象。

    ¥configs - an object containing named configurations.

  • rules - 包含自定义规则定义的对象。

    ¥rules - an object containing the definitions of custom rules.

  • processors - 包含命名处理器的对象。

    ¥processors - an object containing named processors.

首先,创建一个 JavaScript 文件并导出一个包含你希望 ESLint 使用的属性的对象。为了使你的插件尽可能易于维护,我们建议你将插件入口点文件格式化为如下所示:

¥To get started, create a JavaScript file and export an object containing the properties you’d like ESLint to use. To make your plugin as easy to maintain as possible, we recommend that you format your plugin entrypoint file to look like this:

const plugin = {
    meta: {},
    configs: {},
    rules: {},
    processors: {}
};

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

如果你计划将插件作为 npm 包分发,请确保导出插件对象的模块是包的默认导出。这将使 ESLint 在 --plugin 选项.conf 文件中的命令行中指定插件时导入该插件。

¥If you plan to distribute your plugin as an npm package, make sure that the module that exports the plugin object is the default export of your package. This will enable ESLint to import the plugin when it is specified in the command line in the --plugin option.

插件中的元数据

¥Meta Data in Plugins

为了更轻松地调试和更有效地缓存插件,建议在插件根目录下的 meta 对象中提供名称和版本,如下所示:

¥For easier debugging and more effective caching of plugins, it’s recommended to provide a name and version in a meta object at the root of your plugin, like this:

const plugin = {

    // preferred location of name and version
    meta: {
        name: "eslint-plugin-example",
        version: "1.2.3"
    },
    rules: {
        // add rules here
    }
};

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

meta.name 属性应与插件的 npm 包名称匹配,meta.version 属性应与插件的 npm 包版本匹配。完成此操作的最简单方法是从你的 package.json 读取此信息。

¥The meta.name property should match the npm package name for your plugin and the meta.version property should match the npm package version for your plugin. The easiest way to accomplish this is by reading this information from your package.json.

作为替代方案,你还可以在插件的根目录下公开 nameversion 属性,例如:

¥As an alternative, you can also expose name and version properties at the root of your plugin, such as:

const plugin = {

    // alternate location of name and version
    name: "eslint-plugin-example",
    version: "1.2.3",
    rules: {
        // add rules here
    }
};

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

插件中的规则

¥Rules in Plugins

插件可以公开在 ESLint 中使用的自定义规则。为此,插件必须导出一个 rules 对象,其中包含规则 ID 到规则的键值映射。规则 ID 不必遵循任何命名约定,只是它不应包含 / 字符(因此,例如,它可以是 dollar-sign,但不能是 foo/dollar-sign)。要了解有关在插件中创建自定义规则的更多信息,请参阅 自定义规则

¥Plugins can expose custom rules for use in ESLint. To do so, the plugin must export a rules object containing a key-value mapping of rule ID to rule. The rule ID does not have to follow any naming convention except that it should not contain a / character (so it can just be dollar-sign but not foo/dollar-sign, for instance). To learn more about creating custom rules in plugins, refer to Custom Rules.

const plugin = {
    meta: {
        name: "eslint-plugin-example",
        version: "1.2.3"
    },
    rules: {
        "dollar-sign": {
            create(context) {
                // rule implementation ...
            }
        }
    }
};

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

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

¥In order to use a rule 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 rule in the rules configuration, like this:

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

export default [
    {
        plugins: {
            example
        },
        rules: {
            "example/dollar-sign": "error"
        }
    }
];

插件中的处理器

¥Processors in Plugins

插件可以通过提供 processors 对象来公开 processors 以在配置文件中使用。与规则类似,processors 对象中的每个键都是处理器的名称,每个值都是处理器对象本身。这是一个例子:

¥Plugins can expose processors for use in configuration file by providing a processors object. Similar to rules, each key in the processors object is the name of a processor and each value is the processor object itself. Here’s an example:

const plugin = {
    meta: {
        name: "eslint-plugin-example",
        version: "1.2.3"
    },
    processors: {
        "processor-name": {
            preprocess(text, filename) {/* ... */},
            postprocess(messages, filename) { /* ... */ },
        }
    }
};

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

为了在配置文件中使用插件中的处理器,请导入插件并将其包含在 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"
    }
];

插件中的配置

¥Configs in Plugins

你可以通过在 configs 键下指定它们来将配置打包在插件中。当你想要将一组自定义规则与启用推荐选项的配置打包在一起时,这会很有用。每个插件支持多种配置。

¥You can bundle configurations inside a plugin by specifying them under the configs key. This can be useful when you want to bundle a set of custom rules with a configuration that enables the recommended options. Multiple configurations are supported per plugin.

你可以在配置中包含来自插件的单独规则,该配置也包含在插件中。在配置中,你必须在 plugins 对象中指定你的插件名称以及你想要启用的作为插件一部分的任何规则。任何插件规则都必须以插件命名空间为前缀。这是一个例子:

¥You can include individual rules from a plugin in a config that’s also included in the plugin. In the config, you must specify your plugin name in the plugins object as well as any rules you want to enable that are part of the plugin. Any plugin rules must be prefixed with the plugin namespace. Here’s an example:

const plugin = {
    meta: {
        name: "eslint-plugin-example",
        version: "1.2.3"
    },
    configs: {},
    rules: {
        "dollar-sign": {
            create(context) {
                // rule implementation ...
            }
        }
    }
};

// assign configs here so we can reference `plugin`
Object.assign(plugin.configs, {
    recommended: [{
        plugins: {
            example: plugin
        },
        rules: {
            "example/dollar-sign": "error"
        },
        languageOptions: {
            globals: {
                myGlobal: "readonly"
            },
            parserOptions: {
                ecmaFeatures: {
                    jsx: true
                }
            }
        }
    }]
});

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

该插件导出一个 recommended 配置,它是一个包含一个配置对象的数组。当只有一个配置对象时,你还可以仅导出该对象而不使用封闭数组。

¥This plugin exports a recommended config that is an array with one config object. When there is just one config object, you can also export just the object without an enclosing array.

为了在配置文件中使用插件的配置,请导入插件并直接通过插件对象访问配置。假设配置是一个数组,使用扩展运算符将其添加到从配置文件返回的数组中,如下所示:

¥In order to use a config from a plugin in a configuration file, import the plugin and access the config directly through the plugin object. Assuming the config is an array, use the spread operator to add it into the array returned from the configuration file, like this:

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

export default [
    ...example.configs.recommended
];

测试插件

¥Testing a Plugin

ESLint 提供了 RuleTester 实用程序,可以轻松测试插件的规则。

¥ESLint provides the RuleTester utility to make it easy to test the rules of your plugin.

对插件进行代码检查

¥Linting a Plugin

ESLint 插件也应该被检查!建议使用以下 recommended 配置对你的插件进行 lint:

¥ESLint plugins should be linted too! It’s suggested to lint your plugin with the recommended configurations of:

共享插件

¥Share Plugins

为了使你的插件公开可用,你必须将其发布到 npm 上。这样做时,请务必:

¥In order to make your plugin available publicly, you have to publish it on npm. When doing so, please be sure to:

  1. 将 ESLint 列为对等依赖。由于插件旨在与 ESLint 一起使用,因此将 eslint 包添加为对等依赖非常重要。为此,请手动编辑 package.json 文件以包含 peerDependencies 块,如下所示:

    ¥List ESLint as a peer dependency. Because plugins are intended for use with ESLint, it’s important to add the eslint package as a peer dependency. To do so, manually edit your package.json file to include a peerDependencies block, like this:

    {
        "peerDependencies": {
            "eslint": ">=9.0.0"
        }
    }
    
  2. 指定关键字。ESLint 插件应在 package.json 文件中将 eslinteslintplugineslint-plugin 指定为 keywords

    ¥Specify keywords. ESLint plugins should specify eslint, eslintplugin and eslint-plugin as keywords in your package.json file.