跳转到内容
搜索文档

教程 - 带 API 的 React SPA

最后更新 查看 MarkdownAgent 设置

本教程将引导你完成将 Vite 项目适配为使用 Cloudflare Vite 插件的步骤。 大部分内容也适用于适配现有 Vite 项目以及 React 以外的其他前端框架。

简介

在本教程中,你将创建一个可部署为带静态资源的 Worker 的 React SPA。 然后添加一个可从前端代码访问的 API Worker。 你将使用 Vite 开发、构建和预览应用程序,最后部署到 Cloudflare。

设置并配置 React SPA

搭建 Vite 项目

首先使用 Vite 创建 React TypeScript 项目。

npm create vite@latest -- cloudflare-vite-tutorial --template react-ts

接下来,在你选择的编辑器中打开 cloudflare-vite-tutorial 目录。

添加 Cloudflare 依赖

npm i -D @cloudflare/vite-plugin wrangler

将插件添加到 Vite 配置

vite.config.tsts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
	plugins: [react(), cloudflare()],
});

Cloudflare Vite 插件默认不需要任何配置,会在应用程序根目录查找 wrangler.jsoncwrangler.jsonwrangler.toml

配置选项请参阅 API 参考

创建 Worker 配置文件

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "cloudflare-vite-tutorial",
	// Set this to today's date
	"compatibility_date": "2026-08-17",
	"assets": {
		"not_found_handling": "single-page-application"
	}
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "cloudflare-vite-tutorial"
# Set this to today's date
compatibility_date = "2026-08-17"

[assets]
not_found_handling = "single-page-application"

not_found_handling 值已设置为 single-page-application。 这意味着所有未找到的请求都将提供 index.html 文件。 使用 Cloudflare 插件时,assets 路由配置替代 Vite 的默认行为。 这确保应用程序的路由配置在开发时与部署到生产环境时的行为相同。

请注意,使用 Vite 配置资源时不使用 directory 字段。 输出配置中的 directory 将自动指向 client 构建输出。 更多信息请参阅静态资源

更新 .gitignore 文件

开发 Worker 时会使用和/或生成不应存储在 git 中的其他文件。 将以下行添加到 .gitignore 文件:

.gitignoretxt
.wrangler
.dev.vars*

运行开发服务器

运行 npm run dev 启动 Vite 开发服务器,并验证应用程序是否按预期工作。

对于纯前端应用程序,你现在可以构建(npm run build)、预览(npm run preview)和部署(npm exec wrangler deploy)应用程序。 但是,本教程将展示如何进一步添加 API Worker。

添加 API Worker

为 Worker 代码配置 TypeScript

npm i -D @cloudflare/workers-types
tsconfig.worker.jsonjsonc
{
	"extends": "./tsconfig.node.json",
	"compilerOptions": {
		"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo",
		"types": ["@cloudflare/workers-types", "vite/client"],
	},
	"include": ["worker"],
}
tsconfig.jsonjsonc
{
	"files": [],
	"references": [
		{ "path": "./tsconfig.app.json" },
		{ "path": "./tsconfig.node.json" },
		{ "path": "./tsconfig.worker.json" },
	],
}

添加到 Worker 配置

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "cloudflare-vite-tutorial",
	// Set this to today's date
	"compatibility_date": "2026-08-17",
	"assets": {
		"not_found_handling": "single-page-application"
	},
	"main": "./worker/index.ts"
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "cloudflare-vite-tutorial"
# Set this to today's date
compatibility_date = "2026-08-17"
main = "./worker/index.ts"

[assets]
not_found_handling = "single-page-application"

main 字段指定 Worker 代码的入口文件。

添加 API Worker

worker/index.tsts
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 将在不匹配静态资源的非导航请求时被调用。 如果 pathname/api/ 开头,则返回 JSON 响应,否则返回 404 响应。

从 client 调用 API

编辑 src/App.tsx,添加一个调用 API 并设置状态的按钮:

src/App.tsxtsx
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」。

增加计数器以更新浏览器中的应用程序状态。 接下来,通过将返回的 name 更改为 'Cloudflare Workers' 来编辑 api/index.ts。 如果再次点击按钮,将显示新的 name,同时保留之前设置的计数器值。

使用 Vite 和 Cloudflare 插件,可以在编辑之间迭代应用程序的 client 和 server 部分,而不会丢失 UI 状态。

构建应用程序

运行 npm run build 构建应用程序。

npm run build

如果检查 dist 目录,将看到它包含两个子目录:

  • client - 在浏览器中运行的 client 代码
  • cloudflare_vite_tutorial - Worker 代码以及输出 wrangler.json 配置文件

预览应用程序

运行 npm run preview 验证应用程序是否按预期运行。

npm run preview

此命令将在 Workers 运行时本地运行构建输出,与生产环境中的行为非常接近。

部署到 Cloudflare

运行 npm exec wrangler deploy 将应用程序部署到 Cloudflare。

npm exec wrangler deploy

此命令将自动使用构建输出中包含的输出 wrangler.json

后续步骤

在本教程中,我们创建了一个可部署为带静态资源的 Worker 的 SPA。 然后添加了一个可从前端代码访问的 API Worker。 最后,我们将应用程序的 client 和 server 部分部署到 Cloudflare。

可能的后续步骤包括:

这篇文档对您有帮助吗?