Cloudflare
将 Nitro 应用部署到 Cloudflare。
#Cloudflare Workers
预设: cloudflare_module
Note
通过与该提供商的集成支持 workers builds (beta),可以实现零配置。
下面展示了用于将 Nitro 应用部署到 Cloudflare Workers 的示例 nitro.config.ts 文件。
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module"
})#本地预览
你可以使用 Wrangler 在本地预览你的应用:
npm run buildnpx wrangler dev#手动部署
构建应用后,你可以使用 Wrangler 手动部署。
首先确保你已登录到你的 Cloudflare 账户:
npx wrangler login然后你可以使用以下命令部署应用:
npx wrangler deploy#运行时钩子
你可以使用下面的运行时钩子来扩展 Worker 处理程序。
cloudflare:scheduledcloudflare:emailcloudflare:queuecloudflare:tailcloudflare:tracecloudflare:durable:init(仅适用于cloudflare_durable预设)cloudflare:durable:alarm(仅适用于cloudflare_durable预设)
Note
cloudflare:queue 钩子通过 batch 接收消息批次,cloudflare:email 钩子通过 message 接收传入的消息。
#Durable Objects
从 server.ts 文件导出 Durable Object 类。它们在部署后的 Worker 和本地开发环境(包括 Vite)中都可用。也可以在其他文件中定义这些类,再从此处重新导出。
import { DurableObject } from "cloudflare:workers";
export class Counter extends DurableObject {
async fetch() {
const count = (await this.ctx.storage.get<number>("count")) || 0;
await this.ctx.storage.put("count", count + 1);
return Response.json({ count: count + 1 });
}
}
export default {
fetch() {},
};Note
server.ts 必须包含默认导出。如果该文件仅用于导出 Durable Objects,请保留上面的空 fetch 处理器,以便请求继续交由你的路由处理。
在 Wrangler 配置中声明绑定和 Durable Object 导出:
{
"durable_objects": {
"bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
},
"exports": {
"Counter": { "type": "durable-object", "storage": "sqlite" }
}
}在 Nitro 处理器中访问该绑定:
import { defineHandler } from "nitro";
export default defineHandler((event) => {
const { COUNTER } = event.req.runtime!.cloudflare!.env;
return COUNTER.get(COUNTER.idFromName("default")).fetch(event.req);
});使用 Wrangler 环境时,请在所选环境中声明绑定和导出。本地 Durable Object 状态会保存在 .wrangler/state/v3 中,包括开发服务器重新加载前后的状态。
在开发环境中,Durable Objects 会与路由共享模块状态,并在开发服务器不重启的情况下应用代码更改。新增的类或未在 Wrangler 配置中声明的类会触发警告。
如需使用 Counter 类为 COUNTER 绑定添加类型,请参阅绑定类型。
#额外导出
Workflows 或 WorkerEntrypoint 等其他类也以相同方式从 server.ts 导出:
import {
WorkerEntrypoint,
WorkflowEntrypoint,
type WorkflowEvent,
type WorkflowStep,
} from "cloudflare:workers";
export class MyWorkflow extends WorkflowEntrypoint {
async run(event: WorkflowEvent, step: WorkflowStep) {
// ...
}
}
export class MyEntrypoint extends WorkerEntrypoint {
greet(name: string) {
return `Hello ${name}`;
}
}在 Wrangler 配置中通过 workflows 绑定或 exports 条目声明这些类:
{
"workflows": [{ "name": "my-workflow", "binding": "MY_WORKFLOW", "class_name": "MyWorkflow" }],
"exports": {
"MyEntrypoint": { "type": "worker" }
}
}#定时任务(Cron 触发器)
当使用带有 scheduledTasks 的 Nitro 任务时,Nitro 会在构建时自动在 wrangler 配置中生成 Cron 触发器。
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
experimental: {
tasks: true,
},
scheduledTasks: {
"* * * * *": ["cms:update"],
"0 15 1 * *": ["db:cleanup"],
}
})无需手动配置 Wrangler,Nitro 会为你处理。
#Cloudflare Workers with Durable Objects
预设: cloudflare_durable
此预设扩展了 cloudflare_module,并通过 Durable Object 实例路由请求,从而支持有状态功能,例如 WebSocket 支持(通过 CrossWS)以及可跨请求持久存在的内存状态。
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_durable"
})预设入口会导出 $DurableObject 类。在 Wrangler 配置中声明其绑定和导出:
{
"durable_objects": {
"bindings": [
{
"name": "$DurableObject",
"class_name": "$DurableObject"
}
]
},
"exports": {
"$DurableObject": { "type": "durable-object", "storage": "sqlite" }
}
}你可以使用 cloudflare:durable:init 运行时钩子,在 Durable Object 初始化时运行代码,并使用 cloudflare:durable:alarm 钩子处理 alarms。
#追踪
🧪 实验性功能!
启用实验性的 tracingChannel 选项后,Cloudflare 预设会将 Nitro 的追踪通道事件(h3 路由和中间件、srvx、unstorage 操作等)作为自定义 span进行报告,同时还会报告 Cloudflare 的自动插桩事件(fetch 调用、KV 读取、D1 查询等),无需 OpenTelemetry SDK。
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
tracingChannel: true,
});必须在 Worker 上启用追踪,才能记录 span:
{
"observability": {
"traces": {
"enabled": true
}
}
}#Cloudflare Pages
预设: cloudflare_pages
Note
与该提供商的集成支持零配置。
Warning
Cloudflare Workers 是目前推荐用于部署的新预设。如果你需要 Pages 特有的功能,请考虑使用 Cloudflare Pages。
以下展示了用于将 Nitro 应用部署到 Cloudflare Pages 的示例 nitro.config.ts 文件。
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_pages"
})Nitro 自动生成一个 _routes.json 文件,用于控制哪些路由由文件提供,哪些由 Worker 脚本提供。自动生成的路由文件可以通过配置选项 cloudflare.pages.routes 覆盖(了解更多)。
#本地预览
你可以使用 Wrangler 在本地预览你的应用:
npm run buildnpx wrangler pages dev#手动部署
构建应用后,你可以使用 Wrangler 手动部署。
首先确保你已登录到你的 Cloudflare 账户:
npx wrangler login然后你可以使用以下命令部署应用:
npx wrangler pages deploy#使用 GitHub Actions 在 CI/CD 中部署
无论你使用的是 Cloudflare Pages 还是 Cloudflare Workers,都可以使用 Wrangler GitHub actions 来部署应用。
Note
请记得指示 Nitro 使用正确的预设。所有预设都需要这样做,包括 cloudflare_pages。
#环境变量
Nitro 允许你通过 process.env、import.meta.env 或运行时配置,以统一的方式访问环境变量。
Note
请确保只在事件生命周期内访问环境变量,而不要在全局上下文中访问,因为 Cloudflare 只会在请求生命周期内提供这些变量,而不会在此之前提供。
**示例:**如果你已设置 SECRET 和 NITRO_HELLO_THERE 环境变量,可以通过以下方式访问它们:
import { defineHandler } from "nitro";
import { useRuntimeConfig } from "nitro/runtime-config";
console.log(process.env.SECRET) // 注意:这里位于全局作用域!因此它实际上不会生效,变量会是 undefined!
export default defineHandler((event) => {
// 注意:下面这些方式都可以访问上面的变量
useRuntimeConfig().helloThere
useRuntimeConfig().secret
process.env.NITRO_HELLO_THERE
import.meta.env.SECRET
});#在开发模式中指定变量
对于开发,你可以使用 .env 或 .env.local 文件来指定环境变量:
NITRO_HELLO_THERE="captain"
SECRET="top-secret"Note
请确保将 .env 和 .env.local 添加到 .gitignore 文件中,以免提交它们,因为其中可能包含敏感信息。
#为本地预览指定变量
构建完成后,当你使用 wrangler dev 或 wrangler pages dev 在本地试用项目时,请在项目根目录的 .dev.vars 文件中指定环境变量(如 Pages 和 Workers 文档中所述)。
如果你在开发时使用 .env 或 .env.local 文件,你的 .dev.vars 应该与之一致。
Note
请确保将 .dev.vars 添加到 .gitignore 文件中,以免提交它,因为其中可能包含敏感信息。
#为生产环境指定变量
对于生产环境,请使用 Cloudflare 仪表板或 wrangler secret 命令来设置环境变量和密钥。
#使用 wrangler.toml/wrangler.json 指定变量
你可以指定自定义的 wrangler.toml/wrangler.json 文件并在其中定义变量。
Warning
不建议使用此方式存储密钥等敏感数据。
示例:
# 共享
[vars]
NITRO_HELLO_THERE="general"
SECRET="secret"
# 为 `--env production` 用法覆盖值
[env.production.vars]
NITRO_HELLO_THERE="captain"
SECRET="top-secret"#直接访问 Cloudflare 绑定
绑定允许你与 Cloudflare 平台中的资源进行交互,例如键值数据存储(KV)和无服务器 SQL 数据库(D1)。
Tip
Nitro 为 KV Storage 和 Database 等基础功能提供了高级 API。为了保持使用稳定性,优先使用这些 API,而不是直接依赖底层平台 API。
你可以通过 event.req.runtime.cloudflare.env 从请求事件中访问绑定。例如,以下是访问 D1 绑定的方式:
import { defineHandler } from "nitro";
defineHandler(async (event) => {
const { env } = event.req.runtime.cloudflare
const stmt = await env.MY_D1.prepare('SELECT id FROM table')
const { results } = await stmt.all()
})#绑定类型
使用 wrangler types 根据 Wrangler 配置为绑定和 Workers 运行时生成类型。该命令会写入 worker-configuration.d.ts 文件,并在其中声明全局 Env 接口。
{
"scripts": {
"postinstall": "wrangler types",
"typecheck": "wrangler types && tsc --noEmit"
}
}在 tsconfig.json 中包含生成的文件。该文件也提供运行时类型,因此无需安装 @cloudflare/workers-types。Nitro 会为你启用 nodejs_compat 标记;如果还要使用 Node.js API,请将 @types/node(以及 wrangler)添加到开发依赖中,并在类型配置中加入 node:
{
"compilerOptions": {
"types": ["./worker-configuration.d.ts", "node"]
}
}从 cloudflare:workers 导入的绑定会自动获得类型:
import { defineHandler } from "nitro";
import { env } from "cloudflare:workers";
export default defineHandler(async () => {
return env.MY_KV.get("key");
});如需同时为 event.req.runtime.cloudflare.env 添加类型,请扩展 srvx 的 CloudflareEnv 接口:
declare module "srvx" {
interface CloudflareEnv extends Env {}
}
export {};Note
要应用此扩展,项目必须能够解析 srvx。使用 pnpm 时,请将它添加到开发依赖中。
若要使用类为自定义 Durable Objects、Workflows 和 WorkerEntrypoint 绑定添加类型,请将 Wrangler 配置中的 main 指向导出这些类的文件。Nitro 仍会在生成的配置中将 main 设置为构建后的入口。
{
"main": "./server.ts"
}之后,wrangler types 会从该文件读取这些类:
interface Env {
COUNTER: DurableObjectNamespace<import("./server").Counter>;
MY_WORKFLOW: Workflow<Parameters<import("./server").MyWorkflow["run"]>[0]["payload"]>;
API: Service<typeof import("./server").Api>;
}Tip
更改 Wrangler 配置后,请重新运行 wrangler types;也可以在 CI 中运行 wrangler types --check,以发现过期的类型。
#在本地开发中访问绑定
在开发模式下,Nitro 使用 Miniflare 模拟 Cloudflare 环境(这是 Wrangler 和生产环境中的 Cloudflare Workers 使用的相同 workerd 运行时)。这意味着绑定可以直接从请求事件中原生访问,无需单独的代理。
miniflare 软件包由你的项目负责管理:Nitro 会从你的 node_modules 中解析它,并在首次使用时提供安装选项。
要在开发模式下访问绑定,请先定义绑定。你可以在 wrangler.jsonc/wrangler.json/wrangler.toml 文件中完成此操作(读取 wrangler.jsonc、wrangler.toml 和 .dev.vars 需要安装 wrangler 软件包):
[vars]
MY_VARIABLE="my-value"
[[kv_namespaces]]
binding = "MY_KV"
id = "xxx"或者,你也可以在 nitro.config.ts 中使用 cloudflare.wrangler 选项内联定义绑定(它接受与 wrangler.json 相同的结构):
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
cloudflare: {
wrangler: {
vars: {
MY_VARIABLE: "my-value",
},
kv_namespaces: [{ binding: "MY_KV", id: "xxx" }],
},
},
})从现在开始,运行
npm run dev时,你可以按照上面的示例从请求事件中访问 MY_VARIABLE 和 MY_KV。
与 wrangler dev 相比,有以下几点不同:
- 绑定(KV、D1、R2 等)的本地数据会持久化到
.wrangler/state/v3,并与wrangler dev共享。 - 无论
compatibility_date如何设置,都会使用已安装的miniflare所支持的最新兼容性日期。 - Nitro 会提供静态资源。可使用从
server.ts导出的本地 Durable Objects、Workflows 和WorkerEntrypoint;但无法使用指向其他 Worker 的绑定(services、tail_consumers、外部 Durable Objects 和 Workflows)以及队列消费者。 - 设置
cloudflare.wrangler后,它会与最近的 Wrangler 配置文件合并。
#Wrangler environments
如果你有多个 Wrangler 环境,你可以使用 cloudflare.wranglerEnv 选项指定在本地开发模拟时要使用的环境:
import { defineConfig } from "nitro";
export default defineConfig({
preset: 'cloudflare_module',
cloudflare: {
wranglerEnv: 'preview'
}
})