Разница между watch mode и dev server

Режим наблюдения (watch mode) — механизм автоматического отслеживания изменений файлов проекта с последующей повторной сборкой. После запуска Webpack не завершает процесс, а остаётся активным и следит за изменениями зависимостей.

Простейший запуск:

webpack --watch

Альтернативный вариант через конфигурацию:

module.exports = {
    mode: 'development',

    watch: true
};

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

Пример вывода:

asset bundle.js 210 KiB
cached modules 180 KiB
webpack compiled successfully in 430 ms

Ключевая особенность watch mode — отсутствие HTTP-сервера. Webpack только пересобирает проект, но не обслуживает его в браузере.


Принцип работы watch mode

Во время первой сборки Webpack формирует граф зависимостей:

index.js
 ├── app.js
 ├── styles.css
 └── utils.js

После этого система отслеживает изменения файлов:

  • JavaScript
  • CSS
  • SCSS
  • изображения
  • шаблоны
  • любые подключённые ресурсы

При изменении файла происходит:

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

Если проект использует:

output: {
    path: path.resolve(__dirname, 'dist')
}

то после каждой пересборки обновляется содержимое директории dist.


Особенности watch mode

Работа только со сборкой

watch не запускает веб-сервер:

Нет:
- localhost
- live reload
- HMR
- автоматического обновления браузера

Для просмотра изменений требуется отдельный сервер:

npx serve dist

или:

php -S localhost:3000

Файлы записываются на диск

В режиме watch результат сборки физически сохраняется:

dist/
 ├── bundle.js
 └── styles.css

Это важно для:

  • серверных приложений;
  • интеграции с backend;
  • CMS;
  • SSR;
  • Bitrix;
  • WordPress;
  • Laravel;
  • Express.

Минимальная инфраструктура

watch mode не создаёт:

  • WebSocket-соединения;
  • dev middleware;
  • клиентские runtime-компоненты;
  • HMR-инъекции.

Из-за этого режим:

  • потребляет меньше памяти;
  • проще в отладке;
  • ближе к production-сборке.

Настройки watch mode

watchOptions

Webpack позволяет гибко управлять механизмом наблюдения.

Пример:

module.exports = {
    watch: true,

    watchOptions: {
        aggregateTimeout: 300,
        poll: 1000,
        ignored: /node_modules/
    }
};

aggregateTimeout

Задержка перед пересборкой.

aggregateTimeout: 300

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


poll

Включает polling-режим.

poll: 1000

Webpack будет проверять изменения раз в секунду.

Используется:

  • в Docker;
  • WSL;
  • виртуальных машинах;
  • сетевых файловых системах;
  • некоторых Linux-конфигурациях.

ignored

Исключение директорий:

ignored: /node_modules/

Позволяет уменьшить нагрузку на файловую систему.


Webpack Dev Server

webpack-dev-server — отдельный пакет, создающий полноценную среду разработки.

Установка:

npm install webpack-dev-server --save-dev

Запуск:

npx webpack serve

или:

{
    "scripts": {
        "dev": "webpack serve"
    }
}

Что делает dev server

webpack-dev-server объединяет несколько механизмов:

  • HTTP-сервер;
  • watch mode;
  • live reload;
  • HMR;
  • middleware;
  • websocket-коммуникацию;
  • in-memory сборку.

Фактически это надстройка над обычным watch mode.


Архитектура dev server

Во время запуска создаётся:

Browser
   ↕ WebSocket
Dev Server
   ↕
Webpack Compiler

Процесс работы:

  1. браузер открывает страницу;
  2. dev server отдаёт bundle;
  3. браузер подключается через WebSocket;
  4. Webpack отслеживает изменения;
  5. сервер сообщает браузеру об обновлении;
  6. браузер обновляет страницу или модуль.

Главное отличие: запись на диск

Watch mode

Файлы сохраняются:

dist/bundle.js

Dev Server

По умолчанию сборка хранится в памяти:

Memory FS

Физического файла может вообще не существовать.

Это ускоряет работу, поскольку отсутствуют операции записи на диск.


Проверка отличий

Watch mode

webpack --watch

После сборки:

dist/
 └── bundle.js

Файл реально существует.


Dev server

webpack serve

В браузере bundle работает, но файл может отсутствовать:

dist/
 └── (пусто)

Потому что используется виртуальная файловая система.


Скорость работы

Watch mode

Цепочка работы:

Изменение файла
    ↓
Пересборка
    ↓
Запись на диск
    ↓
Обновление вручную

Dev server

Цепочка:

Изменение файла
    ↓
Пересборка в памяти
    ↓
WebSocket уведомление
    ↓
Автообновление браузера

Из-за отсутствия дисковых операций dev server обычно быстрее.


Live Reload

Watch mode

Не поддерживает автоматическое обновление браузера.

После изменения кода требуется:

F5

Dev Server

Поддерживает Live Reload автоматически.

Пример:

module.exports = {
    devServer: {
        liveReload: true
    }
};

При изменении файла браузер автоматически перезагружается.


Hot Module Replacement

Watch mode

HMR отсутствует полностью.

Изменение файла требует:

полной пересборки
+ полной перезагрузки страницы

Dev Server

Поддерживает HMR.

Пример:

module.exports = {
    devServer: {
        hot: true
    }
};

Изменяется только конкретный модуль:

styles.css

без полной перезагрузки страницы.


