Одновременное использование watch и serve

В процессе разработки фронтенд-приложений часто требуется одновременно выполнять две задачи: отслеживать изменения исходного кода и мгновенно обновлять результат в браузере через локальный сервер. В esbuild эти возможности реализуются через два механизма — наблюдение за файлами (watch) и встроенный HTTP-сервер (serve). Их совместное использование формирует минималистичную, но высокопроизводительную среду разработки без внешних инструментов сборки.


Watch: механизм наблюдения за изменениями

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

Поведение watch-режима

При активации watch:

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

Ключевая особенность — отсутствие постоянного пересоздания процесса сборки. esbuild сохраняет внутреннее состояние, что ускоряет последующие итерации.

API-использование watch

import * as esbuild from "esbuild";

await esbuild.build({
  entryPoints: ["src/index.js"],
  outfile: "dist/bundle.js",
  bundle: true,
  watch: {
    onRebuild(error, result) {
      if (error) {
        console.error("Ошибка пересборки:", error);
      } else {
        console.log("Пересборка завершена");
      }
    }
  }
});

Особенности поведения

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

Serve: встроенный HTTP-сервер

Механизм serve предоставляет минимальный HTTP-сервер, предназначенный для разработки. Он не является полноценным production-сервером и используется исключительно для локальной раздачи собранных файлов.

Основные характеристики serve

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

Serve чаще всего используется вместе с watch, чтобы обеспечить автоматическое обновление файлов в браузере.


Комбинирование watch и serve

Совместное использование этих режимов позволяет организовать непрерывный цикл разработки:

  1. serve поднимает HTTP-сервер;
  2. watch отслеживает изменения исходников;
  3. при изменении файлов выполняется пересборка;
  4. сервер раздаёт обновлённые файлы без перезапуска процесса.

Важно понимать, что esbuild не выполняет автоматическую перезагрузку браузера. Обновление страницы остаётся задачей внешнего инструмента (например, livereload-сервера или расширений).


Пример использования через CLI

В CLI оба режима активируются одновременно:

esbuild src/index.js \
  --bundle \
  --outfile=dist/bundle.js \
  --serve=8000 \
  --watch

Поведение CLI-конфигурации

  • сервер запускается на порту 8000;
  • сборка выполняется при старте;
  • любые изменения файлов вызывают пересборку;
  • процесс остаётся активным до ручной остановки.

Пример использования через Node.js API

Более гибкий контроль достигается через API:

import * as esbuild from "esbuild";

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

await ctx.watch();

await ctx.serve({
  port: 8000,
  servedir: "dist"
});

Особенности context API

Новые версии esbuild используют контекстную модель:

  • context() создаёт изолированную среду сборки;
  • watch() активирует наблюдение;
  • serve() запускает сервер поверх контекста.

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


Обработка пересборок и onRebuild

Механизм onRebuild используется для реакции на каждую пересборку.

watch: {
  onRebuild(error, result) {
    if (error) {
      console.error("Ошибка:", error);
      return;
    }

    console.log("Сборка обновлена");
  }
}

Сценарии использования

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

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


Инкрементальные сборки и контекст выполнения

Esbuild оптимизирует повторные сборки за счёт инкрементального анализа:

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

Контекст (context) усиливает этот механизм, позволяя:

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

Типичные проблемы и ограничения

Отсутствие встроенного HMR

Esbuild не предоставляет hot module replacement. Пересборка обновляет файлы, но не управляет состоянием приложения в браузере.

Ограниченность serve

Встроенный сервер:

  • не поддерживает сложную маршрутизацию;
  • не заменяет полноценные backend-серверы;
  • предназначен только для разработки.

Поведение при ошибках сборки

  • serve продолжает работать даже при ошибках;
  • предыдущий успешный билд остаётся доступным;
  • watch не прерывается при сбоях компиляции.

Файловые ограничения

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


Архитектурная модель совместной работы

Комбинация watch и serve формирует цикл:

  • файловый watcher фиксирует изменения;
  • граф зависимостей пересобирается инкрементально;
  • артефакты обновляются в выходной директории;
  • HTTP-сервер отдает актуальную версию;
  • внешние инструменты могут реагировать на изменения.

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