Документация API

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

Архитектура и особенности

Fresh использует Deno как runtime, что отличает его от традиционных Node.js-проектов. Основные элементы архитектуры:

  • Маршруты (Routes): каждая страница представлена отдельным файлом .tsx или .ts в каталоге routes. Имена файлов определяют URL-пути.
  • Компоненты: Fresh поддерживает JSX/TSX, что позволяет строить интерфейсы в декларативном стиле. Компоненты можно использовать как на сервере, так и на клиенте.
  • Islands architecture: уникальная особенность, где только интерактивные части страницы загружаются на клиенте, а остальное рендерится на сервере. Это снижает размер клиентского бандла и ускоряет загрузку.

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

Файловая система определяет маршруты автоматически. Например:

// routes/index.tsx
import { Handlers } from "$fresh/server.ts";
import Counter from "../components/Counter.tsx";

export const handler: Handlers = {
  GET(req, ctx) {
    return ctx.render({ count: 0 });
  }
};

export default function Home(props: { count: number }) {
  return (
    <div>
      <h1>Привет, Fresh!</h1>
      <Counter initialCount={props.count} />
    </div>
  );
}
  • Handlers обрабатывают HTTP-запросы на сервере.
  • Метод ctx.render передает данные в компонент страницы.
  • Компоненты TSX отвечают за визуальную часть и могут содержать интерактивность через Islands.

Islands и клиентская интерактивность

Islands — это части страницы, которые становятся интерактивными на клиенте. Остальной контент остаётся статическим, что позволяет минимизировать JavaScript в браузере.

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

export default function Counter({ initialCount }: { initialCount: number }) {
  const [count, setCount] = useState(initialCount);

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

Работа с API и Handlers

Fresh упрощает создание серверных API. Handlers поддерживают методы GET, POST, PUT, DELETE и позволяют работать с JSON, формами и заголовками.

Пример API-обработчика:

// routes/api/todos.ts
import { Handlers } from "$fresh/server.ts";

let todos: string[] = ["Учить Fresh", "Написать статью"];

export const handler: Handlers = {
  GET() {
    return new Response(JSON.stringify(todos), {
      headers: { "Content-Type": "application/json" },
    });
  },
  POST(req) {
    const { todo } = await req.json();
    todos.push(todo);
    return new Response(JSON.stringify({ status: "ok" }), {
      headers: { "Content-Type": "application/json" },
    });
  },
};
  • Обработчик GET возвращает список задач.
  • Обработчик POST добавляет новую задачу в массив.
  • Fresh автоматически интегрирует такие API с серверным рендерингом страниц.

Работа с данными и состоянием

Fresh позволяет использовать props и серверные функции для передачи данных в компоненты. Для асинхронной загрузки данных используется функция ctx.render() с объектом данных.

// routes/users.tsx
import { Handlers } from "$fresh/server.ts";

export const handler: Handlers = {
  async GET(_, ctx) {
    const response = await fetch("https://jsonplaceholder.typicode.com/users");
    const users = await response.json();
    return ctx.render({ users });
  },
};

export default function UsersPage({ users }: { users: any[] }) {
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
  • Данные загружаются на сервере.
  • Страница рендерится с уже готовым HTML.
  • Пользователь получает полностью загруженную страницу без задержек.

Работа с Middleware

Fresh поддерживает middleware для обработки запросов перед их попаданием в Handlers. Это удобно для аутентификации, логирования или кэширования.

// middleware.ts
import { MiddlewareHandlerContext } from "$fresh/server.ts";

export async function handler(req: Request, ctx: MiddlewareHandlerContext) {
  console.log("Запрос:", req.url);
  return ctx.next();
}
  • Middleware вызывается для каждого запроса.
  • Позволяет изменять или перехватывать запросы до рендеринга страницы.

Настройка маршрутов и статических файлов

  • Статические файлы помещаются в каталог static.
  • URL /static/logo.png будет автоматически доступен по прямой ссылке.
  • Можно подключать CSS, изображения и шрифты без дополнительного бандлинга.

Типизация и интеграция с TypeScript

Fresh полностью совместим с TypeScript. Все props, Handlers и компоненты могут быть типизированы, что повышает безопасность кода и удобство разработки.

  • Типизация props предотвращает ошибки при передаче данных.
  • Handlers могут иметь строгие типы запросов и ответов.
  • Поддерживается импорт типов из внешних библиотек Deno.

Особенности производительности

  • Минимальный JavaScript на клиенте благодаря Islands.
  • Быстрый SSR без тяжелых runtime-зависимостей.
  • Автоматическая оптимизация изображений и статических ресурсов.
  • Поддержка HTTP/2 и современного кэширования.

Работа с формами и событиями

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

<form onSub mit={(e) => { e.preventDefault(); alert("Форма отправлена"); }}>
  <input type="text" placeholder="Введите имя" />
  <button type="submit">Отправить</button>
</form>
  • События обрабатываются на клиенте только там, где это необходимо.
  • Основной HTML остаётся статичным.

Расширение функционала

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

  • [id].tsx для страниц с параметрами.
  • layout.tsx для общих макетов страниц.
  • Встроенная поддержка JSON API, GraphQL и WebSocket через стандартные Handlers.

Инструменты разработки

  • Deno Deploy для деплоя приложений.
  • Live reload при изменении файлов.
  • Тайпчек и линтер встроены в Deno, что упрощает поддержание качества кода.

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