Паттерны glob в конфигурации

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

В основе лежит сопоставление строк путей с шаблонами, где специальные символы заменяют группы символов или целые сегменты пути. ESLint опирается на реализацию, совместимую с minimatch/micromatch, поэтому поведение glob-паттернов совпадает с привычной экосистемой Node.js-инструментов.

Синтаксические элементы glob-паттернов

Звёздочка * Заменяет любую последовательность символов в пределах одного сегмента пути. Пример:

  • *.js — все JavaScript-файлы в текущем каталоге
  • src/*.js — только файлы в src, без вложенных директорий

Двойная звезда ** Означает рекурсивное соответствие любому количеству уровней вложенности.

  • **/*.js — все .js файлы во всём проекте
  • src/**/*.test.js — тестовые файлы в любом подкаталоге src

Вопросительный знак ? Соответствует ровно одному символу.

  • file?.js совпадает с file1.js, fileA.js, но не file10.js

Квадратные скобки [] Диапазоны или наборы символов.

  • file[12].jsfile1.js, file2.js
  • file[a-c].jsfilea.js, fileb.js, filec.js

Фигурные скобки {} Группировка альтернатив.

  • *.{js,ts} — файлы JavaScript и TypeScript
  • src/**/*.{spec,test}.js — разные типы тестов

Отрицание ! Исключение файлов из набора.

  • !node_modules/** — исключение зависимостей
  • В конфигурации ESLint часто используется как элемент массива ignore

Использование glob в классической конфигурации ESLint

В формате .eslintrc glob-паттерны применяются в нескольких ключевых местах: files, excludedFiles, ignorePatterns.

Поле files в overrides

Механизм overrides позволяет применять разные правила к разным наборам файлов:

{
  "overrides": [
    {
      "files": ["**/*.ts"],
      "rules": {
        "no-unused-vars": "off"
      }
    },
    {
      "files": ["src/**/*.test.js"],
      "env": {
        "jest": true
      }
    }
  ]
}

Здесь glob определяет область действия конкретного набора правил. Каждый блок overrides фактически формирует отдельный контекст линтинга.

ignorePatterns

Глобальные исключения описываются через массив паттернов:

{
  "ignorePatterns": [
    "dist/**",
    "build/**",
    "node_modules/**",
    "**/*.min.js"
  ]
}

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

Glob в flat config (eslint.config.js)

Современная система конфигурации ESLint использует flat config, где glob-паттерны стали ещё более значимыми.

Поле files

export default [
  {
    files: ["**/*.js"],
    rules: {
      semi: "error"
    }
  },
  {
    files: ["src/**/*.{ts,tsx}"],
    rules: {
      "@typescript-eslint/no-unused-vars": "error"
    }
  }
];

Каждый объект конфигурации привязывается к набору файлов через glob. Это основной механизм сегментации проекта.

Поле ignores

export default [
  {
    ignores: [
      "dist/**",
      "coverage/**",
      "**/*.min.js"
    ]
  }
];

В flat config исключения становятся частью декларативного массива конфигурации и заменяют .eslintignore.

Принципы сопоставления путей

Glob-паттерны в ESLint работают относительно корня проекта, который определяется расположением конфигурационного файла. Это приводит к нескольким важным особенностям:

  • пути нормализуются к POSIX-формату (/)
  • Windows-разделители (\) приводятся к стандартному виду
  • сопоставление всегда выполняется относительно базовой директории проекта

Например, файл src\utils\index.js будет интерпретироваться как src/utils/index.js.

Приоритеты и порядок применения

При использовании нескольких уровней конфигурации glob-паттерны участвуют в системе приоритетов.

  1. ignores / ignorePatterns — исключают файлы до применения правил
  2. files в конфигурационных блоках — определяют применимость правил
  3. overrides (в классической конфигурации) — уточняют или переопределяют поведение

В flat config порядок объектов в массиве также имеет значение: последующие записи могут переопределять предыдущие для совпадающих файлов.

Расширенные шаблоны и композиция

Glob-паттерны позволяют строить сложные выражения для реальных структур проектов.

Разделение по слоям архитектуры

  • src/api/**/*.js — слой API
  • src/ui/**/*.tsx — UI-компоненты
  • src/shared/**/*.{js,ts} — общие модули

Разделение по типам файлов

  • **/*.test.{js,ts} — тесты
  • **/*.config.{js,cjs,mjs} — конфигурационные файлы
  • **/*.{spec,benchmark}.js — специальные сценарии

Исключение с уточнением

ignores: [
  "**/*",
  "!src/**"
]

Такая конструкция сначала исключает всё, а затем возвращает часть файлов обратно в анализ.

Сложные случаи сопоставления

Dotfiles

Файлы, начинающиеся с точки, по умолчанию не всегда попадают в **/*.

  • .env
  • .eslintrc.js

Для их включения используется явное указание:

  • **/.*
  • .*

Глубокие вложенности

Паттерн ** способен пересекать любое количество директорий:

  • a/**/b.js совпадает с:

    • a/b.js
    • a/x/b.js
    • a/x/y/z/b.js

Комбинация с расширениями

"**/*.{js,jsx,ts,tsx}"

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

Производительность glob-паттернов

Неправильно составленные glob-выражения могут существенно замедлить линтинг больших проектов.

Наиболее затратные конструкции:

  • чрезмерное использование ** на корневом уровне (**/*.js в огромных монорепозиториях)
  • пересекающиеся ignore-правила
  • отсутствие явных ограничений директорий

Более эффективные подходы:

  • ограничение области src/** вместо глобального **
  • явное указание расширений
  • разделение конфигураций по пакетам в монорепозиториях

Типичные паттерны в реальных проектах

Базовый JavaScript проект

  • **/*.js
  • !node_modules/**
  • dist/**

TypeScript проект

  • **/*.{ts,tsx}
  • **/*.d.ts
  • !dist/**

Frontend приложение

  • src/**/*.{js,jsx,ts,tsx}
  • public/**
  • **/*.stories.*

Монорепозиторий

  • packages/*/src/**/*
  • apps/*/src/**/*
  • tools/**

Взаимодействие glob с плагинами ESLint

Плагины ESLint не изменяют сам синтаксис glob, но используют его внутри собственных правил конфигурации. Это приводит к каскадному применению шаблонов:

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

Ограничения glob-модели

Несмотря на гибкость, glob не является полноценным языком запросов:

  • отсутствует логика сравнения содержимого файлов
  • нет поддержки зависимостей между путями
  • невозможно выразить условия типа «файл A, если существует файл B»

Поэтому glob используется только как механизм отбора файлов, а не анализа структуры проекта.

Поведение при конфликтующих паттернах

Если один файл совпадает с несколькими конфигурационными блоками, применяется объединение или переопределение:

  • правила могут суммироваться
  • либо последний совпавший блок имеет приоритет
  • поведение зависит от формата конфигурации (legacy или flat)

Например:

[
  {
    files: ["**/*.js"],
    rules: { semi: "error" }
  },
  {
    files: ["src/**/*.js"],
    rules: { semi: "off" }
  }
]

Файл src/app.js попадёт под оба блока, но итоговое поведение зависит от порядка.

Практика построения устойчивых glob-конфигураций

Стабильные конфигурации обычно придерживаются нескольких принципов:

  • минимизация глобальных масок
  • изоляция зон проекта по директориям
  • явное указание расширений вместо универсальных шаблонов
  • централизованные ignore-правила

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