Back to all posts
Tutorial

终极指南:使用 OpenNext 将 Next.js 15 从 Cloudflare Pages 迁移到 Workers

如果你一直在构建 Next.js 15 应用程序,并尝试使用 @cloudflare/next-on-pages 将它们部署到 Cloudflare Pages,那么你很可能已经碰壁了。

令人头疼的 "Invalid prerender config" 错误、静态与动态路由渲染的不一致,以及 Edge 运行时配置的冲突,一直是社区的重大痛点。在我的个人博客网站上为了调试这些确切的问题耗费了数小时之后,我终于找到了一个无懈可击的解决方案:使用 OpenNext 从 Cloudflare Pages 迁移到 Cloudflare Workers。

在本指南中,我将向你展示为什么 Next.js 在 Pages 上会失败,以及如何将你的架构干净利落地迁移到 Cloudflare Workers,实现完美且健壮的部署。


痛点:Next-on-Pages 的局限性

Cloudflare Pages 最初是为纯静态网站设计的。虽然它已经演变为支持服务器端渲染 (SSR) 和 Edge Functions(通过 @cloudflare/next-on-pages),但它与 Next.js 15 的 App Router 的集成仍然很脆弱。

当你在项目中混合使用静态 SSG 路由(如博客文章)和动态 edge 路由(如 API 端点或数据库查询)时,构建过程通常会崩溃:

Error: Invalid prerender config for /app/[locale]/about
The following routes were not configured to run with the Edge Runtime...

根本原因在于 Vercel 的构建输出所期望的函数结构与 next-on-pages 在 Pages 环境下解析它们的方式之间存在不匹配。


解决方案:OpenNext 和 Cloudflare Workers

现代的方法是停止与 Pages 的构建系统作斗争,转而使用 OpenNext (@opennextjs/cloudflare) 并直接部署到 Cloudflare Workers。

Workers 提供了一个真正的 Serverless 执行环境,它与 Next.js 的 SSR 和 API 路由要求完美契合,而静态文件则由 Cloudflare Assets 处理。

这是逐步的迁移路径。


第一步:安装依赖

移除 next-on-pages 并安装针对 Cloudflare 的 OpenNext:

npm uninstall @cloudflare/next-on-pages
npm install -D @opennextjs/cloudflare

第二步:配置 OpenNext

在项目根目录下创建一个 open-next.config.ts 文件。这会告诉 OpenNext 如何为了 Cloudflare 调整你的 Next.js 构建:

import type { OpenNextConfig } from 'open-next/types/open-next.js';

export default {
  default: {
    override: {
      wrapper: 'cloudflare-node',
      converter: 'edge',
      incrementalCache: 'dummy',
      tagCache: 'dummy',
      queue: 'dummy',
    },
  },
  middleware: {
    external: true,
    override: {
      wrapper: 'cloudflare-edge',
      converter: 'edge',
      proxyExternalRequest: 'fetch',
    },
  },
} as OpenNextConfig;

第三步:为 Workers 设置 Wrangler

你需要一个 wrangler.jsonc(或 wrangler.toml)来定义你的 Worker 部署。请注意我们将主入口指向了生成的 OpenNext worker,并绑定了静态资产。

{
  "main": ".open-next/worker.js",
  "name": "your-project-name",
  "compatibility_date": "2026-06-15",
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "assets": {
    "directory": ".open-next/assets",
    "binding": "ASSETS"
  }
}

第四步:更新构建脚本

更新你的 package.json,首先使用 Next.js 构建,然后使用 OpenNext 处理:

"scripts": {
  "build": "next build && opennextjs-cloudflare",
  "preview": "npm run build && wrangler dev",
  "deploy": "npm run build && wrangler deploy"
}

第五步:清理 Edge 配置

有了 OpenNext 之后,你不再需要为了迎合构建系统而在每个动态文件的顶部严格强制使用 export const runtime = 'edge'。OpenNext 的 cloudflare-node 包装器智能地处理了 Node.js API 和 Edge API,极大地简化了你的代码库。


那 Cloudflare R2 呢?

在迁移过程中,你可能会想是否需要配置一个 Cloudflare R2 存储桶。

简单的回答是:不,目前不需要。 你的 Next.js 静态资产(图片、CSS、JS 文件)由在 wrangler.jsonc 中定义的 Cloudflare Assets 绑定完美地提供服务。

然而,如果你的应用程序扩展到需要处理用户上传的媒体、大型视频或海量数据集,R2 可以无缝集成到这种 Worker 架构中。你只需在 wrangler.jsonc 中绑定 R2 存储桶,并通过服务器操作(Server Actions)或 API 路由中的 env.MY_BUCKET 访问它。

最终成果

通过使用 OpenNext 迁移到 Cloudflare Workers,你实现了:

  • 零构建错误:不再为预渲染配置而抓狂。
  • 完美的本地化:国际化路由 (/[locale]/) 开箱即用。
  • Node.js 兼容性:nodejs_compat 标志允许支持更广泛的 npm 包。

Cloudflare Pages 对于简单的静态网站来说非常棒,但对于雄心勃勃的 Next.js 15 应用程序,基于 Cloudflare Workers 的 OpenNext 才是明确的前进方向。