Расширение чужой конфигурации

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

Основные механизмы расширения включают:

  • поле extends в legacy-конфигурации
  • объединение конфигураций в flat config
  • использование shareable-конфигураций (npm-пакетов)
  • каскадное переопределение через rules и overrides

Параметр extends в legacy-конфигурации

В классическом формате ESLint (eslintrc) ключевую роль играет свойство extends. Оно позволяет подключать готовые наборы правил.

Пример базового использования:

{
  "extends": "eslint:recommended"
}

Подключение может происходить из нескольких источников:

Встроенные конфигурации ESLint

  • eslint:recommended — набор рекомендованных правил
  • eslint:all — полный набор доступных правил
{
  "extends": ["eslint:recommended", "eslint:all"]
}

При объединении нескольких конфигураций они применяются последовательно.


Расширение конфигураций из npm-пакетов

Часто используются сторонние или внутренние shareable-конфигурации. Они публикуются как npm-пакеты и подключаются без указания путей.

Примеры:

{
  "extends": [
    "airbnb",
    "plugin:@typescript-eslint/recommended"
  ]
}

Механизм разрешения имени:

  • eslint-config-<name>extends: "<name>"
  • @scope/eslint-configextends: "@scope"

Также допускается указание конкретных файлов:

{
  "extends": "./configs/base-eslint.json"
}

Порядок наследования и приоритеты

Конфигурации в extends обрабатываются слева направо. Каждая последующая конфигурация может переопределять предыдущую.

Принцип приоритета:

  1. базовые конфигурации
  2. подключённые shareable-конфиги
  3. локальные правила rules
  4. overrides (самый высокий приоритет в своей области)

Пример:

{
  "extends": ["eslint:recommended", "airbnb"],
  "rules": {
    "no-console": "off"
  }
}

В данном случае правило no-console перекрывает настройки всех подключённых конфигураций.


Множественное расширение и композиция

ESLint поддерживает массив конфигураций в extends, что позволяет строить цепочки наследования:

{
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ]
}

Композиция используется для разделения ответственности:

  • базовый стиль JavaScript
  • правила React
  • правила TypeScript
  • отключение конфликтующих форматирующих правил

Переопределение правил

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

{
  "extends": "eslint:recommended",
  "rules": {
    "eqeqeq": "error",
    "curly": "warn",
    "no-unused-vars": "off"
  }
}

Типы значений:

  • "off" — отключение
  • "warn" — предупреждение
  • "error" — ошибка

Также допускается объектная конфигурация:

{
  "rules": {
    "quotes": ["error", "single"],
    "semi": ["error", "always"]
  }
}

Конфигурация overrides

Механизм overrides позволяет применять расширение и переопределение правил для отдельных наборов файлов.

{
  "extends": "eslint:recommended",
  "overrides": [
    {
      "files": ["*.test.js"],
      "rules": {
        "no-unused-expressions": "off"
      }
    },
    {
      "files": ["src/**/*.ts"],
      "extends": "plugin:@typescript-eslint/recommended"
    }
  ]
}

Особенности:

  • применяется только к совпадающим файлам
  • может содержать собственный extends
  • позволяет создавать контекстные конфигурации

Shareable-конфигурации

Shareable configs представляют собой npm-пакеты, экспортирующие объект ESLint-конфигурации.

Типовая структура пакета:

eslint-config-company/
  index.js
  package.json

Пример index.js:

module.exports = {
  rules: {
    "no-console": "warn",
    "prefer-const": "error"
  }
};

Использование:

{
  "extends": "company"
}

Для scoped-пакетов:

{
  "extends": "@company/eslint-config"
}

Flat config и современный подход

В новых версиях ESLint (flat config) механизм наследования изменяется. Вместо extends используется явное объединение конфигурационных объектов.

Пример:

export default [
  baseConfig,
  reactConfig,
  {
    rules: {
      "no-console": "error"
    }
  }
];

Особенности flat config:

  • порядок массивов определяет приоритет
  • отсутствует скрытое наследование
  • плагины подключаются явно
  • конфигурации являются обычными объектами JavaScript

Комбинирование legacy и flat подходов

При миграции часто встречается параллельное использование:

  • legacy-конфигурации через extends
  • частичное переопределение через flat config

Однако модели не смешиваются напрямую: каждая работает в своей системе обработки.


Приоритет правил при расширении

Итоговая конфигурация формируется по следующим уровням:

  1. встроенные дефолты ESLint
  2. конфигурации из extends
  3. плагины и их рекомендации
  4. локальные rules
  5. overrides для конкретных файлов
  6. flat config (если используется) как независимый слой

При конфликте значений выигрывает более поздний и более специфичный источник.


Типовые ошибки при расширении конфигураций

Часто встречающиеся проблемы связаны с неправильной интерпретацией наследования:

  • дублирование одинаковых конфигураций в extends
  • конфликтующие shareable-конфиги (например, форматтеры)
  • ожидание полного отключения правила без явного off
  • неверный порядок подключения конфигураций
  • смешивание несовместимых версий ESLint и плагинов

Особенно критичным является порядок подключения конфигов форматирования и линтинга, поскольку они могут взаимно переопределять правила стиля кода.


Модульность конфигураций и масштабирование

Расширение конфигураций используется для построения иерархических систем:

  • базовая конфигурация организации
  • конфигурация команды или продукта
  • конфигурация проекта
  • локальные исключения

Такая структура позволяет централизовать правила и снижать количество дублирования при сопровождении множества репозиториев.