Пересборка в esbuild реализуется через режим наблюдения за файловой
системой и инкрементальную компиляцию, при которой повторные запуски
сборки используют уже построенные графы модулей и кэшированные
результаты трансформаций. Основной механизм, отвечающий за реакцию на
изменения исходного кода, связан с watch-режимом и функцией
обратного вызова onRebuild.
В отличие от классических сборщиков, где пересборка часто представляет собой повторный полный прогон пайплайна, esbuild старается минимизировать объём повторной работы. Это достигается за счёт сохранения состояния зависимостей модулей и повторного использования уже разобранных AST-подобных структур внутри собственного представления.
Режим наблюдения включается через параметр watch при
запуске build. Внутри этого режима можно определить функцию
onRebuild, которая вызывается каждый раз при обнаружении
изменений в файловой системе и завершении повторной сборки.
import * as esbuild from 'esbuild';
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
watch: {
onRebuild(error, result) {
if (error) {
console.error('Ошибка пересборки:', error);
return;
}
console.log('Пересборка завершена');
}
}
});
Callback onRebuild является ключевым механизмом
интеграции esbuild в среды разработки. Он позволяет подключать любые
внешние процессы: обновление браузера, инвалидацию кэша, перезапуск
серверов или логирование состояния сборки.
Функция onRebuild принимает два аргумента:
error — объект ошибки, возникающий при неуспешной
пересборкеresult — результат успешной сборки, аналогичный
результату первичного buildЛогика обработки обычно строится вокруг проверки наличия ошибки, поскольку esbuild не выбрасывает исключения в привычном синхронном смысле внутри callback.
onRebuild(error, result) {
if (error) {
// Ошибка компиляции или проблема файловой системы
return;
}
// Доступ к метаданным сборки
const { warnings, outputFiles } = result;
}
Объект result содержит метаданные текущей сборки: список
предупреждений, карту модулей, информацию о маппинге исходников, а также
результаты генерации выходных файлов при использовании in-memory
режима.
Ошибки пересборки делятся на две категории: синтаксические ошибки в исходном коде и системные ошибки наблюдения файловой системы.
При синтаксических ошибках error передаётся в
onRebuild, при этом esbuild продолжает наблюдение за
файлами. Это важно: система не прекращает работу при ошибках компиляции,
позволяя разработчику исправить код без перезапуска процесса.
Системные ошибки (например, потеря доступа к файлам или сбой watcher’а) могут привести к остановке режима наблюдения, в зависимости от окружения и платформы.
Одним из ключевых механизмов ускорения является инкрементальная пересборка. При первом запуске строится полный граф зависимостей:
При последующих изменениях esbuild не пересчитывает весь граф заново. Вместо этого он:
Это поведение особенно заметно в проектах с большим количеством модулей, где изменения локализованы в отдельных частях системы.
Объект результата при пересборке сохраняет структуру, аналогичную первичной сборке, однако его содержимое отражает только актуальное состояние после изменений.
Типичные поля результата:
warnings — предупреждения компиляцииerrors — ошибки (если не переданы через callback)metafile — метаданные графа зависимостейoutputFiles — массив сгенерированных файлов (при
соответствующей настройке)При использовании write: false результат может содержать
данные в памяти, что позволяет интегрировать esbuild в кастомные
пайплайны без записи на диск.
Callbacks пересборки часто используются как слой интеграции с HTTP-серверами разработки. Типичный сценарий включает:
onRebuildПростейшая схема взаимодействия:
let server;
esbuild.build({
entryPoints: ['src/app.js'],
bundle: true,
outfile: 'dist/app.js',
watch: {
onRebuild(error) {
if (error) return;
if (server) {
server.invalidate();
}
}
}
});
В более сложных системах callback используется для реализации HMR (Hot Module Replacement), где пересобранные модули заменяются без полной перезагрузки страницы.
Несмотря на гибкость, callback onRebuild имеет ряд
архитектурных ограничений:
Это делает API предсказуемым, но требует дополнительной логики при построении сложных dev-инструментов.
В современных версиях esbuild логика watch может быть интегрирована через контекст сборки, где создаётся управляемый экземпляр сборщика с возможностью явного управления жизненным циклом.
В такой модели пересборка становится частью долгоживущего процесса:
Callback onRebuild сохраняет роль точки синхронизации
между внутренним механизмом пересборки и внешним приложением, но
управление состоянием выносится в контекст.
При изменении исходного файла внутри watch-режима происходит последовательность шагов:
onRebuildЭта последовательность оптимизирована под минимизацию задержек между сохранением файла и обновлением результата, что критично для интерактивной разработки.
При серии быстрых изменений файлов esbuild агрегирует события файловой системы. Вместо запуска отдельной пересборки на каждое изменение, система объединяет изменения в один цикл пересборки.
Это снижает нагрузку и предотвращает каскадные перестройки графа
модулей. Callback onRebuild при этом вызывается только один
раз после завершения агрегированной сборки.
Результат, передаваемый в onRebuild, часто используется
как источник данных для внешних систем:
Интеграция строится вокруг идеи, что esbuild предоставляет только вычислительный слой, а вся оркестрация процессов остаётся на стороне приложения.
В реальных проектах callback пересборки используется в нескольких устойчивых паттернах:
Логирование и метрики Сбор времени пересборки и
количества затронутых модулей через анализ result.
HMR-посредник Проксирование изменений в браузер через WebSocket канал.
Fail-safe режим Игнорирование ошибок пересборки при сохранении предыдущего состояния приложения в памяти.
Кэш-инвалидация Сброс локальных кэшей серверной логики при успешной пересборке.
В крупных кодовых базах поведение callback становится чувствительным к структуре зависимостей. Глубоко вложенные графы увеличивают стоимость пересборки затронутых модулей, однако благодаря инкрементальной модели влияние ограничивается локальными областями.
При этом onRebuild остаётся стабильной точкой входа для
внешней логики, независимо от сложности внутреннего графа.