Механизм overrides в конфигурации ESLint предназначен
для применения различных наборов правил к разным группам файлов внутри
одного проекта. Это позволяет поддерживать единый конфигурационный файл,
сохраняя при этом гибкость для отдельных типов исходного кода.
В классической конфигурации ESLint (например,
.eslintrc.js) секция overrides представляет
собой массив объектов:
module.exports = {
rules: {
semi: ["error", "always"]
},
overrides: [
{
files: ["*.test.js"],
rules: {
"no-unused-expressions": "off"
}
}
]
};
Каждый объект внутри overrides содержит как минимум поле
files, определяющее набор файлов, к которым применяются
переопределённые правила. Остальные поля конфигурации внутри override
работают так же, как и в корневой конфигурации.
Поле files использует glob-шаблоны для определения
области действия override-конфигурации. ESLint сопоставляет путь файла с
каждым шаблоном, и если происходит совпадение, соответствующий набор
правил применяется поверх базовой конфигурации.
Поддерживаются следующие типы шаблонов:
*.js — все файлы в корне проекта с расширением
.js**/*.test.js — все тестовые файлы на любом уровне
вложенностиsrc/**/*.{js,ts} — комбинированные расширенияПример:
overrides: [
{
files: ["src/**/*.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "error"
}
}
]
Механизм сопоставления работает по принципу накопления: если файл совпадает сразу с несколькими override-блоками, все соответствующие конфигурации будут применены.
ESLint применяет конфигурации в строго определённом порядке:
rules на верхнем уровне)extends)overrides, применяемые по совпадению файловЕсли один и тот же rule определён в нескольких местах, действует принцип переопределения:
Пример конфликтующих правил:
module.exports = {
rules: {
quotes: ["error", "single"]
},
overrides: [
{
files: ["**/*.js"],
rules: {
quotes: ["error", "double"]
}
},
{
files: ["**/*.config.js"],
rules: {
quotes: ["error", "single"]
}
}
]
};
Файл app.config.js будет использовать правило
single, несмотря на более общий override выше, так как
более специфичный блок имеет приоритет в рамках совпадения файлов.
Каждый объект внутри overrides может содержать
практически все поля ESLint-конфигурации:
envparserparserOptionspluginsrulesЭто позволяет не только переопределять правила, но и изменять контекст анализа для конкретных файлов.
Пример использования другого парсера:
overrides: [
{
files: ["*.vue"],
parser: "vue-eslint-parser",
rules: {
"vue/no-unused-vars": "error"
}
}
]
Таким образом, overrides становится инструментом
адаптации ESLint под различные языки и диалекты внутри одного
проекта.
При наличии нескольких override-блоков, затрагивающих один и тот же файл, происходит последовательное наложение конфигураций.
Пример:
overrides: [
{
files: ["**/*.js"],
rules: {
"no-console": "warn"
}
},
{
files: ["**/debug/*.js"],
rules: {
"no-console": "off"
}
}
]
Файл debug/logger.js сначала получает правило
warn, затем оно переопределяется на off.
Важно учитывать, что порядок объявления override-блоков критически влияет на итоговое поведение.
Одна из наиболее распространённых задач — ослабление правил в тестовых файлах:
overrides: [
{
files: ["**/*.test.js", "**/*.spec.js"],
rules: {
"no-magic-numbers": "off",
"max-lines": "off"
}
}
]
Конфигурационные файлы часто требуют более мягких ограничений:
overrides: [
{
files: ["*.config.js"],
rules: {
"no-undef": "off",
"no-process-env": "off"
}
}
]
overrides: [
{
files: ["**/*.ts"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
rules: {
"@typescript-eslint/explicit-function-return-type": "error"
}
}
]
Хотя overrides не поддерживает вложенные структуры в
виде иерархий, можно имитировать сложное поведение через комбинацию
glob-шаблонов:
Пример:
overrides: [
{
files: ["src/**/*.js"],
rules: {
"no-console": "error"
}
},
{
files: ["src/utils/**/*.js"],
rules: {
"no-console": "off"
}
}
]
Если несколько шаблонов совпадают с одним файлом, ESLint применяет все подходящие override-блоки. Это может привести к неожиданным результатам при конфликтующих правилах.
Override-блоки не являются независимыми конфигурациями. Они всегда накладываются поверх базовой конфигурации, а не заменяют её полностью.
extends
внутри overridesКаждый override может содержать extends, однако его
поведение менее очевидно: расширенные конфигурации применяются только
внутри данного блока и не влияют на глобальный контекст.
В масштабных кодовых базах overrides становится
центральным механизмом адаптации линтинга под различные слои
архитектуры:
Структура конфигурации обычно эволюционирует в сторону сегментации:
overrides: [
{
files: ["src/ui/**/*"],
rules: { ... }
},
{
files: ["src/server/**/*"],
rules: { ... }
},
{
files: ["scripts/**/*"],
rules: { ... }
}
]
Такой подход позволяет минимизировать количество глобальных исключений и повысить предсказуемость анализа кода.
В новых версиях ESLint используется flat-конфигурация, где аналог
overrides реализуется через массив конфигурационных
объектов с полем files:
export default [
{
files: ["**/*.js"],
rules: {
semi: "error"
}
},
{
files: ["**/*.test.js"],
rules: {
semi: "off"
}
}
];
Хотя синтаксис отличается, концептуальная модель сохраняется: файловые паттерны определяют область действия правил, а порядок объектов влияет на итоговую конфигурацию.