В системе esbuild сообщения об ошибках и предупреждениях строятся вокруг унифицированной структуры данных, которая существует одновременно в двух формах: внутренней (объекты JavaScript API) и текстовой (вывод CLI). Несмотря на различие представления, оба варианта отражают одну и ту же диагностическую модель, включающую текст сообщения, контекст исходного кода и метаданные о месте возникновения проблемы.
Ключевая особенность заключается в том, что esbuild стремится минимизировать избыточность вывода, сохраняя при этом достаточную информацию для точной локализации ошибки без необходимости дополнительной трассировки.
При использовании esbuild через JavaScript API ошибки и
предупреждения возвращаются в виде массивов errors и
warnings, содержащих объекты диагностик.
Типичная структура объекта ошибки:
{
text: "Unexpected token",
location: {
file: "src/index.js",
line: 12,
column: 18,
length: 1,
lineText: "const x = import.meta.env",
suggestion: ""
},
notes: [],
detail: undefined
}
text Основное сообщение ошибки или предупреждения. Содержит краткое описание проблемы без избыточного контекста.
location Объект, описывающий точку возникновения проблемы:
file — путь к файлуline — номер строки (1-based)column — номер столбца (1-based)length — длина фрагмента кода, связанного с
ошибкойlineText — строка исходного кода целикомsuggestion — дополнительная подсказка (используется не
всегда)notes Массив дополнительных сообщений, связанных с основной ошибкой. Используется для цепочек причин, например при ошибках импорта или трансформации.
В CLI esbuild форматирует ошибки в человекочитаемом виде с акцентом на контекст строки и позиционирование указателя.
Пример типичного вывода:
error: Unexpected token
src/index.js:12:18:
12 │ const x = import.meta.env
╵ ^
Особенности CLI-формата:
error или
warning)^ или аналог) визуально показывает точное
местоПредупреждения структурно идентичны ошибкам, но не прерывают процесс
сборки. Они также присутствуют в warnings массива
результата API.
Пример:
warning: The "this" expression is undefined in ES module scope
src/module.js:3:1:
3 │ this.doSomething()
╵ ~~~~
Различие между ошибками и предупреждениями заключается не в структуре, а в семантике обработки:
--bundle с игнорированием части ошибок в watch/incremental
сценариях)esbuild уделяет особое внимание точному позиционированию ошибок. Используется комбинация:
Эта комбинация позволяет восстановить контекст без полноценного AST-дампа.
Пример интерпретации:
location: {
line: 5,
column: 10,
length: 4,
lineText: "let value = fooBar()"
}
Из этого формируется визуальный указатель:
let value = fooBar()
^^^^
Если длина не определена, используется один символ или позиционный маркер.
При использовании plugin API ошибки могут генерироваться внутри хуков
(onResolve, onLoad, transform). В
этом случае esbuild добавляет дополнительную информацию о плагине:
{
text: "Could not resolve dependency",
location: {
file: "src/app.js",
line: 1,
column: 15
},
pluginName: "alias-plugin"
}
Поле pluginName позволяет определить источник ошибки в
цепочке плагинов, что особенно важно при сложной композиции
трансформаций.
Поле notes используется для формирования вложенных
диагностик.
Пример:
{
text: "Failed to resolve import",
location: {...},
notes: [
{
text: "The file does not exist",
location: {
file: "src/app.js",
line: 1,
column: 8
}
}
]
}
CLI отображает такие цепочки последовательно, создавая многоуровневый контекст причины.
При включённых source maps (sourcemap: true) esbuild
старается отображать исходные позиции до трансформации. Это влияет
на:
file (может указывать на исходный файл вместо
промежуточного)line и column (пересчитываются через
mapping)lineText (берётся из оригинального исходника)Это позволяет сохранять согласованность диагностики даже при агрессивной минификации или транспиляции.
Параметр logLevel управляет объёмом и типом выводимых
сообщений:
silent — отключает все сообщенияerror — только ошибкиwarning — ошибки и предупрежденияinfo — добавляет информационные сообщенияdebug — максимальная детализацияПри этом структура объектов errors и
warnings не меняется, меняется только уровень их
отображения в CLI и API-логике.
В режиме инкрементальной сборки (incremental: true) и
watch-режиме esbuild:
Это означает, что массив errors представляет только
актуальный снимок состояния сборки.
CLI и API используют разные стратегии представления:
CLI:
JavaScript API:
esbuild не предоставляет встроенных механизмов глубокой кастомизации форматирования ошибок. Нельзя:
errorsВозможна только внешняя обработка результата API:
const result = await esbuild.build(options)
for (const err of result.errors) {
console.error(`[${err.location?.file}] ${err.text}`)
}
Такой подход используется для интеграции с CI-системами и кастомными логгерами.
Несмотря на различие представления, CLI фактически сериализует те же объекты, что возвращаются через API. Это обеспечивает:
Различие заключается только в слое форматирования и визуализации, но не в модели данных.