Spec-Zone.ru › ESLint

Создание плагинов

Плагины ESLint расширяют его функциональность. В большинстве случаев вы будете расширять ESLint, создавая плагины, которые объединяют дополнительную функциональность, которой вы хотите делиться между несколькими проектами.

Создание плагина

Плагин — это объект JavaScript, предоставляющий ESLint определённые свойства:

  • meta — сведения о плагине.
  • configs — объект с именованными конфигурациями.
  • rules — объект с определениями пользовательских правил.
  • processors — объект с именованными процессорами.

Для начала создайте файл JavaScript и экспортируйте объект, содержащий свойства, которые должен использовать ESLint. Чтобы плагин было как можно проще поддерживать, рекомендуем оформить его основной файл следующим образом:

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

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

Если вы планируете распространять плагин как пакет npm, убедитесь, что модуль, экспортирующий объект плагина, является экспортом по умолчанию вашего пакета. Это позволит ESLint импортировать плагин, когда он указан в командной строке с помощью опции --plugin.

Метаданные плагинов

Для упрощения отладки и повышения эффективности кэширования плагинов рекомендуется указывать name, version и namespace в объекте meta в корне плагина, например:

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

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

Свойство meta.name должно соответствовать имени npm-пакета вашего плагина, а свойство meta.version — его версии в npm. Свойство meta.namespace должно соответствовать префиксу, который пользователи будут использовать для доступа к правилам, процессорам, языкам и конфигурациям плагина. Обычно пространство имён — это часть имени пакета после eslint-plugin-, поэтому в этом примере используется "example". Указание пространства имён позволяет функции defineConfig() найти ваш плагин, даже если пользователь задаёт другое пространство имён в файле конфигурации.

Проще всего добавить имя и версию, прочитав эти сведения из вашего package.json, как в этом примере:

import fs from "fs";

const pkg = JSON.parse(
	fs.readFileSync(new URL("./package.json", import.meta.url), "utf8"),
);

const plugin = {
	// preferred location of name and version
	meta: {
		name: pkg.name,
		version: pkg.version,
		namespace: "example",
	},
	rules: {
		// add rules here
	},
};

export default plugin;
Совет

Хотя названия плагинов ничем не ограничены, другим пользователям будет проще найти ваш плагин на npm, если вы будете следовать этим соглашениям об именовании:

  • Без области видимости: если имя вашего npm-пакета не будет содержать область видимости (не начинается с @), название плагина должно начинаться с eslint-plugin-, например eslint-plugin-example.
  • С областью видимости: если имя вашего npm-пакета будет содержать область видимости, название плагина должно иметь формат @<scope>/eslint-plugin-<plugin-name>, например @jquery/eslint-plugin-jquery, или даже @<scope>/eslint-plugin, например @jquery/eslint-plugin.

В качестве альтернативы можно также предоставить свойства name и version в корне плагина, например:

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;
Важно

Хотя объект meta является предпочтительным способом указать имя и версию плагина, этот формат также допустим и поддерживается для обратной совместимости.

Правила в плагинах

Плагины могут предоставлять пользовательские правила для использования в ESLint. Для этого плагин должен экспортировать объект rules, содержащий сопоставление идентификаторов правил с правилами. Идентификатор правила не обязан следовать каким-либо соглашениям об именовании, но не должен содержать символ / (поэтому он может быть просто dollar-sign, но не foo/dollar-sign, например). Подробнее о создании пользовательских правил в плагинах см. в разделе Пользовательские правила.

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, например:

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

export default defineConfig([
	{
		files: ["**/*.js"], // any patterns you want to apply the config to
		plugins: {
			example,
		},
		rules: {
			"example/dollar-sign": "error",
		},
	},
]);
Предупреждение

Пространства имён, не начинающиеся с @, не могут содержать /; пространства имён, начинающиеся с @, могут содержать /. Например, eslint/plugin — недопустимое пространство имён, а @eslint/plugin — допустимое. Это ограничение необходимо для обратной совместимости с ограничениями на именование плагинов в eslintrc.

Процессоры в плагинах

Плагины могут предоставлять процессоры для использования в файле конфигурации, предоставляя объект processors. Как и в случае с правилами, каждый ключ объекта processors — это имя процессора, а каждое значение — сам объект процессора. Вот пример:

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, например:

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

