Fresh — это современный фреймворк для разработки веб-приложений на JavaScript, ориентированный на высокую производительность и минимальный размер фронтенд-кода. Основная концепция Fresh заключается в рендеринге страниц на сервере (SSR, Server-Side Rendering) с возможностью частичного обновления интерфейса без дополнительного клиентского JavaScript, что обеспечивает быстрый старт страницы и низкое потребление ресурсов.
Fresh использует Deno как runtime, что отличает его от традиционных Node.js-проектов. Основные элементы архитектуры:
.tsx или .ts в каталоге
routes. Имена файлов определяют URL-пути.Файловая система определяет маршруты автоматически. Например:
// 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>
);
}
ctx.render передает данные в компонент
страницы.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 загружается на клиенте.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 позволяет использовать 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>
);
}
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();
}
static./static/logo.png будет автоматически доступен по
прямой ссылке.Fresh полностью совместим с TypeScript. Все props, Handlers и компоненты могут быть типизированы, что повышает безопасность кода и удобство разработки.
Islands позволяют обрабатывать события только внутри интерактивных компонентов:
<form onSub mit={(e) => { e.preventDefault(); alert("Форма отправлена"); }}>
<input type="text" placeholder="Введите имя" />
<button type="submit">Отправить</button>
</form>
Fresh интегрируется с внешними библиотеками и поддерживает динамические маршруты:
[id].tsx для страниц с параметрами.layout.tsx для общих макетов страниц.Fresh сочетает легковесность, современный серверный рендеринг и эффективное использование клиентского JavaScript, что делает его идеальным выбором для быстрого создания высокопроизводительных веб-приложений.