Fresh — это фреймворк для веб-разработки на JavaScript и TypeScript, ориентированный на максимально быстрые сайты, минимальный JavaScript на клиенте и нативную интеграцию с Deno. Его ключевая идея — islands architecture: JavaScript выполняется на клиенте только там, где это действительно необходимо.
Fresh работает поверх Deno, поэтому сначала требуется установленный Deno с поддержкой npm и TypeScript.
Создание нового проекта выполняется командой:
deno run -A -r https://fresh.deno.dev my-fresh-app
В процессе генерации создаётся структура проекта с готовой
конфигурацией, примерами маршрутов и компонентами. Fresh не использует
package.json и node_modules — все зависимости
подтягиваются напрямую по URL или через deno.json.
Базовая структура Fresh-приложения выглядит следующим образом:
my-fresh-app/
├─ routes/
│ ├─ index.tsx
│ └─ _app.tsx
├─ islands/
├─ components/
├─ static/
├─ deno.json
└─ main.ts
routes/ Файловая система маршрутов. Каждый файл автоматически становится HTTP-маршрутом.
islands/ Интерактивные компоненты, которые будут гидратироваться на клиенте.
components/ Обычные серверные компоненты без клиентского JavaScript.
static/ Статические файлы: изображения, CSS, шрифты.
Приложение запускается командой:
deno task start
Fresh поднимает сервер с горячей перезагрузкой. Изменения в коде моментально отражаются в браузере.
Файл routes/index.tsx определяет обработку корневого
пути /.
Пример минимального маршрута:
import { PageProps } from "$fresh/server.ts";
export default function Home(props: PageProps) {
return (
<main>
<h1>Fresh</h1>
<p>Первое приложение</p>
</main>
);
}
Компонент возвращает JSX и рендерится на сервере. В HTML, отправляемом клиенту, нет лишнего JavaScript.
Fresh всегда использует SSR. Компоненты:
Это поведение является стандартным и не требует конфигурации.
_app.tsxФайл routes/_app.tsx применяется ко всем страницам и
используется как глобальный layout.
Пример:
import { AppProps } from "$fresh/server.ts";
export default function App({ Component }: AppProps) {
return (
<html>
<head>
<title>Fresh App</title>
</head>
<body>
<Component />
</body>
</html>
);
}
Этот файл удобен для подключения глобальных стилей, метатегов и общей разметки.
По умолчанию Fresh не отправляет JavaScript клиенту. Для интерактивности используются острова — компоненты, которые гидратируются в браузере.
Файл 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>
);
}
Использование в маршруте:
import Counter from "../islands/Counter.tsx";
export default function Page() {
return (
<div>
<Counter />
</div>
);
}
В этом случае:
Маршруты могут возвращать не только JSX, но и обрабатывать HTTP-методы.
Пример GET-обработчика:
import { Handlers } from "$fresh/server.ts";
export const handler: Handlers = {
GET(req) {
return new Response("Hello from Fresh");
},
};
Можно совмещать обработчики и JSX:
export const handler: Handlers = {
GET(req, ctx) {
return ctx.render({ time: Date.now() });
},
};
export default function Page(props) {
return <p>{props.data.time}</p>;
}
Fresh отлично подходит для серверных форм без клиентского JS.
Пример обработки POST-запроса:
export const handler: Handlers = {
async POST(req) {
const form = await req.formData();
const name = form.get("name");
return new Response(`Привет, ${name}`);
},
};
HTML-форма:
<form method="post">
<input name="name" />
<button>Отправить</button>
</form>
Форма работает полностью на сервере.
Файлы из папки static/ доступны напрямую:
/static/style.css → http://localhost:8000/style.css
Подключение CSS:
<link rel="stylesheet" href="/style.css">
Fresh использует URL-импорты и алиасы:
$fresh/ — встроенные модули Freshpreact — встроен по умолчаниюПример:
import { Handlers } from "$fresh/server.ts";
Файл deno.json определяет задачи, алиасы и
разрешения:
{
"tasks": {
"start": "deno run -A --watch=static/,routes/ main.ts"
}
}
Fresh проектировался с упором на:
Бандлер, транспиляция и сборка не требуются. Код исполняется напрямую.
Первое приложение на Fresh строится вокруг следующих принципов:
Fresh позволяет писать современное веб-приложение, не жертвуя производительностью и простотой архитектуры.