Плюрализация

Fresh — современный фреймворк для создания высокопроизводительных веб-приложений на JavaScript и Deno. Он сочетает преимущества реактивного рендеринга с минимальным размером клиентского кода, обеспечивая мгновенную загрузку страниц и низкую задержку взаимодействия. Основной принцип Fresh заключается в серверной генерации страниц (SSR) с возможностью гидратации отдельных компонентов на клиенте только при необходимости.


Архитектура приложений Fresh

Приложения Fresh строятся вокруг концепции routes и islands.

  • Routes — это серверные обработчики URL, которые формируют HTML-страницы. Каждый файл в папке routes/ автоматически становится маршрутом. Например, файл routes/about.tsx соответствует пути /about.
  • Islands — это интерактивные компоненты, которые можно гидратировать на клиенте. Они позволяют минимизировать объем JavaScript на странице, загружая только необходимый код для интерактивных частей.

Ключевой момент: Fresh использует стратегию islands architecture, при которой большая часть страницы статична и создается на сервере, а динамические элементы становятся интерактивными без полной гидратации всей страницы.


Работа с компонентами

Компоненты в Fresh пишутся на JSX/TSX и могут быть как полностью статическими, так и интерактивными. Для интерактивности используется директива client:load или client:visible:

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onCl ick={() => setCount(count + 1)}>
      Счетчик: {count}
    </button>
  );
}
  • client:load — компонент загружается сразу после загрузки страницы.
  • client:visible — компонент загружается только когда становится видимым в области просмотра (lazy loading).

Использование этих директив позволяет оптимизировать производительность, снижая количество JavaScript, передаваемого клиенту.


Плюрализация и локализация

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

  • Для управления локалями создается объект i18n, который содержит ключи перевода.
  • Компоненты получают текущую локаль через контекст или параметр маршрута.

Пример структуры локализации:

const messages = {
  en: { greeting: "Hello" },
  ru: { greeting: "Привет" },
};

function Greeting({ locale }: { locale: "en" | "ru" }) {
  return <h1>{messages[locale].greeting}</h1>;
}

Fresh поддерживает динамическую смену языка через маршруты, например /ru/about или /en/about, что позволяет легко масштабировать приложения на международный рынок.


Работа с серверной логикой

В Fresh серверная логика отделена от клиентской, что упрощает работу с данными и API.

  • Handlers — функции, обрабатывающие запросы. Они находятся в файлах маршрутов и могут возвращать JSON или HTML:
export const handler = {
  GET: async (_req, _ctx) => {
    const data = await fetchSomeData();
    return new Response(JSON.stringify(data), {
      headers: { "Content-Type": "application/json" },
    });
  },
};
  • Серверная логика может взаимодействовать с базами данных, кэшами и сторонними API без влияния на клиентский код.

Использование server-first подхода позволяет уменьшить объем фронтенд-кода, ускорить рендеринг страниц и обеспечить лучшую SEO-оптимизацию.


Оптимизация и кэширование

Fresh встроенно поддерживает кэширование и оптимизацию загрузки:

  • Статические страницы автоматически кэшируются на сервере.
  • JS и CSS минимизируются и загружаются только при необходимости через islands.
  • Настраивается HTTP-кэширование и контроль версий ассетов, что снижает нагрузку на сеть и ускоряет повторные загрузки страниц.

Подключение сторонних библиотек

Fresh позволяет использовать любые библиотеки на Deno или через CDN. Для этого достаточно импортировать модуль напрямую в код компонента:

import { format } from "https://deno.land/std/datetime/mod.ts";

export default function Time() {
  const now = format(new Date(), "yyyy-MM-dd HH:mm:ss");
  return <p>Текущее время: {now}</p>;
}

Ключевое преимущество — отсутствие необходимости в сборщике вроде Webpack, что упрощает разработку и снижает время сборки проекта.


Роутинг и динамические параметры

Fresh поддерживает динамические маршруты через квадратные скобки:

routes/
  blog/
    [id].tsx

В компоненте [id].tsx доступен параметр id:

export default function BlogPost({ params }: { params: { id: string } }) {
  return <h1>Пост #{params.id}</h1>;
}

Динамический роутинг вместе с серверными обработчиками обеспечивает гибкость при работе с REST API и SEO-оптимизированными страницами.


Интеграция с формами и состоянием

Fresh упрощает работу с формами через стандартные HTML-формы и серверные обработчики:

export const handler = {
  POST: async (req: Request) => {
    const formData = await req.formData();
    const name = formData.get("name");
    return new Response(`Привет, ${name}`);
  },
};

export default function Form() {
  return (
    <form method="POST">
      <input name="name" />
      <button type="submit">Отправить</button>
    </form>
  );
}
  • Данные обрабатываются на сервере без дополнительного клиентского кода.
  • В сочетании с islands можно делать интерактивные формы без полной гидратации страницы.

Fresh сочетает минимализм клиентского кода, мощный серверный рендеринг, гибкий роутинг и встроенную поддержку локализации, что делает его идеальным инструментом для современных веб-приложений с высокой производительностью и масштабируемостью.