Встроенные окружения: client, ssr, workerd

Встроенная модель окружений Vite основана на разделении исполнения кода на несколько независимых контекстов, каждый из которых имеет собственные правила резолвинга модулей, доступные API и модель выполнения. Такой подход позволяет унифицировать разработку приложений, которые одновременно поддерживают браузерный рендеринг, серверный рендеринг и edge-окружения, сохраняя при этом согласованную систему сборки и HMR.

Архитектурно окружения Vite строятся вокруг идеи изолированных графов модулей. Каждый граф соответствует конкретной среде выполнения, где отличаются не только цели бандлинга, но и способы интерпретации зависимостей, формат модулей, а также доступ к встроенным объектам среды. Основные встроенные окружения включают client, ssr и workerd.


Client-окружение представляет классическую браузерную среду выполнения. Именно сюда попадает основной фронтенд-бандл, исполняемый в браузере через ES-модули.

Ключевой характеристикой client-окружения является ориентация на нативную загрузку модулей в браузере, где Vite активно использует ESM без предварительного полного бандлинга в dev-режиме. Вместо этого применяется трансформация “на лету” с последующей доставкой модулей через dev-сервер.

Основные особенности client-окружения:

  • выполнение кода в браузере с доступом к DOM, Window и Web APIs
  • использование ESM-формата как базового
  • поддержка HMR через WebSocket соединение с dev-сервером
  • оптимизация зависимостей через pre-bundling (esbuild)
  • разделение на чанки только в production-сборке

Граф модулей client-окружения строится вокруг entry-файла фронтенда. Все импорты анализируются Vite, после чего формируется карта зависимостей. В dev-режиме каждый модуль остаётся отдельной единицей доставки, что снижает стоимость пересборки при изменениях.

Отдельное значение имеет механизм обработки сторонних зависимостей. Библиотеки из node_modules предварительно преобразуются в формат, совместимый с браузером, поскольку исходный формат может включать CommonJS или Node.js специфичные конструкции.


ssr environment

SSR-окружение предназначено для серверного рендеринга. Оно выполняется в Node.js или совместимых runtime и отличается принципиально иной моделью выполнения модулей.

Основное отличие ssr-окружения заключается в том, что оно ориентировано не на работу с DOM, а на генерацию HTML на сервере. В результате часть API браузера отсутствует, но доступны серверные возможности, включая файловую систему, сетевые запросы и Node.js встроенные модули.

Внутри Vite SSR-окружение формирует отдельный граф модулей, который не пересекается напрямую с client-графом. Это позволяет:

  • исключать браузерные зависимости из серверной сборки
  • заменять импорты на SSR-совместимые реализации
  • управлять external-зависимостями (externalization)
  • обеспечивать изоляцию между серверным и клиентским кодом

SSR-граф работает в формате ESM в большинстве современных конфигураций. Однако Vite также поддерживает интероперабельность с CommonJS модулями через трансформацию.

Особое значение имеет механизм ssrLoadModule, который позволяет загружать модули по требованию во время серверного рендеринга. Такой подход обеспечивает близость к dev-режиму, где изменения кода могут отражаться без полной пересборки приложения.

SSR-окружение тесно связано с понятием hydration. Код, исполняемый на сервере, подготавливает структуру приложения, которая затем повторно активируется в client-окружении. При этом важно, что один и тот же модуль может иметь разное поведение в зависимости от среды выполнения.

Для управления различиями между окружениями используется условная логика и специальные флаги сборки, позволяющие разделять server-only и client-only код.


workerd environment

Workerd-окружение представляет edge-runtime модель, ориентированную на выполнение кода в средах типа Cloudflare Workers. В отличие от Node.js, workerd не имеет полноценной файловой системы и использует ограниченный набор Web-стандартов API.

Vite включает поддержку workerd как отдельного окружения для построения серверной логики, которая может исполняться ближе к пользователю на edge-инфраструктуре.

Основные характеристики workerd-окружения:

  • выполнение в V8 isolate без полноценного Node.js runtime
  • ограниченный доступ к API, ориентированный на Web стандарты
  • высокая производительность холодного старта
  • глобальная распределённая инфраструктура выполнения
  • отсутствие традиционной файловой системы

В контексте Vite workerd-окружение формирует отдельный граф модулей, аналогичный SSR, но с дополнительными ограничениями совместимости. Это требует иной стратегии работы с зависимостями:

  • исключение Node.js встроенных модулей
  • замена файловых операций на fetch-based подходы или KV-хранилища
  • адаптация библиотек под edge-совместимый формат

Ключевой особенностью является то, что workerd-окружение часто используется совместно с SSR-моделью, где часть логики выполняется на edge, а часть — на клиенте. Это приводит к гибридной архитектуре, в которой Vite координирует несколько окружений одновременно.


Изоляция окружений и графы модулей

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

Изоляция достигается через:

  • раздельные резолверы модулей
  • независимые трансформации кода
  • различия в external-зависимостях
  • отдельные кэши HMR и сборки

Такая модель позволяет избежать конфликтов между server и client реализациями библиотек, которые часто используют разные entry-points (например, browser build и node build).

Важным элементом является возможность маршрутизации модулей между окружениями. Некоторые модули могут быть явно помечены как принадлежащие SSR или client графу, что позволяет Vite корректно формировать зависимости и избегать попадания несовместимого кода в неподходящую среду.


Совместная работа client, ssr и workerd

При построении современных приложений редко используется только одно окружение. Чаще формируется связка, где client отвечает за UI, ssr — за первичный рендеринг, workerd — за edge-логику.

В такой архитектуре Vite выполняет роль координационного слоя, который:

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

Особое значение приобретает единый исходный код, который адаптируется под разные среды через условные экспорты и контекстные проверки окружения. При этом Vite сохраняет консистентность между dev и production режимами, минимизируя расхождения в поведении модулей.


Контекст выполнения и различия runtime

Различия между окружениями определяются не только API, но и фундаментальными ограничениями runtime:

  • client ориентирован на интерактивность и DOM
  • ssr ориентирован на генерацию представления
  • workerd ориентирован на масштабируемую распределённую обработку

Vite абстрагирует эти различия через систему окружений, где каждый runtime рассматривается как самостоятельная цель сборки. Это позволяет строить приложения, в которых один кодовый базис обслуживает несколько уровней исполнения без дублирования логики.


Механика резолвинга зависимостей

Резолвинг в разных окружениях отличается поведением:

  • client использует browser-ориентированные entry-points пакетов
  • ssr предпочитает node-ориентированные сборки
  • workerd требует ESM-совместимые и edge-safe зависимости

При этом Vite анализирует поле exports в package.json и выбирает соответствующую ветку импорта. В SSR и workerd режимах дополнительно применяется externalization для предотвращения избыточного бандлинга серверных библиотек.


HMR и окружения

Hot Module Replacement работает только в client-окружении напрямую, но его эффекты могут транслироваться в SSR через пересоздание серверного графа модулей.

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


Гибридные сценарии

Комбинация client + ssr + workerd позволяет реализовывать архитектуры с распределённой логикой:

  • SSR обеспечивает первичный HTML и SEO
  • client отвечает за интерактивность и состояние UI
  • workerd обрабатывает API-уровень ближе к пользователю

Vite объединяет эти уровни через единый инструмент сборки, сохраняя при этом независимость окружений и предотвращая утечки несовместимого кода между ними.