Интерпретация ошибок и предупреждений Rollup

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


Типология ошибок в Rollup

Критические ошибки (errors)

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

Основные источники критических ошибок:

  • синтаксические ошибки в исходных модулях
  • отсутствие импортируемых модулей
  • ошибки плагинов, выбрасывающих исключения
  • некорректная конфигурация Rollup
  • ошибки разрешения зависимостей (resolution failures)

Каждая ошибка представляется объектом, содержащим структурированную информацию:

  • message — текстовое описание
  • code — машинно-ориентированный идентификатор
  • id — путь к модулю или плагину
  • frame — фрагмент кода с указанием позиции
  • loc — координаты ошибки (строка и колонка)
  • plugin — имя плагина, если ошибка произошла внутри него

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


Предупреждения (warnings)

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

Типичные причины предупреждений:

  • циклические зависимости
  • неиспользуемые экспорты
  • невозможность корректного tree-shaking
  • динамические импорты с неопределяемым статическим анализом
  • неоднозначное разрешение модулей

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


Механизм генерации ошибок

Стадии возникновения

Ошибки могут появляться на разных этапах пайплайна:

  1. Парсинг (parsing) Преобразование исходного кода в AST. Здесь фиксируются синтаксические ошибки JavaScript и TypeScript (при использовании соответствующих плагинов).

  2. Разрешение модулей (module resolution) Ошибки возникают при невозможности найти файл или пакет.

  3. Трансформация (transform) Плагины могут модифицировать код и при этом выбрасывать исключения.

  4. Сборка графа зависимостей (dependency graph) Ошибки циклов или некорректных ссылок.

  5. Генерация бандла (generate/write) Проблемы при финальной эмиссии кода.


Структура объекта ошибки

Rollup формирует стандартизированный объект ошибки, расширяющий базовый Error.

Ключевые поля:

  • name — тип ошибки (обычно RollupError)
  • message — человекочитаемое описание
  • code — стабильный идентификатор
  • stack — стек вызовов
  • plugin — источник ошибки
  • hook — стадия плагинного цикла (load, transform, resolveId и т.д.)
  • id — модуль, где произошла ошибка
  • loc — позиция в коде
  • frame — контекстный фрагмент кода

Дополнительно могут присутствовать поля:

  • watchFiles — список файлов, связанных с ошибкой
  • url — ссылка на документацию
  • pos — абсолютная позиция в файле

Обработка ошибок через API Rollup

Синхронная сборка

При использовании rollup.rollup() ошибки выбрасываются как исключения:

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

Пример поведения:

  • ошибка разрешения импорта → немедленный reject
  • ошибка синтаксиса → остановка анализа графа

Асинхронная сборка и watcher

В режиме наблюдения (rollup.watch) обработка ошибок отличается:

  • ошибки не завершают процесс наблюдения
  • watcher продолжает отслеживание изменений
  • ошибки передаются через события

Основные события:

  • event: 'ERROR'
  • event: 'END'
  • event: 'FATAL'

Разделение на ERROR и FATAL важно:

  • ERROR — локальная проблема сборки
  • FATAL — состояние, при котором watcher не может продолжать работу

Хук onwarn и кастомная обработка предупреждений

Базовая модель

onwarn позволяет перехватывать все предупреждения перед их выводом:

export default {
  onwarn(warning, warn) {
    if (warning.code === 'CIRCULAR_DEPENDENCY') {
      return;
    }
    warn(warning);
  }
}

Поведение по умолчанию

Если onwarn не задан:

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

Фильтрация предупреждений

Типичный сценарий обработки:

  • подавление известных циклов
  • игнорирование устаревших API
  • логирование только критичных предупреждений

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


Коды ошибок и их семантика

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

Примеры категорий:

RESOLVE_*

Ошибки разрешения модулей:

  • отсутствующий файл
  • некорректный импорт
  • конфликт экспорта

PARSE_*

Ошибки синтаксиса:

  • неожиданный токен
  • некорректный JSX (при отсутствии плагина)
  • ошибки TypeScript трансляции

PLUGIN_*

Ошибки плагинов:

  • исключения внутри transform
  • некорректный return value
  • нарушение контрактов API

OUTPUT_*

Ошибки генерации:

  • конфликт имен
  • невозможность сериализации
  • ошибки chunking

Ошибки в плагинной системе

Контракт плагинов

Плагины могут:

  • выбрасывать исключения
  • возвращать this.error()
  • использовать this.warn()

Разница принципиальная:

  • throw → немедленная остановка
  • this.error() → структурированная ошибка Rollup
  • this.warn() → предупреждение без остановки

Контекст ошибки внутри плагина

При вызове this.error Rollup автоматически:

  • привязывает ошибку к текущему модулю
  • добавляет позицию AST (если доступна)
  • связывает ошибку с хуком плагина

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


Source maps и расширение ошибок

При включённых source maps Rollup:

  • преобразует позиции ошибок из bundle в исходные файлы
  • добавляет mapping в loc
  • расширяет frame оригинальным кодом

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


Механизмы подавления и эскалации ошибок

Подавление

Некоторые ошибки могут быть подавлены:

  • через onwarn
  • через конфигурации плагинов
  • через игнорирование конкретных кодов

Эскалация предупреждений

Предупреждение может быть превращено в ошибку вручную:

  • проверка warning.code
  • вызов throw new Error
  • использование кастомной логики CI

Ошибки в режиме watch

Watcher добавляет дополнительный слой обработки:

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

Особенность заключается в том, что Rollup не кэширует ошибки как состояние — каждая пересборка рассматривается как независимая попытка.


Логирование и форматирование

Rollup использует структурированный формат вывода:

  • цветовое выделение (в CLI)
  • выделение кода с указанием строки
  • указание имени файла и позиции
  • маркировка плагинов

Типичный формат включает:

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

Интеграция с внешними системами

Ошибки Rollup часто интегрируются в:

  • CI/CD пайплайны
  • системы мониторинга (Sentry, Datadog)
  • кастомные логгеры

Для этого используется:

  • сериализация объекта ошибки
  • извлечение code и stack
  • фильтрация по типам ошибок

Поведение при множественных ошибках

Rollup обрабатывает ошибки по принципу первой критической остановки:

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

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