Как работает HMR

При изменении модуля:

Button.js

Webpack:

  1. пересобирает только изменённый модуль;
  2. создаёт update chunk;
  3. отправляет уведомление через WebSocket;
  4. браузер загружает обновление;
  5. runtime заменяет модуль.

Это существенно ускоряет разработку крупных SPA.


HTTP-сервер

Watch mode

Не предоставляет сервер.

Для запуска проекта необходим отдельный инструмент:

  • Nginx;
  • Apache;
  • Express;
  • serve;
  • Lite Server;
  • PHP server.

Dev Server

Содержит встроенный HTTP-сервер.

По умолчанию:

http://localhost:8080

Proxy

Watch mode

Proxy отсутствует.


Dev Server

Имеется встроенный proxy middleware.

Пример:

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://localhost:3001'
            }
        }
    }
};

Запрос:

/api/users

будет проксирован на backend.

Это особенно важно для:

  • SPA;
  • React;
  • Vue;
  • REST API;
  • microservices.

History API Fallback

Watch mode

Не умеет обрабатывать SPA-маршруты.


Dev Server

Поддерживает fallback:

module.exports = {
    devServer: {
        historyApiFallback: true
    }
};

Маршрут:

/profile/settings

будет перенаправлен на:

index.html

Middleware

Watch mode

Не предоставляет middleware API.


Dev Server

Работает поверх Express middleware.

Поддерживаются:

  • custom middleware;
  • headers;
  • compression;
  • rewrite;
  • proxy;
  • mock API.

Пример:

module.exports = {
    devServer: {
        setupMiddlewares: (middlewares, devServer) => {
            devServer.app.get('/ping', (req, res) => {
                res.json({ status: 'ok' });
            });

            return middlewares;
        }
    }
};

Использование в backend-проектах

Watch mode подходит лучше

Особенно для:

  • Bitrix;
  • WordPress;
  • Laravel;
  • Symfony;
  • Yii;
  • Express SSR.

Причина проста:

backend ожидает реальные файлы

Например:

<script src="/dist/bundle.js"></script>

Backend читает файл из файловой системы.


Dev Server подходит для frontend-разработки

Особенно для:

  • React;
  • Vue;
  • Angular;
  • SPA;
  • microfrontend;
  • Vite-подобного DX.

Нагрузка на систему

Watch mode

Обычно:

  • меньше RAM;
  • меньше CPU;
  • проще инфраструктура.

Dev Server

Дополнительно запускает:

  • websocket server;
  • middleware stack;
  • live reload;
  • HMR runtime;
  • memory filesystem.

Потребление ресурсов выше.


Сравнение поведения

Возможность Watch Mode Dev Server
Автоматическая пересборка Да Да
HTTP-сервер Нет Да
Live Reload Нет Да
HMR Нет Да
Proxy Нет Да
History API Fallback Нет Да
Запись файлов на диск Да Обычно нет
WebSocket Нет Да
Middleware Нет Да
Скорость обновления Ниже Выше
Подходит для backend Да Частично
Подходит для SPA Ограниченно Отлично

Когда использовать watch mode

Интеграция с CMS

Например:

  • Bitrix;
  • WordPress;
  • Drupal.

Backend работает с физическими файлами:

/dist/app.js

SSR и backend rendering

Node.js-серверу нужны реальные assets:

fs.readFileSync()

Простая инфраструктура

Когда не нужны:

  • HMR;
  • proxy;
  • live reload;
  • SPA routing.

Production-like среда

watch mode ближе к реальной production-сборке, поскольку:

  • файлы пишутся на диск;
  • отсутствует memory filesystem;
  • нет dev runtime.

Когда использовать dev server

SPA-приложения

React/Vue/Angular-проекты получают:

  • HMR;
  • быстрые обновления;
  • proxy;
  • live reload.

Активная UI-разработка

Изменение:

.button {
    color: red;
}

мгновенно появляется в браузере без полной перезагрузки страницы.


Разделение frontend/backend

Frontend запускается отдельно:

localhost:8080

Backend:

localhost:3000

API связывается через proxy.


Комбинирование режимов

Иногда используются оба варианта одновременно.

Пример:

{
    "scripts": {
        "watch": "webpack --watch",
        "dev": "webpack serve"
    }
}

Типичная схема

Backend-разработка

npm run watch

Frontend SPA

npm run dev

Типичные ошибки

Ожидание HMR в watch mode

Ошибка:

webpack --watch

не поддерживает hot reload.


Ожидание файлов в dist при dev server

При использовании:

webpack serve

файлы могут отсутствовать физически.


Смешивание backend и dev server

Backend пытается читать:

dist/bundle.js

но dev server хранит сборку в памяти.


devMiddleware.writeToDisk

Dev server умеет записывать файлы на диск.

Пример:

module.exports = {
    devServer: {
        devMiddleware: {
            writeToDisk: true
        }
    }
};

Теперь:

  • dev server сохраняет преимущества HMR;
  • файлы появляются в dist.

Это полезно для интеграции frontend и backend.


Внутреннее различие архитектур

Watch mode

Основа:

Webpack Compiler

Dev Server

Основа:

Webpack Compiler
+ Dev Middleware
+ Express Server
+ WebSocket Server
+ HMR Runtime

По сути, webpack-dev-server — полноценная платформа разработки поверх обычного compiler API Webpack.