@astrojs/ cloudflare
此适配器允许 Astro 将你的按需渲染的路由和功能部署到Cloudflare,包括服务端岛屿、操作和会话。
如果你将 Astro 用作静态站点构建器,则不需要适配器。
在我们的Cloudflare 部署指南中了解如何部署你的 Astro 站点。
为何选择 Astro Cloudflare
标题为“为何选择 Astro Cloudflare”的部分Cloudflare 的开发者平台让你能够开发全栈应用程序,并能访问存储和 AI 等资源,所有这些都部署在全球边缘网络上。此适配器会构建你的 Astro 项目,以便通过 Cloudflare 进行部署。
Astro 包含一个 astro add
命令来自动设置官方集成。如果你愿意,也可以手动安装集成。
使用 astro add
命令添加 Cloudflare 适配器,以在你的 Astro 项目中启用服务端渲染。这将一步到位地安装 @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
:始终使用在图像选项中配置的图像服务。此选项不会检查所配置的图像服务是否能在 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 上,此选项允许你向生成的 _routes.json
文件添加或排除自定义模式(例如 /fonts/*
),该文件决定了哪些路由是按需生成的。如果你需要添加无法自动生成的路由模式,或排除预渲染的路由,这将非常有用。
有关自定义路由模式的更多信息,请参阅 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' }], // Route a prerended page to the server function for on-demand rendering exclude: [{ pattern: '/pagefind/*' }], // Use Starlight's pagefind search, which is generated statically at build time } }, }),});
sessionKVBindingName
标题为“sessionKVBindingName”的部分类型: string
默认: 'SESSION'
astro@5.6.0
sessionKVBindingName
选项允许你指定用于会话存储的 KV 绑定的名称。默认情况下,它被设置为 SESSION
,但你可以更改它以匹配你自己的 KV 绑定名称。更多信息请参阅会话。
export default defineConfig({ adapter: cloudflare({ sessionKVBindingName: 'MY_SESSION_BINDING', }),});
workerEntryPoint
标题为“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
标题为“workerEntryPoint.path”的部分类型: string
默认: @astrojs/cloudflare/entrypoints/server.js
@astrojs/cloudflare@12.6.0
新增
入口文件的路径。这应该是相对于你 Astro 项目根目录的相对路径。
默认情况下,适配器使用一个通用的入口文件,它只支持 fetch
处理器。
要支持其他的Cloudflare 调用处理器,你可以创建一个自定义文件作为入口点。如果你想使用需要其他处理器的功能(例如,持久化对象、Cloudflare 队列、计划调用),这将非常有用。
workerEntryPoint.namedExports
标题为“workerEntryPoint.namedExports”的部分类型: string[]
默认: ['default']
@astrojs/cloudflare@12.6.0
新增
用于入口文件的命名导出的数组。
提供你的自定义入口文件的任何其他已定义的命名导出(例如 DurableObject
)。如果未提供,则仅包含默认导出。
创建自定义 Cloudflare Worker 入口文件
标题为“创建自定义 Cloudflare Worker 入口文件”的部分自定义入口文件必须导出一个 createExports()
函数,并带有一个 default
导出,其中包含你需要的所有处理器。
以下示例入口文件注册了一个持久化对象和一个队列处理器
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 运行时
标题为“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" }}
密钥是一种特殊类型的环境变量,允许你将加密的文本值附加到你的 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;const secret = env.DB_PASSWORD;---
Cloudflare 环境变量和密钥与 astro:env
API 兼容。
类型定义
标题为“类型定义”的部分wrangler
提供了一个 types
命令来为绑定生成 TypeScript 类型。这使你能够为 locals 添加类型,而无需手动键入它们。有关更多信息,请参阅 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 和 Pages 上均可用。
静态资源
标题为“静态资源”的部分由 Astro 构建的静态资源都以哈希命名,因此可以为其设置长缓存标头。默认情况下,Cloudflare 上的 Astro 会为这些文件添加这样的标头。
重定向
标题为“重定向”的部分你可以声明自定义重定向以将请求重定向到不同的 URL。为此,请在 Astro 项目的 public/
文件夹中添加一个 _redirects
文件。该文件将被复制到你的构建输出目录。
此功能在 Cloudflare Workers 和 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
文件来确定哪些请求被路由到服务端函数,哪些作为静态资源提供。默认情况下,会根据项目的文件和配置自动为你的项目生成一个 _routes.json
文件。
你可以在你的适配器配置中指定要遵循的额外路由模式,或者创建你自己的自定义 _routes.json
文件来完全覆盖自动生成。
创建一个自定义的 public/_routes.json
将覆盖自动生成。有关更多详细信息,请参阅Cloudflare 关于创建自定义 _routes.json
的文档。
Astro 会话 API 允许你在请求之间轻松存储用户数据。这可以用于用户数据和偏好设置、购物车和身份验证凭据等。与 cookie 存储不同,数据没有大小限制,并且可以在不同设备上恢复。
当使用 Cloudflare 适配器时,Astro 会自动为会话存储配置 Workers KV。在使用会话之前,你需要创建一个 KV 命名空间来存储数据,并在你的 Wrangler 配置文件中配置一个 KV 绑定。默认情况下,Astro 期望 KV 绑定的名称为 SESSION
,但如果你愿意,可以通过在适配器配置中设置 sessionKVBindingName
选项来选择不同的名称。
-
使用 Wrangler CLI 创建一个 KV 命名空间,并记下新命名空间的 ID
终端窗口 npx wrangler kv namespace create "SESSION" -
在你的 Wrangler 配置中声明 KV 命名空间,将命名空间 ID 设置为上一个命令返回的 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 模块的示例,该模块通过将请求的数字参数相加来响应请求。
// Import the WebAssembly moduleimport mod from '../util/add.wasm';
// Instantiate first in order to use itconst 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.mjs
中。
export default defineConfig({ adapter: cloudflare(), vite: { build: { minify: false, }, },});