watch.include и watch.exclude

Механизм наблюдения за файлами в Rollup строится вокруг параметра watch, который позволяет запускать пересборку при изменениях исходного кода. Внутри этой конфигурации ключевую роль играют фильтры include и exclude, определяющие, какие файлы должны отслеживаться системой файлового наблюдения, а какие игнорироваться.

Режим наблюдения в Rollup активируется через CLI или через API-конфигурацию. После включения процесса сборщик подписывается на изменения файловой системы и реагирует на события добавления, изменения и удаления файлов. Однако не все файлы проекта должны участвовать в этом процессе: зависимости, временные директории, сгенерированные артефакты и внешние библиотеки могут существенно увеличивать нагрузку и замедлять пересборку.

Для управления областью наблюдения используются:

  • watch.include — явно задаёт набор файлов или директорий, которые должны отслеживаться
  • watch.exclude — исключает определённые пути из наблюдения

Эти параметры работают совместно, формируя итоговый фильтр.

Принцип приоритета include и exclude

Логика обработки сводится к последовательной фильтрации:

  1. Если задан include, Rollup сначала ограничивает область только указанными путями
  2. Затем из этого набора исключаются пути, совпадающие с exclude

При отсутствии include наблюдение охватывает весь граф модулей проекта, за исключением явно исключённых элементов через exclude.

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

Форматы задания путей

Оба параметра принимают несколько типов значений:

  • строка с путём
  • массив строк
  • glob-выражения
  • регулярные выражения

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

watch: {
  include: 'src/**',
  exclude: 'src/vendor/**'
}

Здесь наблюдение ограничено директориией src, но исключает всё, что находится в src/vendor.

Регулярные выражения позволяют более гибкую фильтрацию:

watch: {
  include: /src\/.*\.js$/,
  exclude: /node_modules/
}

В этом случае учитываются только JavaScript-файлы внутри src, при этом любые модули из node_modules игнорируются.

Поведение при работе с node_modules

Одна из ключевых причин использования exclude — исключение node_modules. Даже если Rollup не всегда отслеживает их по умолчанию в watch-режиме, подключение плагинов или нестандартных резолверов может привести к их попаданию в граф зависимостей.

Типичный шаблон конфигурации:

watch: {
  include: 'src/**',
  exclude: 'node_modules/**'
}

Это снижает нагрузку на файловую систему и предотвращает лишние триггеры пересборки.

Особенности работы glob-шаблонов

Glob-выражения интерпретируются через механизмы сопоставления путей, аналогичные тем, что используются в большинстве Node.js-инструментов. Основные правила:

  • * — любое количество символов в пределах одного сегмента пути
  • ** — рекурсивное соответствие вложенным директориям
  • ? — один произвольный символ
  • {a,b} — альтернативы

Пример более сложной конфигурации:

watch: {
  include: [
    'src/**',
    'shared/**'
  ],
  exclude: [
    '**/*.test.js',
    '**/*.spec.js',
    'src/legacy/**'
  ]
}

Такой подход позволяет отделить продуктивный код от тестов и устаревших модулей.

Влияние на производительность

Фильтры include и exclude напрямую влияют на количество файлов, находящихся под наблюдением. При большом количестве отслеживаемых путей увеличивается:

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

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

Особенно критично это для монорепозиториев, где без фильтрации Rollup может отслеживать десятки тысяч файлов.

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

Некоторые плагины Rollup могут добавлять собственные виртуальные модули или расширять граф зависимостей. В таких случаях watch.include и watch.exclude работают только на уровне файловой системы и не всегда способны ограничить внутренние зависимости плагинов.

Например, плагин резолвинга может подтянуть модули из node_modules, даже если они исключены из наблюдения. Поэтому фильтры следует рассматривать как первую линию оптимизации, но не абсолютное ограничение графа сборки.

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

Если один и тот же путь одновременно попадает под include и exclude, приоритет всегда остаётся за exclude. Это гарантирует предсказуемость поведения при сложных конфигурациях.

Пример:

watch: {
  include: 'src/**',
  exclude: 'src/**/debug/**'
}

Даже если директория debug входит в общий include, она будет полностью исключена из наблюдения.

Практика комбинирования правил

В реальных проектах часто используется комбинированный подход:

  • include ограничивает корневые директории проекта
  • exclude убирает тесты, сборочные артефакты и сторонние каталоги

Типичная конфигурация:

watch: {
  include: ['src/**', 'config/**'],
  exclude: [
    '**/*.map',
    '**/*.d.ts',
    'dist/**',
    'node_modules/**'
  ]
}

Такой набор обеспечивает стабильную пересборку без избыточных триггеров.

Особенности работы с вложенными монорепозиториями

В монорепозиториях структура часто включает несколько пакетов с общими зависимостями. В этом случае watch.include может быть настроен на конкретный пакет:

watch: {
  include: 'packages/app/src/**',
  exclude: 'packages/**/node_modules/**'
}

Это позволяет изолировать пересборку одного пакета без влияния на остальные.

Поведение при динамических импортax

При использовании динамических import() Rollup расширяет граф зависимостей во время анализа. Однако watch-фильтры продолжают применяться только к файловой системе. Это означает, что динамически подключённые модули всё равно могут попадать в наблюдение, если они находятся вне зоны exclude.

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

Ограничения механизма фильтрации

Существуют ограничения, которые важно учитывать при настройке:

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

Из-за этого возможны ситуации, когда файл исключён из watch, но всё равно участвует в сборке как зависимость другого модуля.

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

На практике часто встречаются следующие проблемы:

  • слишком широкое include без исключений, приводящее к деградации производительности
  • исключение ключевых исходных директорий через exclude
  • попытка использовать exclude как механизм отключения модулей в графе сборки
  • отсутствие учёта тестовых файлов, приводящее к лишним пересборкам

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

Поведение при изменении конфигурации watch

Изменение watch.include и watch.exclude требует перезапуска процесса наблюдения. Rollup не всегда пересчитывает фильтры динамически, особенно при использовании CLI-режима. Это связано с тем, что система наблюдения и построение графа модулей инициализируются один раз при старте процесса.

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