Deno Deploy

Fresh — это современный веб-фреймворк на базе Deno, ориентированный на создание быстрых и эффективных приложений с минимальной загрузкой на сервер. Основная концепция Fresh — zero runtime overhead, то есть отсутствие дополнительного кода на клиенте, кроме строго необходимого. В сочетании с Deno Deploy это позволяет запускать приложения с минимальными задержками и высокой масштабируемостью.

Deno Deploy обеспечивает выполнение кода напрямую в облаке без необходимости настройки серверной инфраструктуры. Код загружается как модуль, и платформа автоматически масштабирует его выполнение, обрабатывая HTTP-запросы в реальном времени. Это делает Fresh и Deno Deploy идеальным сочетанием для серверных и серверно-клиентских приложений.


Структура проекта Fresh

Проект Fresh строится вокруг нескольких ключевых директорий:

  • routes/ — содержит маршруты приложения. Каждый файл соответствует URL-пути. Например, routes/index.tsx обрабатывает запросы к /.
  • islands/ — компоненты, которые могут быть интерактивными на клиенте. Остальная часть страницы рендерится на сервере.
  • components/ — статические компоненты, которые рендерятся только на сервере.
  • static/ — статические ресурсы: изображения, CSS, шрифты.
  • deno.json — конфигурация Deno, включая импорты и разрешения.

Ключевой принцип Fresh — страницы рендерятся на сервере и отправляются клиенту полностью готовыми. Это обеспечивает моментальную загрузку и исключает необходимость гидратации всего DOM, как в традиционных SPA.


Маршрутизация и обработка запросов

Маршруты в Fresh строятся на основе файловой структуры. Файлы в routes/ экспортируют функции с особыми сигнатурами:

export const handler: Handlers = {
  GET(req, ctx) {
    return ctx.render({ message: "Hello, Fresh!" });
  }
};
  • Handlers — объект с методами HTTP-запросов (GET, POST, PUT и т.д.).
  • ctx.render — функция, возвращающая HTML, сгенерированный на сервере.

Для динамических маршрутов используются синтаксические шаблоны файлов. Например, routes/posts/[id].tsx соответствует URL /posts/123, где id доступен через ctx.params.id.


Компоненты и Islands

Fresh вводит концепцию Islands — участков страницы, которые становятся интерактивными только там, где это необходимо. Основная страница рендерится полностью на сервере, а интерактивные части загружаются отдельно.

// islands/Counter.tsx
import { useState } from "preact/hooks";

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button onCl ick={() => setCount(count + 1)}>
      Нажато {count} раз
    </button>
  );
}

Islands подключаются к страницам через JSX:

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

export default function Home() {
  return (
    <main>
      <h1>Пример Fresh Islands</h1>
      <Counter />
    </main>
  );
}

Применение Islands уменьшает объем JavaScript на клиенте и повышает производительность.


Работа с данными и SSR

Fresh использует встроенный механизм Server-Side Rendering (SSR) для работы с данными. Данные передаются в компонент через ctx.render:

export const handler: Handlers = {
  async GET(_req, ctx) {
    const posts = await fetchPostsFromDB();
    return ctx.render({ posts });
  }
};

В компоненте данные доступны через PageProps:

interface PageData {
  posts: Array<{ id: string; title: string }>;
}

export default function PostsPage({ data }: PageProps<PageData>) {
  return (
    <ul>
      {data.posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

SSR в Fresh выполняется мгновенно благодаря оптимизации Deno Deploy, где каждая страница компилируется и кэшируется на уровне CDN.


Развертывание на Deno Deploy

Для публикации приложения достаточно нескольких шагов:

  1. Инициализация проекта:

    deno run -A https://deno.land/x/fresh@latest/init.ts my_app
    cd my_app
  2. Локальная проверка:

    deno task start
  3. Деплой на Deno Deploy: Используется CLI deployctl или веб-интерфейс Deno Deploy. Достаточно указать корневой модуль main.ts или main.tsx.

Deno Deploy автоматически обрабатывает зависимости, кэширует модули и обеспечивает мгновенный масштабируемый запуск без ручного управления серверами.


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

Fresh автоматически кеширует страницы на уровне CDN, что минимизирует время отклика. Для динамических страниц можно управлять заголовками кеширования:

export const handler: Handlers = {
  GET(_req, ctx) {
    const res = ctx.render({ message: "Кешируемая страница" });
    res.headers.set("Cache-Control", "max-age=60");
    return res;
  }
};

Поддерживаются как статические страницы (SSG), так и динамические (SSR) с умной стратегией кеширования, что позволяет гибко балансировать производительность и актуальность данных.


Интеграция с базами данных и внешними API

Fresh не накладывает ограничений на работу с внешними источниками данных. Благодаря асинхронной природе Deno можно подключать любые REST или GraphQL API, а также использовать нативные драйверы для PostgreSQL, MySQL и других баз.

Пример интеграции с REST API:

export const handler: Handlers = {
  async GET(_req, ctx) {
    const response = await fetch("https://api.example.com/items");
    const items = await response.json();
    return ctx.render({ items });
  }
};

Преимущества Fresh на Deno Deploy

  • Минимальный клиентский JavaScript: загружается только то, что необходимо для интерактивных Islands.
  • Нативная поддержка TypeScript: нет необходимости в сборщиках или транспиляторах.
  • Мгновенный SSR и кэширование на CDN: повышает скорость загрузки и снижает нагрузку на сервер.
  • Простая маршрутизация через файловую структуру: нет необходимости в сложных конфигурациях маршрутов.
  • Автоматическое масштабирование: Deno Deploy управляет ресурсами и сетевым трафиком.

Fresh в связке с Deno Deploy предоставляет современную платформу для создания веб-приложений, объединяя высокую производительность, удобство разработки и автоматическую оптимизацию под облачные среды.