关于 cloudflare-nextjs
使用 OpenNext Cloudflare adapter 将 Next.js 应用部署到 Cloudflare Workers 的指南 Skill。它涵盖新项目配置、现有应用迁移、开发与 workerd 预览流程、配置要求和常见部署错误。
主要功能
- 01OpenNext adapter 设置
- 02新项目与迁移指南
- 03Next.js 和 workerd 测试流程
- 04Wrangler 与 Cloudflare 绑定配置
- 05部署错误排查
适用场景
- 01将新的 Next.js 应用部署到 Cloudflare Workers
- 02迁移现有 Next.js 应用
- 03部署前测试 Workers 特有行为
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackspace/ claudeskillz --skill cloudflare-nextjs安装后在 Claude Code 中输入/cloudflare-nextjs确认已加载。
附带文件README.mdSKILL.json
详细介绍
Cloudflare Next.js 部署技能
使用 OpenNext Cloudflare 适配器将 Next.js 应用部署到 Cloudflare Workers,实现可用于生产环境的无服务器 Next.js 托管。
适用场景
- 将 Next.js 应用(App Router 或 Pages Router)部署到 Cloudflare Workers
- 需要在 Cloudflare 上实现服务端渲染(SSR)、静态站点生成(SSG)或增量静态再生成(ISR)
- 将现有 Next.js 应用从 Vercel、AWS 或其他平台迁移到 Cloudflare
- 使用 Cloudflare 服务(D1、R2、KV、Workers AI)构建全栈 Next.js 应用
- 需要在 Workers 上使用 React Server Components、Server Actions 或 Next.js 中间件
- 希望通过 Cloudflare 的网络实现全球边缘部署
核心概念
OpenNext 适配器架构
OpenNext Cloudflare 适配器(@opennextjs/cloudflare)会将 Next.js 构建产物转换为兼容 Cloudflare Worker 的格式。这与标准 Next.js 部署方式有本质区别:
- 需要 Node.js 运行时:在 Workers 中使用 Node.js 运行时(而非 Edge 运行时)
- 双重开发工作流:同时在 Next.js 开发服务器和 workerd 运行时中测试
- 自定义构建流程:
next build→ OpenNext 转换 → Worker 部署 - Cloudflare 专属配置:需要 wrangler.jsonc 和 open-next.config.ts
与标准 Next.js 的关键区别
| 方面 | 标准 Next.js | Cloudflare Workers |
|---|---|---|
| 运行时 | Node.js 或 Edge | Node.js(通过 nodejs_compat) |
| 开发服务器 | next dev | next dev + opennextjs-cloudflare preview |
| 部署 | 取决于平台 | opennextjs-cloudflare deploy |
| Worker 大小 | 无限制 | 3 MiB(免费)/ 10 MiB(付费) |
| 数据库连接 | 可使用全局客户端 | 必须限定在请求范围内 |
| 图像优化 | 内置 | 通过 Cloudflare Images 实现 |
| 缓存 | Next.js 缓存 | OpenNext 配置 + Workers 缓存 |
设置模式
新项目设置
使用 Cloudflare 的 create-cloudflare(C3)CLI 创建新 Next.js 项目,并预先配置 Workers:
npm create cloudflare@latest -- my-next-app --framework=next
执行内容:
- 运行 Next.js 官方设置工具(
create-next-app) - 安装
@opennextjs/cloudflare适配器 - 创建配置正确的
wrangler.jsonc - 创建用于缓存配置的
open-next.config.ts - 向
package.json添加部署脚本 - 可选择立即部署到 Cloudflare
开发工作流:
npm run dev # Next.js dev server (fast reloads)
npm run preview # Test in workerd runtime (production-like)
npm run deploy # Build and deploy to Cloudflare
迁移现有项目
要向现有 Next.js 应用添加 OpenNext 适配器:
1. 安装适配器
npm install --save-dev @opennextjs/cloudflare
2. 创建 wrangler.jsonc
{
"name": "my-next-app",
"compatibility_date": "2025-05-05",
"compatibility_flags": ["nodejs_compat"]
}
关键配置:
compatibility_date:最低为2025-05-05(用于支持 FinalizationRegistry)compatibility_flags:必须包含nodejs_compat(用于 Node.js 运行时)
3. 创建 open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// Caching configuration (optional)
// See: https://opennext.js.org/cloudflare/caching
});
4. 更新 package.json 脚本
{
"scripts": {
"dev": "next dev",
"build": "next build",
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
}
}
脚本用途:
dev:Next.js 开发服务器(快速迭代)preview:构建并在 workerd 运行时中运行(部署前测试)deploy:构建并部署到 Cloudflarecf-typegen:为 Cloudflare 绑定生成 TypeScript 类型
5. 确保使用 Node.js 运行时(而非 Edge)
从应用中移除 Edge 运行时导出:
// ❌ REMOVE THIS (Edge runtime not supported)
export const runtime = "edge";
// ✅ Use Node.js runtime (default)
// No export needed - Node.js is default
开发工作流
双重测试策略
务必在两种环境中都进行测试:
-
Next.js 开发服务器(
npm run dev)- 热重载速度快
- 开发体验最佳
- 在 Node.js 中运行(不是生产运行时)
- 用于快速迭代
-
Workerd 运行时(
npm run preview)- 在接近生产的环境中运行
- 可发现运行时特有的问题
- 重建时间较长
- 部署前必须运行
何时使用各环境
# Iterating on UI/logic → Use Next.js dev server
npm run dev
# Testing integrations (D1, R2, KV) → Use preview
npm run preview
# Before deploying → ALWAYS test preview
npm run preview
# Deploy to production
npm run deploy
配置要求
Wrangler 配置
wrangler.jsonc 中的最低要求:
{
"name": "your-app-name",
"compatibility_date": "2025-05-05", // Minimum for FinalizationRegistry
"compatibility_flags": ["nodejs_compat"] // Required for Node.js runtime
}
包导出的环境变量
如果使用具有多个导出条件的 npm 包,请创建 .env:
WRANGLER_BUILD_CONDITIONS=""
WRANGLER_BUILD_PLATFORM="node"
这可确保 Wrangler 在 node 导出可用时优先使用它。
Cloudflare 绑定集成
在 wrangler.jsonc 中添加绑定:
{
"name": "your-app-name",
"compatibility_date": "2025-05-05",
"compatibility_flags": ["nodejs_compat"],
// D1 Database
"d1_databases": [
{
"binding": "DB",
"database_name": "production-db",
"database_id": "your-database-id"
}
],
// R2 Storage
"r2_buckets": [
{
"binding": "BUCKET",
"bucket_name": "your-bucket"
}
],
// KV Storage
"kv_namespaces": [
{
"binding": "KV",
"id": "your-kv-id"
}
],
// Workers AI
"ai": {
"binding": "AI"
}
}
在 Next.js 中通过 process.env 访问绑定:
// app/api/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
// Access Cloudflare bindings
const env = process.env as any;
// D1 Database query
const result = await env.DB.prepare('SELECT * FROM users').all();
// R2 Storage access
const file = await env.BUCKET.get('file.txt');
// KV Storage access
const value = await env.KV.get('key');
// Workers AI inference
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
prompt: 'Hello AI'
});
return Response.json({ result });
}
错误预防(记录了 10 种以上错误)
1. 超出 Worker 大小限制(3 MiB - 免费计划)
错误:"Your Worker exceeded the size limit of 3 MiB"
原因:Workers 免费计划将 Worker 大小限制为 3 MiB(gzip 压缩后)
解决方案:
- 升级到 Workers 付费计划(限制为 10 MiB)
- 分析打包大小并移除未使用的依赖
- 使用动态导入对大型依赖进行代码分割
打包分析:
npx opennextjs-cloudflare build
cd .open-next/server-functions/default
# Analyze handler.mjs.meta.json with ESBuild Bundle Analyzer
来源:https://opennext.js.org/cloudflare/troubleshooting#worker-size-limits
2. 超出 Worker 大小限制(10 MiB - 付费计划)
错误:"Your Worker exceeded the size limit of 10 MiB"
原因:不必要的代码被打包进 Worker
调试工作流:
- 运行
npx opennextjs-cloudflare build - 前往
.open-next/server-functions/default - 使用 ESBuild Bundle Analyzer 分析
handler.mjs.meta.json - 找出并移除大型依赖,或将其外置
来源:https://opennext.js.org/cloudflare/troubleshooting#worker-size-limits
3. 未定义 FinalizationRegistry
错误:"ReferenceError: FinalizationRegistry is not defined"
原因:wrangler.jsonc 中的 compatibility_date 设置过早
解决方案:将 compatibility_date 更新为 2025-05-05 或更晚的日期:
{
"compatibility_date": "2025-05-05" // Minimum for FinalizationRegistry
}
来源:https://opennext.js.org/cloudflare/troubleshooting#finalizationregistry-is-not-defined
4. 无法代表其他请求执行 I/O
错误:"Cannot perform I/O on behalf of a different request"
原因:数据库客户端在全局范围内创建,并在多个请求间重复使用
问题代码:
// ❌ WRONG: Global DB client
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export async function GET() {
// This will fail - pool created in different request context
const result = await pool.query('SELECT * FROM users');
return Response.json(result);
}
解决方案:在请求处理程序内部创建数据库客户端:
// ✅ CORRECT: Request-scoped DB client
import { Pool } from 'pg';
export async function GET() {
// Create client within request context
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const result = await pool.query('SELECT * FROM users');
await pool.end();
return Response.json(result);
}
替代方案:使用专为 Workers 设计的 Cloudflare D1,而不是外部数据库:
// ✅ BEST: Use D1 (no connection pooling needed)
export async function GET(request: NextRequest) {
const env = process.env as any;
const result = await env.DB.prepare('SELECT * FROM users').all();
return Response.json(result);
}
5. NPM 包导入失败
错误:"Could not resolve '<package>'"
原因:缺少 nodejs_compat 标志或包导出条件
解决方案 1:启用 nodejs_compat 标志:
{
"compatibility_flags": ["nodejs_compat"]
}
解决方案 2:对于具有多个导出的包,创建 .env:
WRANGLER_BUILD_CONDITIONS=""
WRANGLER_BUILD_PLATFORM="node"
来源:https://opennext.js.org/cloudflare/troubleshooting#npm-packages-fail-to-import
6. 无法加载代码块(Turbopack)
错误:"Failed to load chunk server/chunks/ssr/"
原因:Next.js 使用 Turbopack 构建(next build --turbo)
解决方案:使用标准构建方式(适配器不支持 Turbopack):
{
"scripts": {
"build": "next build" // ✅ Correct
// "build": "next build --turbo" // ❌ Don't use Turbopack
}
}
来源:https://opennext.js.org/cloudflare/troubleshooting#failed-to-load-chunk
7. SSRF 漏洞(CVE-2025-6087)
漏洞:通过 /_next/image 端点发起的服务端请求伪造
受影响版本:@opennextjs/cloudflare < 1.3.0
解决方案:升级到 1.3.0 或更高版本:
npm install --save-dev @opennextjs/cloudflare@^1.3.0
影响:允许未经过身份验证的用户代理任意远程内容
来源:https://github.com/advisories/GHSA-rvpw-p7vw-wj3m
8. Durable Objects 绑定警告
警告:"You have defined bindings to the following internal Durable Objects... will not work in local development, but they should work in production"
原因:OpenNext 使用 Durable Objects 进行缓存(DOQueueHandler、DOShardedTagCache)
解决方案:可安全忽略——这是预期行为
替代方案(用于隐藏警告):在单独的 Worker 中定义 Durable Objects,并使用其自身配置
来源:https://opennext.js.org/cloudflare/known-issues#caching-durable-objects
9. Prisma + D1 中间件冲突
错误:在 Next.js 中间件中使用 @prisma/client + @prisma/adapter-d1 时出现构建错误
原因:在中间件上下文中初始化数据库
解决方法:在路由处理程序中初始化 Prisma 客户端,而不是在中间件中初始化
来源:https://github.com/opennextjs/opennextjs-cloudflare/issues/471
10. cross-fetch 库错误
错误:使用依赖于 cross-fetch 的库时出现错误
原因:OpenNext 会修补部署包,导致 cross-fetch 在原生 fetch 可用时尝试使用 Node.js 库
解决方案:直接使用原生 fetch API,而不是使用 cross-fetch:
// ✅ Use native fetch
const response = await fetch('https://api.example.com/data');
// ❌ Avoid cross-fetch
// import fetch from 'cross-fetch';
来源:https://opennext.js.org/cloudflare/troubleshooting
11. Windows 开发问题
问题:无法保证完全支持 Windows
原因:Next.js 底层工具在 Windows 上存在问题
解决方案:
- 使用 WSL(适用于 Linux 的 Windows 子系统)
- 使用 Linux 虚拟机
- 使用基于 Linux 的 CI/CD 进行部署
来源:https://opennext.js.org/cloudflare#windows-support
功能支持矩阵
| 功能 | 状态 | 备注 |
|---|---|---|
| App Router | ✅ 完全支持 | 最新的 App Router 功能均可正常使用 |
| Pages Router | ✅ 完全支持 | 支持旧版 Pages Router |
| Route Handlers | ✅ 完全支持 | API 路由可按预期运行 |
| React Server Components | ✅ 完全支持 | RSC 功能完整 |
| Server Actions | ✅ 完全支持 | Server Actions 可正常运行 |
| SSG | ✅ 完全支持 | 静态站点生成 |
| SSR | ✅ 完全支持 | 服务端渲染 |
| ISR | ✅ 完全支持 | 增量静态再生成 |
| Middleware | ✅ 支持 | Node.js 中间件除外(15.2+) |
| Image Optimization | ✅ 支持 | 通过 Cloudflare Images 实现 |
| Partial Prerendering (PPR) | ✅ 支持 | 在 Next.js 中为实验性功能 |
| Composable Caching | ✅ 支持 | 'use cache' 指令 |
| Response Streaming | ✅ 支持 | 支持流式响应 |
next/after API | ✅ 支持 | 响应后的异步工作 |
| Node.js Middleware (15.2+) | ❌ 不支持 | 计划在未来支持 |
| Edge Runtime | ❌ 不支持 | 请使用 Node.js runtime |
与 Cloudflare 服务集成
D1 数据库(SQL)
// app/api/users/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as any;
const result = await env.DB.prepare(
'SELECT * FROM users WHERE active = ?'
).bind(true).all();
return Response.json(result.results);
}
export async function POST(request: NextRequest) {
const env = process.env as any;
const { name, email } = await request.json();
const result = await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind(name, email).run();
return Response.json({ id: result.meta.last_row_id });
}
Wrangler 配置:
{
"d1_databases": [
{
"binding": "DB",
"database_name": "production-db",
"database_id": "your-database-id"
}
]
}
另请参阅:cloudflare-d1 skill,了解完整的 D1 模式
R2 存储(对象存储)
// app/api/upload/route.ts
import type { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const env = process.env as any;
const formData = await request.formData();
const file = formData.get('file') as File;
// Upload to R2
await env.BUCKET.put(file.name, file.stream(), {
httpMetadata: {
contentType: file.type
}
});
return Response.json({ success: true, filename: file.name });
}
export async function GET(request: NextRequest) {
const env = process.env as any;
const { searchParams } = new URL(request.url);
const filename = searchParams.get('file');
const object = await env.BUCKET.get(filename);
if (!object) {
return new Response('Not found', { status: 404 });
}
return new Response(object.body, {
headers: {
'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream'
}
});
}
另请参阅:cloudflare-r2 skill,了解完整的 R2 模式
Workers AI(模型推理)
// app/api/ai/route.ts
import type { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const env = process.env as any;
const { prompt } = await request.json();
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
prompt
});
return Response.json(response);
}
Wrangler 配置:
{
"ai": {
"binding": "AI"
}
}
另请参阅:cloudflare-workers-ai skill,了解完整的 AI 模式
KV 存储(键值)
// app/api/cache/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as any;
const { searchParams } = new URL(request.url);
const key = searchParams.get('key');
const value = await env.KV.get(key);
return Response.json({ key, value });
}
export async function PUT(request: NextRequest) {
const env = process.env as any;
const { key, value, ttl } = await request.json();
await env.KV.put(key, value, { expirationTtl: ttl });
return Response.json({ success: true });
}
另请参阅:cloudflare-kv skill,了解完整的 KV 模式
图像优化
Next.js 图像优化通过 Cloudflare Images 实现。在 open-next.config.ts 中配置:
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
imageOptimization: {
loader: 'cloudflare'
}
});
在组件中使用:
import Image from 'next/image';
export default function Avatar() {
return (
<Image
src="/avatar.jpg"
alt="User avatar"
width={200}
height={200}
// Automatically optimized via Cloudflare Images
/>
);
}
计费:Cloudflare Images 的使用费用单独计算
文档:https://developers.cloudflare.com/images/
缓存配置
在 open-next.config.ts 中配置缓存行为:
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// Custom cache configuration
cache: {
// Override default cache behavior
// See: https://opennext.js.org/cloudflare/caching
}
});
默认行为:OpenNext 提供合理的默认缓存设置
高级用法:请参阅 OpenNext 官方缓存文档
已知限制
尚不支持
-
Node.js Middleware(Next.js 15.2+)
- 在 Next.js 15.2 中引入
- 计划在未来版本中支持
- 目前请使用标准中间件
-
Edge Runtime
- 仅支持 Node.js runtime
- 请从应用中移除
export const runtime = "edge"
-
完全支持 Windows
- 无法保证在 Windows 上进行开发时一切正常
- 请使用 WSL、VM 或基于 Linux 的 CI/CD
Worker 大小限制
- 免费计划:限制为 3 MiB(gzip 压缩后)
- 付费计划:限制为 10 MiB(gzip 压缩后)
- 开发期间监控打包文件大小
- 使用动态导入进行代码拆分
数据库连接
- 外部数据库客户端(PostgreSQL、MySQL)必须限定在单个请求范围内
- 不能跨请求重用连接(Workers 的限制)
- 数据库需求优先使用 Cloudflare D1(专为 Workers 设计)
部署
从本地计算机部署
# Build and deploy in one command
npm run deploy
# Or step by step:
npx opennextjs-cloudflare build
npx opennextjs-cloudflare deploy
从 CI/CD 部署
在 CI/CD 系统中配置部署命令:
npm run deploy
示例:
- GitHub Actions:
.github/workflows/deploy.yml - GitLab CI:
.gitlab-ci.yml - Cloudflare Workers Builds:自动检测
npm run deploy
环境变量:在 Cloudflare 控制面板或 CI/CD 系统中设置密钥
自定义域名
在 Cloudflare 控制面板中添加自定义域名:
- 导航至 Workers & Pages
- 选择你的 Worker
- Settings → Domains & Routes
- 添加自定义域名
DNS:域名必须托管在 Cloudflare 上(需要区域)
TypeScript 支持
为 Cloudflare 绑定生成类型:
npm run cf-typegen
此命令会创建 cloudflare-env.d.ts,其中包含绑定的类型:
// cloudflare-env.d.ts (auto-generated)
interface CloudflareEnv {
DB: D1Database;
BUCKET: R2Bucket;
KV: KVNamespace;
AI: Ai;
}
在路由处理程序中使用:
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as CloudflareEnv;
// Now env.DB, env.BUCKET, etc. are typed
}
测试
本地测试(开发环境)
# Next.js dev server (fast iteration)
npm run dev
本地测试(模拟生产环境)
# Workerd runtime (catches Workers-specific issues)
npm run preview
集成测试
部署前务必在 preview 模式下测试:
# Build and run in workerd
npm run preview
# Test bindings (D1, R2, KV, AI)
# Test middleware
# Test API routes
# Test SSR/ISR behavior
从其他平台迁移
从 Vercel 迁移
- 复制现有的 Next.js 项目
- 执行现有项目的迁移步骤(见上文)
- 在 Cloudflare 控制面板中更新环境变量
- 替换 Vercel 专属功能:
- Vercel Postgres → Cloudflare D1
- Vercel Blob → Cloudflare R2
- Vercel KV → Cloudflare KV
- Vercel Edge Config → Cloudflare KV
- 使用
npm run preview进行全面测试 - 使用
npm run deploy部署
从 AWS / 其他平台迁移
流程与从 Vercel 迁移相同——适配器会自动处理 Next.js 的标准功能。
资源
官方文档
- OpenNext Cloudflare:https://opennext.js.org/cloudflare
- Cloudflare Next.js 指南:https://developers.cloudflare.com/workers/framework-guides/web-apps/nextjs/
- Next.js 文档:https://nextjs.org/docs
故障排除
- 故障排除指南:https://opennext.js.org/cloudflare/troubleshooting
- 已知问题:https://opennext.js.org/cloudflare/known-issues
- GitHub 问题:https://github.com/opennextjs/opennextjs-cloudflare/issues
相关技能
cloudflare-worker-base- 使用 Hono + Vite + React 的基础 Worker 设置cloudflare-d1- D1 数据库集成cloudflare-r2- R2 对象存储cloudflare-kv- KV 键值存储cloudflare-workers-ai- Workers AI 集成cloudflare-vectorize- 用于 RAG 的向量数据库
快速参考
基本命令
# New project
npm create cloudflare@latest -- my-next-app --framework=next
# Development
npm run dev # Fast iteration (Next.js dev server)
npm run preview # Test in workerd (production-like)
# Deployment
npm run deploy # Build and deploy to Cloudflare
# TypeScript
npm run cf-typegen # Generate binding types
关键配置
// wrangler.jsonc
{
"compatibility_date": "2025-05-05", // Minimum!
"compatibility_flags": ["nodejs_compat"] // Required!
}
常见陷阱
- ❌ 使用 Edge 运行时 → ✅ 使用 Node.js 运行时
- ❌ 全局数据库客户端 → ✅ 限定在单个请求范围内的客户端
- ❌ 使用过时的 compatibility_date → ✅ 使用 2025-05-05+
- ❌ 缺少 nodejs_compat → ✅ 添加到 compatibility_flags
- ❌ 只在
dev中测试 → ✅ 部署前务必在preview中测试 - ❌ 使用 Turbopack → ✅ 使用标准 Next.js 构建
已通过生产环境测试:官方 Cloudflare 支持及活跃社区 节省 Token:相比手动设置约节省 59% 避免的错误:已记录 10+ 个问题 上次验证时间:2025-10-21