@astrojs/ cloudflare
此适配器允许 Astro 将你的 按需渲染路由及其功能部署到 Cloudflare,包括 服务器群岛,actions 以及 sessions。
如果你只是将 Astro 作为静态的站点构建器,则不需要适配器。
在我们的 Cloudflare Pages 部署指南 中了解如何部署 Astro 站点。
为什么选择 Astro Cloudflare
Section titled “为什么选择 Astro Cloudflare”Cloudflare 的 开发者平台 为用户提供存储、AI 等资源支持,助力开发全栈应用,并部署至全球边缘网络。此适配器专为 Astro 项目设计,可将其构建为符合 Cloudflare 部署要求的格式。
Astro 包含了一个 astro add
命令,用于自动设置官方集成。如果你愿意,可以改为 手动安装集成。
在你的 Astro 项目中使用 astro add
命令添加 Cloudflare 适配器,以启用服务器端渲染。这将安装 @astrojs/cloudflare
并一步到位地对你的 astro.config.mjs
文件进行相应的更改。
npx astro add cloudflare
pnpm astro add cloudflare
yarn astro add cloudflare
现在,你可以启用 对每个页面的按需渲染,或者将你的构建输出配置设置为 output: 'server'
从而 默认对所有页面都进行服务器端渲染。
首先,使用合适的包管理器将 @astrojs/cloudflare
适配器添加到项目的依赖项中。
npm install @astrojs/cloudflare
pnpm add @astrojs/cloudflare
yarn add @astrojs/cloudflare
然后,将适配器添加到 astro.config.mjs
文件中:
import { defineConfig } from 'astro/config';import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ adapter: cloudflare(),});
Cloudflare 适配器接受以下选项:
cloudflareModules
Section titled “cloudflareModules”类型: boolean
默认值: true
该功能默认启用。如果你想禁用它,设置 cloudflareModules
为 false
。
imageService
Section titled “imageService”类型: 'passthrough' | 'cloudflare' | 'compile' | 'custom'
默认值: 'compile'
确定适配器使用哪个图像服务。当配置了不兼容的图像服务时,适配器将默认使用 compile
模式。否则,它将使用全局配置的图像服务:
cloudflare
: 使用 Cloudflare 图像调整 服务。passthrough
: 使用现有的noop
服务。compile
: 使用 Astro 的默认服务(sharp),但仅在构建时对预渲染的路由有效。对按需渲染的页面,所有astro:assets
功能都将被禁用。custom
: 总是使用在 Image 选项 中配置的图像服务。此选项不会检查配置的图像服务是否在 Cloudflare 的workerd
运行时中工作。
import { defineConfig } from "astro/config";import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ adapter: cloudflare({ imageService: 'cloudflare' }),})
platformProxy
Section titled “platformProxy”决定是否以及如何将 Cloudflare 运行时添加到 astro dev
中。它包含对本地 workerd
绑定和 Cloudflare 特定值的代理和模拟,允许在 Node.js 开发过程中模拟运行时。阅读更多关于 Cloudflare 运行时 的信息。
此处提供的代理尽最大努力模拟真实生产环境。虽然它们旨在尽可能接近真实情况,但两者之间可能存在轻微的差异和不一致。
platformProxy.enabled
Section titled “platformProxy.enabled”类型: boolean
默认值: true
用于决定是否在开发模式下启用 Cloudflare 运行时。
platformProxy.configPath
Section titled “platformProxy.configPath”类型: string
默认值: undefined
用于定义 Wrangler 配置文件的路径。如果该项留空,那么它会在项目根目录下寻找 wrangler.toml
、wrangler.json
和 wrangler.jsonc
。
platformProxy.environment
Section titled “platformProxy.environment”类型: string
默认值: undefined
用于设置使用的 Cloudflare 环境。你必须在 Wrangler 配置文件中选择一项环境,否则将会引发错误。
platformProxy.persist
Section titled “platformProxy.persist”类型: boolean | { path: string }
默认值: true
用于设置是否在本地存储绑定数据,以及将绑定数据存储在本地文件系统中的何处。
- 如果设置为
true
,绑定数据会被存储在.wrangler/state/v3/
。该位置与 wrangler 的默认设置相同。 - 如果设置为
false
,绑定数据将不会被存储在本地文件系统中。 - 如果设置为
{ path: string }
,绑定数据将会存储在指定的路径下。
wrangler
的 --persist-to
选项会在底层添加一个名为 v3
的子目录,而 @astrojs/cloudflare
的 persist
属性则不会。例如,要重用与运行 wrangler dev --persist-to ./my-directory
相同的位置,你必须指定:persist: { path: "./my-directory/v3" }
。
以下配置展示了在运行开发服务器时启用 Cloudflare 运行时的示例,以及使用 wrangler.json
配置文件。它还指定了一个自定义位置,用于将数据持久化到文件系统中:
import cloudflare from '@astrojs/cloudflare';import { defineConfig } from 'astro/config';export default defineConfig({ adapter: cloudflare({ platformProxy: { enabled: true, configPath: 'wrangler.json', persist: { path: './.cache/wrangler/v3' }, }, }),});
routes.extend
Section titled “routes.extend”在 Cloudflare Workers 中,该选项不适用。请参考 Cloudflare Workers 路由 以获取更多信息。
在 Cloudflare Pages 中,此选项允许你添加或排除自定义模式(例如 /fonts/*
)到生成的 _routes.json
文件中,该文件决定了哪些路由是按需生成的。如果你需要添加无法自动生成的路由模式,或排除预渲染的路由,这会很有用。
关于自定义路由模式的更多信息,可以在 Cloudflare 的路由文档中找到。指定的任何路由都不会自动去重,将会按原样添加到现有路由中。
routes.extend.include
Section titled “routes.extend.include”类型: { pattern: string }[]
默认值: undefined
在 routes.extend.include
数组中配置 Cloudflare 适配器按需生成的其他路由。
routes.extend.exclude
Section titled “routes.extend.exclude”类型: { pattern: string }[]
默认值: undefined
在 routes.extend.exclude
数组中配置要从按需渲染中排除的路由。这些路由将预先渲染并以静态方式提供,而不会调用服务端函数。此外,你还可以使用这个选项直接提供任何静态资源(例如:图片、字体、css、js、html、txt、json 等)文件,无需通过服务端函数路由请求。
export default defineConfig({ adapter: cloudflare({ routes: { extend: { include: [{ pattern: '/static' }], // 将预渲染的页面路由到服务端函数以实现按需渲染 exclude: [{ pattern: '/pagefind/*' }], // 使用 Starlight 的 pagefind 搜索,该搜索在构建时静态生成 } }, }),});
sessionKVBindingName
Section titled “sessionKVBindingName”类型: string
默认值: SESSION
astro@5.6.0
sessionKVBindingName
选项允许你指定用于会话存储的 KV 绑定的名称。默认情况下,该选项会被设置为 SESSION
,但你能够将其改变为匹配你个人 KV 绑定的名称。更多内容请参阅 Sessions。
export default defineConfig({ adapter: cloudflare({ sessionKVBindingName: 'MY_SESSION_BINDING', }),});
workerEntryPoint
Section titled “workerEntryPoint”类型: { path: string | URL, namedExports: string[] }
默认值: { path: '@astrojs/cloudflare/entrypoints/server.js', namedExports: [] }
@astrojs/cloudflare@12.6.0
新
该配置对象允许你在使用 astro build
命令时为 Cloudflare Worker 指定 workerEntryPoint。
你可以选择性地指定自定义文件的 path
和 namedExports
:
import cloudflare from '@astrojs/cloudflare';import { defineConfig } from 'astro/config';
export default defineConfig({ adapter: cloudflare({ workerEntryPoint: { path: 'src/worker.ts', namedExports: ['MyDurableObject'] } }),});
workerEntryPoint.path
Section titled “workerEntryPoint.path”类型: string
默认值: @astrojs/cloudflare/entrypoints/server.js
@astrojs/cloudflare@12.6.0
新
入口文件的路径。应为 Astro 项目根目录下的相对路径。
默认情况下,适配器会使用一个通用入口文件,仅支持 fetch
处理器。
如需支持其他 Cloudflare 调用处理器,可创建自定义入口文件。这对于需要 Durable Objects、Cloudflare Queues、Scheduled Invocations 等功能时非常有用。
workerEntryPoint.namedExports
Section titled “workerEntryPoint.namedExports”类型: []
默认值: ['default']
@astrojs/cloudflare@12.6.0
新
为入口文件提供额外的命名导出。
如有自定义入口文件(如 DurableObject),可在此处指定命名导出。若未指定,仅包含默认导出。
创建自定义 Cloudflare Worker 入口文件
Section titled “创建自定义 Cloudflare Worker 入口文件”自定义入口文件必须导出 createExports()
函数,并通过 default
导出包含所有所需处理器。
以下示例注册了 Durable Object 和队列处理器:
import type { SSRManifest } from 'astro';import { App } from 'astro/app';import { handle } from '@astrojs/cloudflare/handler'import { DurableObject } from 'cloudflare:workers';
class MyDurableObject extends DurableObject<Env> { constructor(ctx: DurableObjectState, env: Env) { super(ctx, env) }}
export function createExports(manifest: SSRManifest) { const app = new App(manifest); return { default: { async fetch(request, env, ctx) { await env.MY_QUEUE.send("log"); return handle(manifest, app, request, env, ctx); }, async queue(batch, _env) { let messages = JSON.stringify(batch.messages); console.log(`consumed from our queue: ${messages}`); } } satisfies ExportedHandler<Env>, MyDurableObject: MyDurableObject, }}
Cloudflare 运行时
Section titled “Cloudflare 运行时”Cloudflare 运行时允许你访问环境变量并绑定 Cloudflare 资源。
Cloudflare 运行时使用在 wrangler.toml
/wrangler.json
配置文件中找到的绑定。
你可以从 Astro.locals.runtime
中访问绑定:
---const { env } = Astro.locals.runtime;---
你也可以通过 context.locals
从 API 端点访问运行时:
export function GET(context) { const runtime = context.locals.runtime; return new Response('Some body');}
请查看 Cloudflare 文档中的 所有支持的绑定列表。
环境变量与私密环境变量
Section titled “环境变量与私密环境变量”CloudFlare 运行时将环境变量视为一种绑定。
例如,你可以在 wrangler.json
中对 环境变量 进行如下定义:
{ "vars" : { "MY_VARIABLE": "test" }}
私密环境变量(Secrets)是一种特殊类型的环境变量,它允许你将加密的文本值附加至 Cloudflare Worker。为确保设置后其内容不可见,私密环境变量需通过专用方式定义。
要定义 secrets
,请通过 Wrangler CLI 来完成添加,而不是在 Wrangler 配置文件中添加。
npx wrangler secret put <KEY>
要为本地开发设置私密环境变量,你还需要在 Astro 项目根目录中添加一个 .dev.vars
文件:
DB_PASSWORD=myPassword
接下来你就可以访问环境变量,包括私密环境变量了,它们可以在 Astro.locals.runtime
的 env
对象中被找到:
---const { env } = Astro.locals.runtime;const myVariable = env.MY_VARIABLE;---
Cloudflare 的环境变量和私密环境变量与 astro:env
API 相兼容。
wrangler
提供了一个 types
命令来为绑定生成 TypeScript 类型。这允许你对本地变量进行类型定义,而无需手动输入它们。更多信息请参考 Cloudflare 文档。
每次更改配置文件(例如 wrangler.toml
、.dev.vars
)时,你需要运行 wrangler types
。
你可以创建一个 pnpm 脚本来自动在其他命令之前运行 wrangler types
。
{ "scripts": { "dev": "wrangler types && astro dev", "start": "wrangler types && astro dev", "build": "wrangler types && astro check && astro build", "preview": "wrangler types && astro preview", "astro": "astro" }}
你可以使用 Runtime
来为 runtime
对象添加类型:
type Runtime = import('@astrojs/cloudflare').Runtime<Env>;
declare namespace App { interface Locals extends Runtime { otherLocals: { test: string; }; }}
Cloudflare 平台
Section titled “Cloudflare 平台”你可以通过在 Astro 项目的 public/
文件夹中添加一个 _headers
文件来附加 自定义标头 到你的响应中,该文件将被复制到构建输出目录中。
该方法也可以用于 Cloudflare Workers 和 Cloudflare Pages 中。
由 Astro 构建的所有资源都以哈希命名,因此可以为它们添加长期缓存标头。默认情况下,Cloudflare 上的 Astro 会为这些文件添加这样的头。
你可以声明一个 自定义重定向 从而将请求重定向到不同的 URL。为此,请在 Astro 项目的 public/
文件夹中添加一个 _redirects
文件,该文件将被复制到构建输出目录。
该方法也可以用于 Cloudflare Workers 和 Cloudflare Pages 中。
Cloudflare Workers 路由
Section titled “Cloudflare Workers 路由”静态资源的路由是基于构建目录(例如 ./dist
)的文件结构的。如果不匹配,将会回退至按需渲染的 Worker。更多内容详见 Cloudflare Workers 静态资源路由。
不同于 Cloudflare Pages,使用 Workers 时,无需 _routes.json
文件。
目前,Cloudflare 适配器始终会生成该文件。为了解决这个问题,可在你的 public/
文件夹中创建一个 .assetsignore
文件,并向其添加以下内容:
_worker.js_routes.json
Cloudflare Pages 路由
Section titled “Cloudflare Pages 路由”在 Cloudflare Pages 中,路由规则 通过 _routes.json
文件定义,用于决定哪些请求应路由至服务端函数(Server Function)处理,哪些应作为静态资源直接返回。默认情况下,系统会根据项目文件结构及配置自动生成此文件。
你可以通过在适配器配置文件中 指定额外的路由规则,或创建自定义的 _routes.json
文件来覆盖自动生成的结果。
创建自定义的 public/_routes.json
将覆盖这种自动生成的文件。参阅 Cloudflare 关于创建自定义 _routes.json
的文档 了解更多细节。
Sessions
Section titled “Sessions”Astro Session API 允许你在请求间,轻松地存储用户数据。该功能可用于用户数据和偏好选项,购物车内容,资格鉴权。不同于 cookie 存储,这里不存在对数据大小的限制,并且可以将其存储在不同的设备上。
当使用 Cloudflare 适配器时,Astro 会自动配置用于会话(session)存储的 Workers KV。但在使用会话前,你还需要创建一个 KV 命名空间来存储数据并在你的 Wrangler 配置文件中对 KV 绑定进行配置。默认绑定名需为 SESSION
,若需自定义名称,请通过适配器配置文件中的 sessionKVBindingName
选项来指定。
-
使用 Wrangler CLI 创建一个 KV 命名空间并记录下新命名空间的 ID:
终端窗口 npx wrangler kv namespace create "SESSION" -
在你的 Wrangler 配置文件中,声明 KV 命名空间,ID 是运行上一个命令时所返回的内容:
wrangler.json {"kv_namespaces": [{"binding": "SESSION","id": "<KV_NAMESPACE_ID>"}]}wrangler.toml kv_namespaces = [{ binding = "SESSION", id = "<KV_NAMESPACE_ID>" }] -
接下来你就可以在你的服务器代码中使用会话了:
src/components/CartButton.astro ---export const prerender = false;const cart = await Astro.session?.get('cart');---<a href="/checkout">🛒 {cart?.length ?? 0} items</a>
对 Cloudflare KV 的写入操作在跨区域时遵循 最终一致性原则。这意味着:在同一区域内,数据变更会立即生效,而跨区域同步的变更可能需要最多 60 秒才能完成全球节点同步。这对大多数用户来说是无感的,因为常规用户不会在连续请求间切换地理区域,但是仍有部分用例会受影响,例如那些 VPN 用户。
Cloudflare 模块导入
Section titled “Cloudflare 模块导入”Cloudflare workerd
运行时支持导入一些 非标准模块类型。大多数额外的文件类型在 Astro 中也是可用的:
.wasm
或.wasm?module
:导出一个可以实例化的WebAssembly.Module
.bin
:导出文件的原始二进制内容,类型为ArrayBuffer
.txt
:导出文件内容的字符串形式
所有模块类型都导出一个默认值。模块既可以从服务器端渲染的页面导入,也可以从预渲染的页面导入,以生成静态站点。
以下是导入一个 Wasm 模块的示例,该模块通过将请求的数字参数相加来响应请求:
// 导入 WebAssembly 模块import mod from '../util/add.wasm?module';
// 先实例化才能使用const addModule: any = new WebAssembly.Instance(mod);
export async function GET(context) { const a = Number.parseInt(context.params.a); const b = Number.parseInt(context.params.b); return new Response(`${addModule.exports.add(a, b)}`);}
虽然这个例子很简单,但是 Wasm 可以用来加速在不涉及大量 I/O 的情况下的计算密集型操作,比如嵌入图像处理库,或嵌入小型预索引数据库以在只读数据集上进行搜索。
Node.js 兼容性
Section titled “Node.js 兼容性”默认情况下,Cloudflare 不支持 Node.js 运行时 API。但通过一些配置,Cloudflare 可以支持 Node.js 运行时 API 的一个子集。你可以在 Cloudflare 的文档中找到支持的 Node.js 运行时 API。
如果要使用这些 API,你的页面或端点必须是服务器渲染的(而不是预渲染的),并使用 import {} from 'node:*'
导入语法。
export const prerender = false;import { Buffer } from 'node:buffer';
你还需要修改你的 Astro 配置中的 vite
配置,以允许使用 node:*
导入语法:
import { defineConfig } from "astro/config";import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ adapter: cloudflare({}), vite: { ssr: { external: ['node:buffer'], }, },})
此外,你还需要遵循 Cloudflare 的文档来启用支持。具体指导,请参考 Cloudflare 关于启用 Node.js 兼容性的文档。
如果一个项目将一个包导入到服务器中,而该包使用了 Node.js 运行时 API,这在部署到 Cloudflare 时可能会引起问题。这个问题出现在不使用 node:*
导入语法的包上。建议你联系包的作者,以确定该包是否支持上述导入语法。如果该包不支持这种语法,你可能需要使用另一个包。
使用 Wrangler 预览
Section titled “使用 Wrangler 预览”为了使用 wrangler
在本地运行你的应用程序,请更新预览脚本:
对于 Workers:
"preview": "wrangler dev ./dist"
对于 Pages:
"preview": "wrangler pages dev ./dist"
使用 wrangler
部署能让你访问 Cloudflare 绑定、环境变量 和 cf 对象。要让热重载或 Astro 开发服务器与 Wrangler 工作,可能需要进行自定义设置。请参阅 社区示例。
有意义的错误消息
Section titled “有意义的错误消息”目前,在 Wrangler 中运行应用程序时由于代码被压缩,错误消息并不是很有用。为了更好地进行调试,你可以将 vite.build.minify = false
添加到你的 astro.config.js
文件中。
export default defineConfig({ adapter: cloudflare(), vite: { build: { minify: false, }, },});