תיעוד 46
מדריך: אפליקציית React מסוג SPA עם API
יצירת אפליקציית React מסוג SPA עם Worker של API באמצעות תוסף Vite.
המדריך הזה עובר על הצעדים הנדרשים כדי להתאים פרויקט Vite לשימוש בתוסף Vite של Cloudflare. חלק גדול מהתוכן רלוונטי גם להתאמה של פרויקטי Vite קיימים, וגם למסגרות צד לקוח שאינן React.
הערה
אם רוצים להתחיל אפליקציה חדשה מתבנית שכבר מוגדרת עם Vite, React ותוסף Vite של Cloudflare, עיינו במדריך מסגרת React. כדי ליצור Worker עצמאי, עיינו בתחילת העבודה.
#מבוא
במדריך זה תיצרו אפליקציית React מסוג SPA שאפשר לפרוס כ-Worker עם נכסים סטטיים. אחר כך תוסיפו Worker של API שאפשר לגשת אליו מקוד צד הלקוח. תפתחו, תבנו ותציגו בתצוגה מקדימה את האפליקציה באמצעות Vite, ולבסוף תפרסו ל-Cloudflare.
#הקמה והגדרה של אפליקציית React מסוג SPA
#יצירת שלד לפרויקט Vite
התחילו ביצירת פרויקט React עם TypeScript באמצעות Vite.
עם npm:
npm create vite@latest -- cloudflare-vite-tutorial --template react-tsעם yarn:
yarn create vite cloudflare-vite-tutorial --template react-tsעם pnpm:
pnpm create vite@latest cloudflare-vite-tutorial --template react-tsלאחר מכן, פתחו את התיקייה cloudflare-vite-tutorial בעורך שבחרתם.
#הוספת תלויות Cloudflare
עם npm:
npm i -D @cloudflare/vite-plugin wranglerעם yarn:
yarn add -D @cloudflare/vite-plugin wranglerעם pnpm:
pnpm add -D @cloudflare/vite-plugin wranglerעם bun:
bun add -d @cloudflare/vite-plugin wrangler#הוספת תוסף Vite של Cloudflare לפרויקט
בקובץ vite.config.ts, הוסיפו את תוסף Vite של Cloudflare אחרי תוסף המסגרת:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { cloudflare } from "@cloudflare/vite-plugin";
export default defineConfig({
plugins: [react(), cloudflare()],
});תוסף Vite של Cloudflare אינו דורש תצורה כברירת מחדל, והוא יחפש קובץ wrangler.jsonc, wrangler.json או wrangler.toml בשורש האפליקציה.
#יצירת קובץ התצורה של ה-Worker
צרו קובץ wrangler.jsonc בשורש הפרויקט:
wrangler.jsonc:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-app",
// Set this to today's date
"compatibility_date": "2026-09-05",
"assets": {
"not_found_handling": "single-page-application"
}
}wrangler.toml:
name = "my-app"
# Set this to today's date
compatibility_date = "2026-09-05"
[assets]
not_found_handling = "single-page-application"הערך של not_found_handling הוגדר כ-single-page-application. המשמעות היא שכל בקשה שלא נמצאה תוגש עם הקובץ index.html, וזה נדרש עבור React Router ופתרונות ניתוב אחרים בצד הלקוח.
עם תוסף Cloudflare, תצורת הניתוב של assets משמשת במקום התנהגות ברירת המחדל של Vite. כך תצורת הניתוב של האפליקציה עובדת באותו אופן בפיתוח כמו בפריסה לייצור.
השדה directory אינו בשימוש כשמגדירים נכסים עם Vite. השדה directory בתצורת הפלט יצביע אוטומטית על פלט הבנייה של הלקוח. למידע נוסף, עיינו בנכסים סטטיים.
הערה
כשמשתמשים בתוסף Vite של Cloudflare, תצורת ה-Worker שאתם מספקים (למשל wrangler.jsonc) היא קובץ תצורת הקלט. קובץ פלט נפרד בשם wrangler.json נוצר כשמריצים vite build. קובץ הפלט הוא תצלום מצב של התצורה בזמן הבנייה, והוא מותאם כך שיפנה לתוצרי הבנייה. זו התצורה שמשמשת לתצוגה מקדימה ולפריסה.
#עדכון קובץ .gitignore
במהלך פיתוח Workers יש קבצים נוספים שבשימוש או שנוצרים, ואין לאחסן אותם ב-Git. הוסיפו את השורות הבאות לקובץ .gitignore:
.wrangler
.dev.vars*#הפעלת שרת הפיתוח
הריצו את פקודת הפיתוח של המסגרת כדי להפעיל את שרת הפיתוח של Vite ולוודא שהאפליקציה עובדת כמצופה.
עם npm:
npm run devעם yarn:
yarn run devעם pnpm:
pnpm run devעבור אפליקציה שהיא רק צד לקוח, אפשר כבר לבנות, להציג בתצוגה מקדימה ולפרוס את האפליקציה. הסעיפים הבאים מראים איך להמשיך ולהוסיף Worker של API.
#הוספת Worker של API
#הוספת טיפוסי TypeScript של Workers
עם npm:
npm i -D @cloudflare/workers-typesעם yarn:
yarn add -D @cloudflare/workers-typesעם pnpm:
pnpm add -D @cloudflare/workers-typesעם bun:
bun add -d @cloudflare/workers-typesצרו קובץ tsconfig.worker.json שמרחיב את תצורת TypeScript של Node ומוסיף את טיפוסי Workers:
{
"extends": "./tsconfig.node.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo",
"types": ["@cloudflare/workers-types/2023-07-01", "vite/client"],
},
"include": ["worker"],
}לאחר מכן הוסיפו הפניה לתצורה החדשה הזו בקובץ tsconfig.json שבשורש:
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.worker.json" },
],
}#הוספת נקודת הכניסה של ה-Worker לתצורה
עדכנו את קובץ התצורה של Wrangler והוסיפו שדה main שמצביע על נקודת הכניסה של ה-Worker:
wrangler.jsonc:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-app",
// Set this to today's date
"compatibility_date": "2026-09-05",
"main": "./worker/index.ts",
"assets": {
"not_found_handling": "single-page-application"
}
}wrangler.toml:
name = "my-app"
# Set this to today's date
compatibility_date = "2026-09-05"
main = "./worker/index.ts"
[assets]
not_found_handling = "single-page-application"השדה main מציין את קובץ הכניסה של קוד ה-Worker.
#הוספת ה-Worker של ה-API
צרו קובץ worker/index.ts עם התוכן הבא:
export default {
fetch(request) {
const url = new URL(request.url);
if (url.pathname.startsWith("/api/")) {
return Response.json({
name: "Cloudflare",
});
}
return new Response(null, { status: 404 });
},
} satisfies ExportedHandler;ה-Worker שבבלוק הקוד הקודם יופעל לכל בקשה שאינה בקשת ניווט ושאינה תואמת נכס סטטי. הוא מחזיר תגובת JSON אם ה-pathname מתחיל ב-/api/, ואחרת מחזיר תגובת 404.
הערה
עבור בקשות ניווט ברמה העליונה, דפדפנים שולחים כותרת Sec-Fetch-Mode: navigate. אם היא קיימת וה-URL אינו תואם נכס סטטי, תופעל ההתנהגות של not_found_handling במקום ה-Worker. ניתוב מרומז זה הוא ברירת המחדל.
אם במקום זאת רוצים להגדיר במפורש את הנתיבים שמפעילים את ה-Worker, אפשר לספק מערך של תבניות נתיב ל-run_worker_first. כך מבטלים את הפרשנות של כותרת Sec-Fetch-Mode.
wrangler.jsonc:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "cloudflare-vite-tutorial",
// Set this to today's date
"compatibility_date": "2026-09-05",
"main": "./worker/index.ts",
"assets": {
"not_found_handling": "single-page-application",
"run_worker_first": [
"/api/*"
]
}
}wrangler.toml:
name = "cloudflare-vite-tutorial"
# Set this to today's date
compatibility_date = "2026-09-05"
main = "./worker/index.ts"
[assets]
not_found_handling = "single-page-application"
run_worker_first = ["/api/*"]#קריאה ל-API מהלקוח
ערכו את src/App.tsx כך שיכלול כפתור נוסף שקורא ל-API ומעדכן state:
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
function App() {
const [count, setCount] = useState(0);
const [name, setName] = useState("unknown");
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button
onClick={() => setCount((count) => count + 1)}
aria-label="increment"
>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<div className="card">
<button
onClick={() => {
fetch("/api/")
.then((res) => res.json() as Promise<{ name: string }>)
.then((data) => setName(data.name));
}}
aria-label="get name"
>
Name from API is: {name}
</button>
<p>
Edit <code>api/index.ts</code> to change the name
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
);
}
export default App;עכשיו, אם לוחצים על הכפתור, יוצג Name from API is: Cloudflare.
העלו את המונה כדי לעדכן את מצב האפליקציה בדפדפן. לאחר מכן ערכו את api/index.ts ושנו את ה-name שהוא מחזיר ל-'Cloudflare Workers'. אם לוחצים שוב על הכפתור, יוצג ה-name החדש, והערך הקודם של המונה יישמר.
עם Vite ותוסף Cloudflare אפשר לעבוד יחד על חלקי הלקוח והשרת של האפליקציה, בלי לאבד את מצב ממשק המשתמש בין עריכות.
#בניית האפליקציה
הריצו את פקודת הבנייה כדי לבנות את האפליקציה.
עם npm:
npm run buildעם yarn:
yarn run buildעם pnpm:
pnpm run buildתיקיית dist תכיל את פלט הבנייה של הלקוח בתת התיקייה client, ואת קוד ה-Worker לצד קובץ התצורה wrangler.json שבפלט.
#תצוגה מקדימה של האפליקציה
הריצו את פקודת התצוגה המקדימה כדי לוודא שהאפליקציה רצה כמצופה.
עם npm:
npm run previewעם yarn:
yarn run previewעם pnpm:
pnpm run previewהפקודה הזו תריץ את פלט הבנייה באופן מקומי בסביבת הריצה של Workers, באופן שקרוב מאוד להתנהגות בייצור.
#פריסה ל-Cloudflare
הריצו את פקודת הפריסה כדי לפרוס את האפליקציה ל-Cloudflare.
עם npm:
npx wrangler deployעם yarn:
yarn wrangler deployעם pnpm:
pnpm wrangler deployהפקודה הזו תשתמש אוטומטית בקובץ wrangler.json שבפלט הבנייה.
#הצעדים הבאים
במדריך זה יצרנו SPA שאפשר לפרוס כ-Worker עם נכסים סטטיים. אחר כך הוספנו Worker של API שאפשר לגשת אליו מקוד צד הלקוח. לבסוף פרסנו ל-Cloudflare גם את חלקי הלקוח וגם את חלקי השרת של האפליקציה.
צעדים אפשריים בהמשך:
- הוספת binding לשירות Cloudflare נוסף, למשל מרחב שמות KV או מסד נתונים D1
- הרחבת ה-API כך שיכלול נתיבים נוספים
- שימוש בספרייה, למשל Hono או tRPC, ב-Worker של ה-API