Отсутствие сборки на этапе разработки

Fresh — веб-фреймворк для JavaScript и TypeScript, построенный вокруг идеи полного отказа от этапа сборки на этапе разработки. В традиционных фронтенд-проектах разработка почти всегда сопровождается bundler’ом: Webpack, Vite, Rollup или аналогами. Fresh принципиально устраняет этот слой, опираясь на возможности современных браузеров и серверной среды Deno.

Отсутствие сборки означает, что исходный код приложения используется напрямую, без предварительной компиляции, упаковки или трансформации в единый бандл. Сервер запускается мгновенно, изменения в коде отражаются сразу, а архитектура проекта остаётся максимально прозрачной.

ES-модули как фундамент

В основе подхода лежит нативная поддержка ES-модулей:

import { Handlers, PageProps } from "$fresh/server.ts";
import Counter from "../islands/Counter.tsx";

Каждый файл — это полноценный модуль, загружаемый напрямую. Нет промежуточных артефактов, нет папок dist, нет скрытых преобразований. Структура проекта совпадает с логикой приложения, а не с требованиями инструмента сборки.

Браузер и сервер понимают модули напрямую, поэтому Fresh просто проксирует запросы к ним, не вмешиваясь в код.

Разработка без ожиданий

Классическая проблема сборщиков — время. Даже быстрые инструменты требуют:

  • анализа зависимостей,
  • трансформации JSX,
  • пересборки при изменениях,
  • поддержки hot-reload.

Fresh устраняет саму необходимость этого процесса. При старте:

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

Hot reload реализован на уровне сервера: при изменении файла он просто переотдаётся заново. Никакого пересчёта графа зависимостей не требуется.

JSX без транспиляции

Fresh использует Preact и серверный рендеринг. JSX обрабатывается на сервере с помощью встроенных возможностей Deno и свежего runtime, без Babel или SWC на этапе разработки.

export default function Home() {
  return <h1>Hello Fresh</h1>;
}

Этот код исполняется напрямую. Никакой отдельной конфигурации для JSX не существует, потому что она не нужна.

Сервер как точка сборки

Важно различать отсутствие сборки и отсутствие оптимизации. Fresh не собирает проект во время разработки, но сервер берёт на себя минимальные обязанности:

  • отдача модулей;
  • кэширование;
  • преобразование импортов;
  • изоляция islands.

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

Islands Architecture без бандлинга

Архитектура islands тесно связана с отказом от сборки. Каждый интерактивный компонент — отдельный модуль:

import Counter from "../islands/Counter.tsx";

В браузер отправляется только код конкретного острова, а не весь JavaScript приложения. Благодаря отсутствию бандлинга:

  • нет единого JS-файла на всё приложение;
  • каждый island загружается по требованию;
  • код разделён логически, а не искусственно.

Это работает напрямую через ES-модули, без chunk’ов и split-points.

Простота отладки

Отладка в Fresh максимально приближена к нативной:

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

Разработчик работает с тем кодом, который написал, без прослойки абстракций.

Отсутствие конфигурации

Типичный проект с бандлером включает:

  • конфигурационные файлы;
  • плагины;
  • загрузчики;
  • алиасы;
  • версии зависимостей сборщика.

Fresh избавляется от всего этого. Нет:

  • webpack.config.js
  • vite.config.ts
  • Babel-плагинов
  • loader’ов

Вся конфигурация — это структура каталогов и импорты. Среда разработки не требует поддержки, потому что она практически отсутствует.

Влияние на архитектуру проекта

Отказ от сборки напрямую влияет на стиль проектирования:

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

Проект читается как набор стандартных ES-модулей, а не как результат сложной трансформации.

Граница между разработкой и продакшеном

На этапе продакшена Fresh всё же выполняет сборку, но это отдельный, осознанный шаг. В разработке приоритет — скорость и прозрачность. В продакшене — оптимизация и минимизация.

Такое разделение устраняет компромиссы: разработка остаётся быстрой, а финальный результат — эффективным.

Итоговая модель

Отсутствие сборки в Fresh — не упрощение ради упрощения, а следствие зрелости платформы:

  • браузеры умеют ES-модули;
  • сервер может выполнять JSX;
  • HTTP/2 и кэширование решают проблемы производительности.

Fresh использует эти возможности напрямую, убирая устаревшие слои инфраструктуры. Это делает процесс разработки линейным, предсказуемым и максимально близким к реальному выполнению кода.