В основе работы esbuild лежит отдельный компилирующий сервис, реализованный на языке Go и запускаемый как дочерний процесс. JavaScript-обёртка взаимодействует с ним через IPC (межпроцессное взаимодействие), передавая задачи сборки и получая результаты обратно. Такой подход обеспечивает высокую скорость, так как основная нагрузка выполняется вне V8 и не блокирует event loop.
При инициализации через esbuild.startService() создаётся
долгоживущий процесс, который хранит состояние между сборками: кеши,
модули, граф зависимостей и внутренние структуры оптимизации. Это
позволяет значительно ускорять повторные сборки.
Однако наличие постоянного дочернего процесса требует явного
управления его жизненным циклом. Для этого используется метод завершения
сервиса — stop().
Метод stop() предназначен для корректного завершения
работы фонового процесса esbuild, созданного через
startService().
Ключевая функция:
После вызова stop() сервис становится недоступным для
дальнейших операций сборки.
При вызове service.stop() происходит последовательность
операций:
Важно, что esbuild старается завершиться корректно, дождавшись окончания активных сборок, а не прерывая их мгновенно.
Метод stop() возвращает Promise и работает
асинхронно.
import * as esbuild from 'esbuild';
const service = await esbuild.startService();
// выполнение сборок
await service.build({
entryPoints: ['src/index.js'],
outfile: 'dist/bundle.js'
});
// завершение сервиса
await service.stop();
Асинхронная природа связана с тем, что необходимо дождаться:
Если в момент вызова stop() выполняется сборка, esbuild
переходит в режим контролируемого завершения:
Принудительного убийства процесса по умолчанию не происходит, что минимизирует риск повреждения состояния или частично записанных файлов.
Повторный вызов stop() после завершения сервиса:
Сервис после остановки считается одноразовым объектом жизненного цикла.
Возможны ситуации, когда остановка вызывается параллельно с другими операциями:
build() в процессе выполненияwatch() режим активенВ таких случаях esbuild координирует очередь задач, однако при неправильном порядке вызовов может возникать:
Особое поведение наблюдается при использовании watch API.
При активном наблюдении за файлами:
stop() наблюдатель также завершаетсяТаким образом, stop() является универсальным способом
завершения всей инфраструктуры esbuild-сервиса.
В серверных приложениях (например, Node.js API или SSR-серверах)
esbuild часто используется как фоновый компилятор. В таких случаях
stop() становится частью процедуры graceful shutdown:
process.on('SIGTERM', async () => {
await service.stop();
process.exit(0);
});
Это предотвращает появление «зависших» процессов после остановки приложения.
После выполнения stop() освобождаются:
На уровне операционной системы дочерний процесс полностью исчезает, что особенно важно для контейнеризированных сред и CI/CD систем.
Некоторые инструменты используют принудительное завершение процессов
через kill. В esbuild такой подход не является основным,
поскольку:
stop() реализует мягкое завершение, ориентированное на
корректность и детерминированность состояния.
Пара startService() и stop() образует
замкнутый цикл управления процессом:
startService() — создание долгоживущего компиляционного
процессаstop() — завершение этого процесса и очистка средыТакой подход делает esbuild пригодным для:
При этом каждый сервисный инстанс существует независимо и требует
явного завершения через stop().