esbuild.formatMessages(): форматирование ошибок вручную

Роль форматирования сообщений в процессе сборки

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

Функция esbuild.formatMessages() выполняет преобразование массива диагностических объектов в текстовые строки с учётом контекста, типа сообщения и параметров форматирования. Она используется тогда, когда стандартный вывод esbuild не применяется напрямую, а требуется ручной контроль над представлением ошибок и предупреждений.


Структура диагностического сообщения

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

  • text — основное описание ошибки или предупреждения

  • location — информация о позиции в исходном коде

    • file
    • line
    • column
    • length
    • lineText
  • notes — дополнительные уточнения, вложенные сообщения

  • pluginName — имя плагина, сформировавшего сообщение

  • detail — расширенные технические данные (в зависимости от источника)

Пример структуры:

{
  text: "Unexpected token",
  location: {
    file: "src/index.js",
    line: 12,
    column: 8,
    lineText: "const a = ",
    length: 1
  },
  notes: [
    {
      text: "Parsing failed here"
    }
  ],
  pluginName: "js-parser"
}

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


Сигнатура функции formatMessages

esbuild.formatMessages(messages, options)

Функция принимает массив сообщений и объект настроек, возвращая массив строк.


Параметры options

kind

Определяет тип сообщений, подлежащих форматированию:

  • "error" — ошибки
  • "warning" — предупреждения

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


color

Управляет использованием ANSI-цветов в выводе:

  • true — включение цветного вывода
  • false — отключение цветов

Цвета используются для выделения:

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

В средах CI обычно применяется color: false для предотвращения вывода управляющих символов.


terminalWidth

Определяет ширину виртуального терминала для форматирования:

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

Значение особенно важно при выводе в лог-файлы или нестандартные терминалы.


Поведение форматирования

esbuild.formatMessages() преобразует структурированные сообщения в многострочный текст, включающий:

  • путь к файлу
  • строку и колонку ошибки
  • исходную строку кода
  • маркер позиции ошибки (caret ^)
  • вложенные заметки (notes)
  • имя плагина (если присутствует)

Типичный результат:

src/index.js:12:8: error: Unexpected token
const a =
       ^
Parsing failed here

Форматирование ориентировано на быстрое визуальное восприятие причины ошибки без необходимости ручного разбора структуры объекта.


Работа с ошибками и предупреждениями

Разделение error и warning влияет на семантику вывода:

  • ошибки интерпретируются как блокирующие события сборки
  • предупреждения отображают потенциальные проблемы, не останавливающие процесс

При использовании formatMessages выбор kind влияет на стилизацию и префиксы сообщений, что важно при унифицированном логировании.


Использование в transform API

При работе с esbuild.transform() результат может содержать массив errors и warnings, которые изначально представлены в сыром формате:

const result = await esbuild.transform(code, {
  loader: "js"
});

Дальнейшая обработка:

const formatted = await esbuild.formatMessages(result.errors, {
  kind: "error",
  color: false,
  terminalWidth: 80
});

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


Использование в build API

В esbuild.build() сообщения доступны через результат сборки:

const result = await esbuild.build({
  entryPoints: ["src/index.js"],
  outfile: "dist/bundle.js",
  bundle: true
});

Форматирование предупреждений:

const warnings = await esbuild.formatMessages(result.warnings, {
  kind: "warning",
  color: true,
  terminalWidth: 100
});

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


Вложенные сообщения (notes)

Поле notes используется для расширения контекста ошибки. При форматировании оно выводится как дополнительный блок под основным сообщением.

Особенности:

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

Пример:

src/app.js:20:5: error: Missing semicolon
console.log("test")
    ^
Note: This expression is part of a larger statement

Управление шириной вывода

Параметр terminalWidth влияет на визуальную структуру вывода:

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

При значениях ниже стандартных (например, 40–60 символов) формат становится более вертикальным, что упрощает чтение в узких логах.


Цветовое форматирование

При color: true применяются ANSI escape-последовательности:

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

В средах без поддержки ANSI цвет автоматически отключается или игнорируется, но структура сообщения сохраняется.


Сценарии ручного форматирования

Использование esbuild.formatMessages() характерно для следующих архитектур:

  • собственные сборочные системы поверх esbuild
  • интеграция в тестовые раннеры
  • обработка ошибок в веб-интерфейсах сборки
  • агрегирование логов в CI/CD системах
  • создание альтернативных CLI с кастомным выводом

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


Постобработка результатов

После вызова formatMessages возможны дополнительные преобразования:

  • фильтрация строк по ключевым словам
  • агрегация повторяющихся ошибок
  • преобразование в HTML или JSON-структуры
  • группировка по файлам или плагинам

Пример группировки:

const grouped = formatted.reduce((acc, msg) => {
  const file = msg.split(":")[0];
  acc[file] = acc[file] || [];
  acc[file].push(msg);
  return acc;
}, {});

Особенности интеграции с плагинами

Плагины esbuild могут генерировать собственные сообщения, которые полностью совместимы с formatMessages. Поле pluginName добавляет контекст происхождения ошибки, что критично при сложной цепочке трансформаций.

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


Поведение при пустых данных

Если массив сообщений пуст:

  • функция возвращает пустой массив
  • побочных эффектов не возникает
  • форматирование пропускается без ошибок

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


Производительность форматирования

Функция оптимизирована для обработки больших массивов сообщений:

  • линейная сложность по количеству сообщений
  • отсутствие I/O операций
  • отсутствие глобального состояния

При больших сборках (тысячи сообщений) основное влияние на производительность оказывает не форматирование, а генерация самих сообщений esbuild.