@astrojs/ cloudflare
此适配器允许 Astro 将你的 按需渲染路由及其功能部署到 Cloudflare,包括 服务器群岛,actions 以及 sessions。
如果你只是将 Astro 作为静态的站点构建器,则不需要适配器。
在我们的 Cloudflare Pages 部署指南 中了解如何部署 Astro 站点。
为什么选择 Astro Cloudflare
段落标题 为什么选择 Astro CloudflareCloudflare 的 开发者平台 为用户提供存储、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
段落标题 cloudflareModules类型: boolean
默认值: true
该功能默认启用。如果你想禁用它,设置 cloudflareModules
为 false
。
imageService
段落标题 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
段落标题 platformProxy决定是否以及如何将 Cloudflare 运行时添加到 astro dev
中。它包含对本地 workerd
绑定和 Cloudflare 特定值的代理和模拟,允许在 Node.js 开发过程中模拟运行时。阅读更多关于 Cloudflare 运行时 的信息。
此处提供的代理尽最大努力模拟真实生产环境。虽然它们旨在尽可能接近真实情况,但两者之间可能存在轻微的差异和不一致。
platformProxy.enabled
段落标题 platformProxy.enabled类型: boolean
默认值: true
用于决定是否在开发模式下启用 Cloudflare 运行时。
platformProxy.configPath
段落标题 platformProxy.configPath类型: string
默认值: undefined
用于定义 Wrangler 配置文件的路径。如果该项留空,那么它会在项目根目录下寻找 wrangler.toml
、wrangler.json
和 wrangler.jsonc
。
platformProxy.environment
段落标题 platformProxy.environment类型: string
默认值: undefined
用于设置使用的 Cloudflare 环境。你必须在 Wrangler 配置文件中选择一项环境,否则将会引发错误。
platformProxy.persist
段落标题 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
段落标题 routes.extend在 Cloudflare Workers 中,该选项不适用。请参考 Cloudflare Workers 路由 以获取更多信息。
在 Cloudflare Pages 中,此选项允许你添加或排除自定义模式(例如 /fonts/*
)到生成的 _routes.json
文件中,该文件决定了哪些路由是按需生成的。如果你需要添加无法自动生成的路由模式,或排除预渲染的路由,这会很有用。
关于自定义路由模式的更多信息,可以在 Cloudflare 的路由文档中找到。指定的任何路由都不会自动去重,将会按原样添加到现有路由中。
routes.extend.include
段落标题 routes.extend.include类型: { pattern: string }[]
默认值: undefined
在 routes.extend.include
数组中配置 Cloudflare 适配器按需生成的其他路由。
routes.extend.exclude
段落标题 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
段落标题 sessionKVBindingName类型: string
默认值: SESSION
astro@5.6.0
sessionKVBindingName
选项允许你指定用于会话存储的 KV 绑定的名称。默认情况下,该选项会被设置为 SESSION
,但你能够将其改变为匹配你个人 KV 绑定的名称。更多内容请参阅 Sessions。
export default defineConfig({ adapter: cloudflare({ sessionKVBindingName: 'MY_SESSION_BINDING', }),});
Cloudflare 运行时
段落标题 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 文档中的 所有支持的绑定列表。
环境变量与私密环境变量
段落标题 环境变量与私密环境变量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 平台
段落标题 Cloudflare 平台标头
段落标题 标头你可以通过在 Astro 项目的 public/
文件夹中添加一个 _headers
文件来附加 自定义标头 到你的响应中,该文件将被复制到构建输出目录中。
该方法也可以用于 Cloudflare Workers 和 Cloudflare Pages 中。
资源
段落标题 资源由 Astro 构建的所有资源都以哈希命名,因此可以为它们添加长期缓存标头。默认情况下,Cloudflare 上的 Astro 会为这些文件添加这样的头。
重定向
段落标题 重定向你可以声明一个 自定义重定向 从而将请求重定向到不同的 URL。为此,请在 Astro 项目的 public/
文件夹中添加一个 _redirects
文件,该文件将被复制到构建输出目录。
该方法也可以用于 Cloudflare Workers 和 Cloudflare Pages 中。
路由
段落标题 路由Cloudflare Workers 路由
段落标题 Cloudflare Workers 路由静态资源的路由是基于构建目录(例如 ./dist
)的文件结构的。如果不匹配,将会回退至按需渲染的 Worker。更多内容详见 Cloudflare Workers 静态资源路由。
不同于 Cloudflare Pages,使用 Workers 时,无需 _routes.json
文件。
目前,Cloudflare 适配器始终会生成该文件。为了解决这个问题,可在你的 public/
文件夹中创建一个 .assetsignore
文件,并向其添加以下内容:
_worker.js_routes.json
Cloudflare Pages 路由
段落标题 Cloudflare Pages 路由在 Cloudflare Pages 中,路由规则 通过 _routes.json
文件定义,用于决定哪些请求应路由至服务端函数(Server Function)处理,哪些应作为静态资源直接返回。默认情况下,系统会根据项目文件结构及配置自动生成此文件。
你可以通过在适配器配置文件中 指定额外的路由规则,或创建自定义的 _routes.json
文件来覆盖自动生成的结果。
创建自定义的 public/_routes.json
将覆盖这种自动生成的文件。参阅 Cloudflare 关于创建自定义 _routes.json
的文档 了解更多细节。
Sessions
段落标题 SessionsAstro 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 模块导入
段落标题 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 兼容性
段落标题 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 预览
段落标题 使用 Wrangler 预览为了使用 wrangler
在本地运行你的应用程序,请更新预览脚本:
对于 Workers:
"preview": "wrangler dev ./dist"
对于 Pages:
"preview": "wrangler pages dev ./dist"
使用 wrangler
部署能让你访问 Cloudflare 绑定、环境变量 和 cf 对象。要让热重载或 Astro 开发服务器与 Wrangler 工作,可能需要进行自定义设置。请参阅 社区示例。
有意义的错误消息
段落标题 有意义的错误消息目前,在 Wrangler 中运行应用程序时由于代码被压缩,错误消息并不是很有用。为了更好地进行调试,你可以将 vite.build.minify = false
添加到你的 astro.config.js
文件中。
export default defineConfig({ adapter: cloudflare(), vite: { build: { minify: false, }, },});