Конфигурация ESLint редко остается неизменной на протяжении всего жизненного цикла проекта. Обновляются версии самого линтера, появляются новые правила, изменяются рекомендуемые настройки, развиваются плагины и расширяемые конфигурации. Без контроля версий и продуманной стратегии обновления конфигурация постепенно превращается в источник нестабильности сборки и неожиданных ошибок.
Версионирование конфигурации ESLint позволяет:
Особенно важным становится управление версиями в крупных проектах, монорепозиториях и библиотеках с длительным сроком поддержки.
ESLint придерживается принципов Semantic Versioning (SemVer).
Формат версии:
MAJOR.MINOR.PATCH
Например:
9.15.0
Где:
Примеры:
| Версия | Тип изменений |
|---|---|
| 8.56.0 → 8.57.0 | Новые возможности |
| 8.57.0 → 8.57.1 | Исправления |
| 8.57.1 → 9.0.0 | Потенциально ломающие изменения |
При переходе между мажорными версиями необходимо внимательно изучать документацию миграции.
Конфигурация ESLint обычно хранится в одном из файлов:
eslint.config.js
.eslintrc.js
.eslintrc.cjs
.eslintrc.json
.eslintrc.yml
Изменения конфигурации должны находиться под контролем системы версий.
Пример фиксации изменений в Git:
git add eslint.config.js
git commit -m "Update ESLint rules for async code"
История изменений позволяет определить:
Использование плавающих версий может привести к неожиданным изменениям поведения линтера.
Нежелательный вариант:
{
"devDependencies": {
"eslint": "^9.0.0"
}
}
Символ ^ разрешает автоматическое обновление минорных
версий.
Более контролируемый подход:
{
"devDependencies": {
"eslint": "9.15.0"
}
}
В этом случае команда установки всегда получит одинаковую версию ESLint.
Для воспроизводимости среды используются lock-файлы:
package-lock.json
yarn.lock
pnpm-lock.yaml
Lock-файл фиксирует:
Без lock-файла одинаковый package.json может приводить к
разным версиям зависимостей на разных машинах.
Помимо ESLint необходимо контролировать версии плагинов.
Пример:
{
"devDependencies": {
"eslint": "9.15.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-react": "7.36.1"
}
}
Плагин может:
Поэтому обновление плагинов требует такого же внимания, как и обновление самого линтера.
Многие проекты используют готовые конфигурации:
extends: [
"eslint:recommended",
"plugin:react/recommended"
]
Или:
import js from "@eslint/js";
export default [
js.configs.recommended
];
Каждая подобная конфигурация имеет собственный жизненный цикл.
После обновления пакета могут измениться:
Поэтому обновление пакетов-конфигураций необходимо тестировать отдельно.
Получение установленной версии:
npx eslint --version
Результат:
v9.15.0
Также версия отображается через менеджер пакетов:
npm list eslint
или:
yarn why eslint
Для npm:
npm outdated
Пример вывода:
Package Current Wanted Latest
eslint 9.14.0 9.15.0 9.15.0
Значения:
Такой анализ позволяет планировать обновления конфигурации.
Обновления выполняются редко.
Преимущества:
Недостатки:
Обновления выполняются постоянно.
Например:
Преимущества:
Недостатки:
Перед выпуском новой версии продукта выполняется:
Такой подход часто используется в корпоративной разработке.
Установка новой версии:
npm install eslint@latest --save-dev
Или конкретной версии:
npm install eslint@9.15.0 --save-dev
После обновления необходимо выполнить:
npx eslint .
для проверки совместимости существующей конфигурации.
Перед обновлением рекомендуется анализировать:
Особенно это важно при переходе между мажорными версиями.
Например:
8.x → 9.x
может включать:
Одним из крупнейших изменений в истории ESLint стал переход к Flat Config.
Старый формат:
module.exports = {
rules: {
semi: "error"
}
};
Новый формат:
export default [
{
rules: {
semi: "error"
}
}
];
Многие проекты при обновлении до ESLint 9 переходили именно на новую систему конфигурации.
После обновления полезно анализировать итоговую конфигурацию.
Команда:
npx eslint --print-config src/index.js
Выводит объединенную конфигурацию с учетом:
Это помогает обнаруживать изменения после обновления зависимостей.
После обновления рекомендуемых наборов правил могут появиться десятки новых предупреждений.
Резкое включение всех правил часто приводит к проблемам.
Более безопасный подход:
rules: {
"no-console": "warn"
}
После исправления нарушений:
rules: {
"no-console": "error"
}
Такое внедрение снижает нагрузку на команду.
Во время обновления часто применяют промежуточное состояние.
Пример:
rules: {
eqeqeq: "warn",
curly: "warn",
semi: "error"
}
После устранения всех замечаний:
rules: {
eqeqeq: "error",
curly: "error",
semi: "error"
}
Подобная схема особенно полезна для старых проектов.
После обновления конфигурации важно убедиться, что одинаковые правила применяются во всех окружениях.
Пример:
- run: npm ci
- run: npm run lint
Использование команды:
npm ci
гарантирует установку зависимостей строго по lock-файлу.
Практикой сопровождения является выделение отдельной ветки:
chore/update-eslint
Процесс выглядит следующим образом:
Такой подход снижает риск случайного попадания массовых исправлений в функциональные задачи.
Для автоматического контроля версий применяются сервисы:
Они способны:
Это особенно полезно для проектов с большим количеством ESLint-плагинов.
Сложные изменения желательно сопровождать документацией.
Пример записи в CHANGELOG:
Changed:
- Updated ESLint from 8.57.0 to 9.15.0
- Migrated to Flat Config
- Enabled no-unused-private-class-members
Подобная история упрощает поддержку проекта спустя месяцы и годы.
Ошибка:
Definition for rule 'some-rule' was not found
Причины:
Ошибка:
ESLint couldn't find the config
Причины:
Ошибка:
This plugin is not compatible with ESLint 9
Решение:
Даже без ошибок результаты проверки могут измениться.
Например:
"no-unused-vars": "error"
Новая версия правила может обнаруживать больше ситуаций, чем предыдущая.
Поэтому после обновления всегда требуется полный запуск линтера по всему проекту.
Крупные компании часто создают собственные пакеты:
@company/eslint-config
Для них также применяется SemVer.
Пример:
{
"extends": [
"@company/eslint-config"
]
}
Изменения версий могут означать:
Внутренние конфигурации рекомендуется сопровождать собственным журналом изменений и миграционной документацией.
--print-config.