Next.js 部署到 Cloudflare Pages

25 年 10 月 4 日 星期六
981 字
5 分钟

最近部署在 Vercel 的项目被多个 AI 爬虫攻击后,超过了免费用量帐号直接被暂停了,等了几周也没有恢复,所以打算迁移到 Cloudflare Pages。此前听过说过 Vercel 的流量费用非常贵,但是没想到还有超量就暂停帐号的手段,除了升级订阅服务没有任何办法。总之,有相似问题的小伙伴可以参考这篇博客进行迁移。

前言

首先,要将原本运行在 VercelCloudflare Pages 的项目运行环境是不一样的。

部署方式运行时说明
VercelNode.js Runtime默认运行时,它具有访问所有 Node.js API 的权限,并用于渲染您的应用。
Cloudflare PagesEdge Runtime只包含有限 API 的中间件运行时,不支持所有 Node.js API,不支持增量静态再生 (ISR)。

因为 Cloudflare Pages 使用的是 Edge Runtime,所以一些有关 Node.js 的依赖库不会正常工作,例如 path、fs 等文件读写这些。如果项目中有用了 Edge Runtime 不支持的数据操作,那最好改成 fetch 去获取数据。

安装构建依赖

Cloudflare Pages 提供了一个 @cloudflare/next-on-pages 依赖库,可以把 Next.js 项目编译为 Pages 兼容的编译文件。

bash
npm install -D @cloudflare/next-on-pages

yarn add -D @cloudflare/next-on-pages

pnpm install -D @cloudflare/next-on-pages

然后,我们需要在 package.json 中补充三条 script

json
"scripts": {
  "pages:build": "npx @cloudflare/next-on-pages",
  "preview": "npm run pages:build && wrangler pages dev",
  "deploy": "npm run pages:build && wrangler pages deploy"
}

添加配置支持

同时,我们还需要在 next.config.ts 中额外添加配置,用于构建时初始化 @cloudflare/next-on-pages

typescript
import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev'

// Export an async default function that returns the NextConfig.
// Next supports the config being a Promise, so we can run async
// setup here without using top-level await or an IIFE.
export default async function (): Promise<NextConfig> {
  if (process.env.NODE_ENV === 'development') {
    await setupDevPlatform()
  }

  return nextConfig
}

Nodejs 兼容标识和指定构建路径

除此之外,还需要在项目的根目录中添加一个 wrangler.toml 文件,用于指定构建后的路径和配置。

toml
name = "PROJECT_NAME"
compatibility_date = "2025-10-04"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = ".vercel/output/static"

这里可以直接复制配置,然后更改 name 为项目名字和 compatibility_date 为最新日期就好了。

运行时声明

为了让 Next.js 运行在 Edge Runtime,需要在所有的服务端界面("use server")和 API 的顶层进行显式的 runtime 声明。大部分情况下,只需要在 app/layout.tsxapp/api/*.ts 文件的顶部添加一行声明就好了。

tsx
export const runtime = 'edge'

添加 NotFound 界面

通过 @cloudflare/next-on-pages 依赖构建后会在文件中默认生成一个 _not-found 界面,但是这个界面也是运行在服务端的,如果在项目中没有声明 runtime,那么就会在部署时报错。

所以,我们需要在项目中添加 app/not-found.tsx 文件

tsx
import { Button } from '@/components/ui/button'
import Link from 'next/link'

export const runtime = 'edge'

export default function NotFound() {
  return (
    <div className="flex min-h-70 flex-col items-center justify-center">
      <h1 className="mt-4 text-4xl font-bold tracking-tight text-zinc-800 sm:text-5xl dark:text-zinc-100">
        Page not found
      </h1>
      <p className="mt-4 text-base text-zinc-600 dark:text-zinc-400">
        Sorry, we couldn’t find the page you’re looking for.
      </p>
      <Link href="/" className="mt-4 cursor-pointer">
        <Button variant="secondary" className="cursor-pointer">
          Go back home
        </Button>
      </Link>
    </div>
  )
}

部署到 Cloudflare Pages

然后,我们在 Cloudflare Pages 导入现有 Git 存储库

Cloudflare Page部署

然后选择要部署的 Github 存储库

Cloudflare Page选择存储库

选择框架预设为 Next.js,默认配置保持不变,然后点击保存并部署

Cloudflare Page 构建设置

如果有缺少的界面没有配置 runtime,在部署的日志都会显示出来,我们只需要根据错误再次调整就好了

Cloudflare Pages构建问题

部署成功后就是下面的显示的日志输出,我们就可以访问网站了

Cloudflare Page部署成功

结语

至此,我们就完成了部署,不过这种方法只适合现有的 Next.js 项目进行迁移。现在 Cloudflare 的 @cloudflare/next-on-pages 依赖仓库已经被归档了,官方更推荐使用 Open Next 通过 CLI 的方式进行构建和部署。

文章标题:Next.js 部署到 Cloudflare Pages

文章作者:rowink

文章链接:https://exi.ink/posts/nextjs%E9%83%A8%E7%BD%B2%E5%88%B0cloudflare-pages

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。