Публикуемая конфигурация ESLint оформляется как отдельный npm-пакет, предназначенный для переиспользования в различных проектах. Основой служит набор правил, пресетов и подключаемых плагинов, инкапсулированных в единый конфигурационный модуль.
Типовая структура пакета включает следующие элементы:
index.js,
eslint.config.js или .eslintrc.js)package.json с метаданными и зависимостямиКлючевая особенность publishable-конфигурации заключается в её
предсказуемом поведении при подключении через extends.
Для конфигураций ESLint используется строго определённая схема именования:
eslint-config-*@scope/eslint-configПримеры:
eslint-config-standardeslint-config-airbnb-base@company/eslint-configПри установке через extends имя пакета сокращается до
части после префикса:
{
"extends": "company"
}
или для scoped-пакета:
{
"extends": "@company"
}
ESLint автоматически резолвит такие пакеты по соглашению именования.
Конфигурационный пакет ESLint требует корректного описания метаданных npm. Основные поля определяют поведение при установке и совместимость.
{
"name": "eslint-config-company",
"version": "1.0.0",
"main": "index.js",
"peerDependencies": {
"eslint": ">=8.0.0"
},
"keywords": [
"eslint",
"eslintconfig",
"lint"
],
"license": "MIT"
}
Ключевое требование — указание ESLint в
peerDependencies. Это предотвращает установку собственной
версии ESLint внутри пакета и обеспечивает единое окружение линтинга в
проекте.
Дополнительно иногда фиксируются версии плагинов:
{
"peerDependencies": {
"eslint": ">=8.0.0",
"eslint-plugin-import": ">=2.25.0"
}
}
Традиционный формат конфигурации основан на экспорте объекта:
module.exports = {
rules: {
semi: ["error", "always"],
quotes: ["error", "single"]
},
env: {
node: true,
es2022: true
}
};
При публикации такой пакет подключается через
extends:
{
"extends": "company"
}
ESLint автоматически ищет eslint-config-company в
node_modules.
В новых версиях ESLint используется flat config
(eslint.config.js), где конфигурация экспортируется
массивом объектов:
export default [
{
files: ["**/*.js"],
rules: {
semi: "error",
quotes: ["error", "single"]
}
}
];
Публикуемые конфигурации в таком формате чаще экспортируют готовый массив или функцию:
export default [
...baseConfig,
{
rules: {
"no-console": "warn"
}
}
];
Для переиспользования в других пакетах применяется импорт:
import companyConfig from "eslint-config-company";
Большие конфигурации разделяются на слои:
Пример структуры:
eslint-config-company/
base.js
react.js
typescript.js
index.js
index.js агрегирует конфигурации:
module.exports = [
require("./base"),
require("./typescript"),
require("./react")
];
Конфигурации ESLint часто зависят от плагинов:
eslint-plugin-importeslint-plugin-reacteslint-plugin-promiseТакие зависимости фиксируются в peerDependencies, чтобы
избежать конфликтов версий.
Пример конфигурации правил:
module.exports = {
plugins: ["import"],
rules: {
"import/order": "error",
"import/no-unresolved": "error"
}
};
Публикуемая конфигурация активируется через механизм наследования:
{
"extends": ["company", "company/react"]
}
Поддерживается цепочка расширений, где каждая следующая конфигурация дополняет или переопределяет предыдущую.
При многоуровневой архитектуре используются отдельные entry points:
eslint-config-companyeslint-config-company/reacteslint-config-company/nodeДля npm-пакетов ESLint применяется семантическое версионирование:
Изменение поведения линтинга считается breaking change даже при
изменении одного правила с warn на error.
Публикация конфигурации осуществляется через npm CLI. Перед публикацией фиксируется версия пакета:
npm version minor
Далее выполняется публикация:
npm publish
Для scoped-пакетов требуется указание публичного доступа:
npm publish --access public
Scoped-пакеты позволяют изолировать конфигурации внутри организации:
@company/eslint-config
Преимущества:
Структура использования:
{
"extends": "@company"
}
Публикуемая конфигурация должна поддерживать переопределение на уровне проекта:
{
"extends": "company",
"rules": {
"quotes": ["error", "double"]
}
}
Механизм merge конфигураций выполняется ESLint по приоритету:
Конфигурации часто разделяются по средам выполнения:
Пример:
module.exports = {
env: {
browser: true,
node: true,
jest: true
}
};
В модульной публикации это выносится в отдельные entry points:
eslint-config-company/nodeeslint-config-company/browserКорректная публикация требует строгого разделения:
dependencies — редко используютсяpeerDependencies — ESLint и плагиныdevDependencies — тестирование и линтинг самого
пакетаПример:
{
"devDependencies": {
"eslint": "^8.0.0"
}
}
Перед публикацией конфигурация проверяется на корректность применения правил:
Тестовые проекты используют локальное подключение пакета через
npm link или workspace-монорепозиторий.
В крупных проектах конфигурации публикуются как набор пакетов:
packages/
eslint-config-base
eslint-config-react
eslint-config-node
Управление версиями осуществляется централизованно, что обеспечивает согласованность правил во всех частях экосистемы.
Конфигурации ESLint тесно связаны с плагинами и форматтерами. Часто требуется синхронизация:
eslint-plugin-*Несовместимость версий приводит к конфликтам в разрешении правил и различиям в поведении линтера между проектами.