export default defineConfig([
	{
		files: ["**/*.txt"],
		plugins: {
			example,
		},
		processor: "example/processor-name",
	},
]);

Конфигурации в плагинах

Вы можете включить конфигурации в состав плагина, указав их в ключе configs. Это может быть полезно, если вы хотите объединить набор пользовательских правил с конфигурацией, включающей рекомендуемые параметры. Один плагин может поддерживать несколько конфигураций.

В конфигурацию, также включённую в плагин, можно добавить отдельные правила из этого плагина. В конфигурации необходимо указать имя плагина в объекте plugins, а также любые правила этого плагина, которые вы хотите включить. Перед всеми правилами плагина должно стоять пространство имён плагина. Вот пример:

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 — массив с одним объектом конфигурации. Если объект конфигурации только один, вместо массива можно экспортировать сам объект.

Чтобы использовать конфигурацию из плагина в файле конфигурации, импортируйте плагин и используйте ключ extends, чтобы указать имя конфигурации, например:

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

export default defineConfig([
	{
		files: ["**/*.js"], // any patterns you want to apply the config to
		plugins: {
			example,
		},
		extends: ["example/recommended"],
	},
]);
Важно

Плагины не могут принудительно включить определённую конфигурацию. Пользователи должны вручную добавить конфигурации плагина в свой файл конфигурации.

Обратная совместимость со старыми конфигурациями

Если плагину нужно экспортировать конфигурации, работающие как с текущей системой (flat config), так и со старой системой (eslintrc), можно экспортировать оба типа конфигураций из ключа configs. Для экспорта старых конфигураций рекомендуем добавлять к их именам префикс "legacy-" (например, "legacy-recommended"), чтобы было понятно, как их следует использовать.

Если вы работаете над плагином, существовавшим до ESLint v9.0.0, возможно, у вас уже есть старые конфигурации с такими именами, как "recommended". Если вы не хотите менять имя конфигурации, можно также создать дополнительную запись в объекте configs с префиксом "flat/" (например, "flat/recommended"). Вот пример:

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, {
	// flat config format
	"flat/recommended": [
		{
			plugins: {
				example: plugin,
			},
			rules: {
				"example/dollar-sign": "error",
			},
			languageOptions: {
				globals: {
					myGlobal: "readonly",
				},
				parserOptions: {
					ecmaFeatures: {
						jsx: true,
					},
				},
			},
		},
	],

	// eslintrc format
	recommended: {
		plugins: ["example"],
		rules: {
			"example/dollar-sign": "error",
		},
		globals: {
			myGlobal: "readonly",
		},
		parserOptions: {
			ecmaFeatures: {
				jsx: true,
			},
		},
	},
});

// for ESM
export default plugin;

// OR for CommonJS
module.exports = plugin;

При таком подходе обе системы конфигурации распознают "recommended". Старая система конфигурации использует ключ recommended, а текущая — ключ flat/recommended. Вспомогательная функция defineConfig() сначала проверяет ключ recommended, а если его формат не подходит, проверяет ключ flat/recommended. Это позволяет постепенно перейти на новую систему, если позднее вы захотите переименовать flat/recommended в recommended, когда поддержка старой системы конфигурации больше не потребуется.

Тестирование плагина

В ESLint есть утилита RuleTester, упрощающая тестирование правил вашего плагина.

Проверка плагина линтером

Плагины ESLint тоже нужно проверять линтером! Рекомендуется проверять плагин с помощью конфигураций recommended для следующих пакетов:

  • eslint
  • eslint-plugin-eslint-plugin
  • eslint-plugin-n

Распространение плагинов

Чтобы сделать плагин общедоступным, его нужно опубликовать в npm. При этом обязательно выполните следующие действия:

  1. Укажите ESLint как одноранговую зависимость. Поскольку плагины предназначены для использования с ESLint, важно добавить пакет eslint в качестве одноранговой зависимости. Для этого вручную отредактируйте файл package.json и добавьте в него блок peerDependencies, например:

    {
    	"peerDependencies": {
    		"eslint": ">=10.0.0"
    	}
    }
    
  2. Укажите ключевые слова. В файле package.json плагины ESLint должны указывать eslint, eslintplugin и eslint-plugin в качестве ключевых слов.

© OpenJS Foundation and other contributors
Licensed under the MIT License.
https://eslint.org/docs/latest/extend/plugins

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API