Создайте приложение React с create-vite
React — это наиболее широко используемая JavaScript-библиотека для фронтенда.
В этом руководстве мы создадим простое приложение React с Deno. Приложение будет отображать список динозавров. При нажатии на одного из них вы перейдёте на страницу динозавра с более подробной информацией. Вы можете посмотреть готовый репозиторий приложения на GitHub.

Создайте приложение React с Vite и Deno
В этом руководстве мы будем использовать create-vite для быстрого создания приложения Deno и React. Vite — это инструмент сборки и сервер разработки для современных веб-проектов. Он хорошо сочетается с React и Deno, использует ES-модули и позволяет вам импортировать компоненты React напрямую.
В терминале выполните следующую команду, чтобы создать новое приложение React с Vite, используя шаблон typescript:
deno run -A npm:create-vite@latest --template react-ts
При запросе присвойте вашему приложению имя и cd в только что созданную папку проекта. Затем выполните следующую команду, чтобы установить зависимости:
deno install
Теперь вы можете запустить ваше новое приложение react, выполнив:
deno task dev
Это запустит сервер Vite, нажмите на ссылку вывода в локальном хосте, чтобы увидеть ваше приложение в браузере. Если у вас установлен расширение Deno для VSCode, вы можете заметить, что редактор выделяет некоторые ошибки в коде. Это потому, что приложение, созданное Vite, разработано с Node в виду и поэтому использует соглашения, которых нет в Deno (например, «небрежные импорты» — импорт модулей без расширения файла). Отключите расширение Deno для этого проекта, чтобы избежать этих ошибок, или попробуйте руководство по созданию приложения React с файлом deno.json.
Добавление бэкенда
Следующим шагом является добавление API бэкенда. Мы создадим очень простой API, возвращающий информацию о динозаврах.
В корне вашего нового проекта создайте папку api. В этой папке создайте файл main.ts, который запустит сервер, и файл data.json, который будет содержать жёстко закодированные данные динозавров.
Скопируйте и вставьте этот JSON-файл в файл api/data.json.
Мы собираемся создать простой сервер API с маршрутами, возвращающими информацию о динозаврах. Мы будем использовать oak фреймворк для мидлверов и cors мидлвер, чтобы включить CORS.
Используйте команду deno add для добавления необходимых зависимостей в ваш проект:
deno add jsr:@oak/oak jsr:@tajpouria/cors
Далее, обновите api/main.ts для импорта необходимых модулей и создания новой Router инстанции для определения некоторых маршрутов:
import { Application, Router } from "@oak/oak";
import { oakCors } from "@tajpouria/cors";
import data from "./data.json" with { type: "json" };
const router = new Router();
После этого, в том же файле, мы определим два маршрута. Один на /api/dinosaurs для возврата всех динозавров, и /api/dinosaurs/:dinosaur для возврата определенного динозавра на основе имени в URL:
router.get("/api/dinosaurs", (context) => {
context.response.body = data;
});
router.get("/api/dinosaurs/:dinosaur", (context) => {
if (!context?.params?.dinosaur) {
context.response.body = "No dinosaur name provided.";
}
const dinosaur = data.find((item) =>
item.name.toLowerCase() === context.params.dinosaur.toLowerCase()
);
context.response.body = dinosaur ?? "No dinosaur found.";
});
Наконец, внизу того же файла создайте новый Application экземпляр и прикрепите определённые маршруты к приложению с помощью app.use(router.routes()) и запустите сервер, прослушивая порт 8000:
const app = new Application();
app.use(oakCors());
app.use(router.routes());
app.use(router.allowedMethods());
await app.listen({ port: 8000 });
Вы можете запустить сервер API с помощью deno run --allow-env --allow-net api/main.ts. Мы создадим задачу для выполнения этой команды в фоновом режиме и обновим задачу разработки, чтобы запустить как приложение React, так и сервер API.
В вашем файле package.json обновите поле scripts для включения следующего:
{
"scripts": {
"dev": "deno task dev:api & deno task dev:vite",
"dev:api": "deno run --allow-env --allow-net api/main.ts",
"dev:vite": "deno run -A npm:vite",
// ...
}
Если вы запустите deno task dev сейчас и посетите localhost:8000/api/dinosaurs, в вашем браузере вы должны увидеть JSON-ответ со всеми динозаврами.
Обновление точки входа
Точка входа для приложения React находится в файле src/main.tsx. Наш будет очень простым:
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<App />,
);
Добавление роутера
Приложение будет иметь два маршрута: / и /:dinosaur.
Мы будем использовать react-router-dom, чтобы построить логику маршрутизации, поэтому нам нужно добавить зависимость react-router-dom в ваш проект. В корне проекта выполните:
deno add npm:react-router-dom
Обновите файл /src/App.tsx для импорта и использования компонента BrowserRouter из react-router-dom и определения двух маршрутов:
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Index from "./pages/index";
import Dinosaur from "./pages/Dinosaur";
import "./App.css";
function App() {
return (
<BrowserRouter><Routes><Route path="/" element={<Index />} /><Route path="/:selectedDinosaur" element={<Dinosaur />} /></Routes></BrowserRouter>
);
}
export default App;
Прокси для перенаправления запросов к API
Vite будет обслуживать приложение на порту 5173, а наш API работает на порту 8000. Поэтому нам нужно настроить прокси, чтобы разрешить api/-маршрутам быть доступными роутеру. Перезапишите vite.config.ts следующим, чтобы настроить прокси:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
proxy: {
"/api": {
target: "http://localhost:8000",
changeOrigin: true,
},
},
},
});
Создание страниц
Мы создадим две страницы: Index и Dinosaur. Страница Index будет отображать список всех динозавров, а страница Dinosaur — подробности о конкретном динозавре.
Создайте папку pages в каталоге src и внутри неё два файла: index.tsx и Dinosaur.tsx.
Типы
Обе страницы будут использовать тип Dino для описания формы данных, которые они ожидают от API, поэтому давайте создадим файл types.ts в каталоге src:
export type Dino = { name: string; description: string };
index.tsx
Эта страница будет получать список динозавров из API и отображать их как ссылки:
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { Dino } from "../types.ts";
export default function Index() {
const [dinosaurs, setDinosaurs] = useState<Dino[]>([]);
useEffect(() => {
(async () => {
const response = await fetch(`/api/dinosaurs/`);
const allDinosaurs = await response.json() as Dino[];
setDinosaurs(allDinosaurs);
})();
}, []);
return (
<main><h1>Welcome to the Dinosaur app</h1><p>Click on a dinosaur below to learn more.</p>{dinosaurs.map((dinosaur: Dino) => {
return (
<Link
to={`/${dinosaur.name.toLowerCase()}`}
key={dinosaur.name}
className="dinosaur"
>{dinosaur.name}</Link>
);
})}</main>
);
}
Dinosaur.tsx
Эта страница будет получать подробности о конкретном динозавре из API и отображать их в абзаце:
import { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { Dino } from "../types";
export default function Dinosaur() {
const { selectedDinosaur } = useParams();
const [dinosaur, setDino] = useState<Dino>({ name: "", description: "" });
useEffect(() => {
(async () => {
const resp = await fetch(`/api/dinosaurs/${selectedDinosaur}`);
const dino = await resp.json() as Dino;
setDino(dino);
})();
}, [selectedDinosaur]);
return (
<div><h1>{dinosaur.name}</h1><p>{dinosaur.description}</p><Link to="/">🠠 Back to all dinosaurs</Link></div>
);
}
Стиль списка динозавров
Поскольку мы отображаем список динозавров на главной странице, давайте сделаем некоторую базовую форматирование. Добавьте следующее в конец src/App.css для отображения нашего списка динозавров в упорядоченном виде:
.dinosaur {
display: block;
}
Запуск приложения
Для запуска приложения используйте задачу, которую вы настроили ранее
deno task dev
Перейдите по ссылке локального сервера Vite в вашем браузере (localhost:5173) и вы должны увидеть список динозавров, по которому вы можете нажать, чтобы узнать о каждом из них.

Сборка и развертывание
На данный момент приложение обслуживается сервером разработки Vite. Чтобы обслуживать приложение в режиме производства, вы можете собрать приложение с помощью Vite, а затем обслуживать созданные файлы с помощью Deno. Для этого нам нужно обновить сервер API для обслуживания созданных файлов. Мы напишем мидлвер для этого. В вашем каталоге api создайте новую папку util и новый файл под названием routeStaticFilesFrom.ts и добавьте следующий код:
import { Next } from "jsr:@oak/oak/middleware";
import { Context } from "jsr:@oak/oak/context";
// Configure static site routes so that we can serve
// the Vite build output and the public folder
export default function routeStaticFilesFrom(staticPaths: string[]) {
return async (context: Context<Record<string, object>>, next: Next) => {
for (const path of staticPaths) {
try {
await context.send({ root: path, index: "index.html" });
return;
} catch {
continue;
}
}
await next();
};
}
Этот мидлвер попытается обслуживать статические файлы из путей, указанных в массиве staticPaths. Если файл не найден, он вызовет следующий мидлвер в цепочке. Теперь мы можем обновить файл api/main.ts для использования этого мидлвера:
import { Application, Router } from "@oak/oak";
import { oakCors } from "@tajpouria/cors";
import data from "./data.json" with { type: "json" };
import routeStaticFilesFrom from "./util/routeStaticFilesFrom.ts";
const router = new Router();
router.get("/api/dinosaurs", (context) => {
context.response.body = data;
});
router.get("/api/dinosaurs/:dinosaur", (context) => {
if (!context?.params?.dinosaur) {
context.response.body = "No dinosaur name provided.";
}
const dinosaur = data.find((item) =>
item.name.toLowerCase() === context.params.dinosaur.toLowerCase()
);
context.response.body = dinosaur ? dinosaur : "No dinosaur found.";
});
const app = new Application();
app.use(oakCors());
app.use(router.routes());
app.use(router.allowedMethods());
app.use(routeStaticFilesFrom([
`${Deno.cwd()}/dist`,
`${Deno.cwd()}/public`,
]));
await app.listen({ port: 8000 });
Добавьте скрипт serve в ваш файл package.json для сборки приложения с помощью Vite и затем запуска сервера API:
{
"scripts": {
// ...
"serve": "deno task build && deno task dev:api",
}
Теперь вы можете обслуживать собранное приложение с помощью Deno, выполнив:
deno task serve
Если вы посетите localhost:8000 в вашем браузере, вы должны увидеть запущенное приложение!
🦕 Теперь вы можете создать и разрабатывать приложение React с Vite и Deno! Вы готовы создать быстрые веб-приложения. Надеемся, вам понравится изучение этих передовых инструментов, мы с нетерпением ждём, что вы создадите!
© 2018–2024 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/tutorials/how_to_with_npm/create-react