Chapter 08

Pages + Full-stack 框架

Pages 起初是"托管静态站",现在和 Workers 合为一体——可以部署 Next.js / SvelteKit / Remix / Astro 任何主流框架的全栈版本,一套 Bindings 直接用。

两种部署形态

Pages(Dashboard Git 集成)
连 GitHub/GitLab,push 自动构建部署。每个 PR 有 Preview 环境。
Workers + Static Assets
2024 新模式:Worker 本身可以托管静态资源,wrangler deploy 一步到位。这是两者合并后的统一路径。

2026 起 Cloudflare 推荐走 Workers + Static Assets——但大量现存项目还在 Pages 上,两种都要懂。

Next.js on Cloudflare

官方推荐 @opennextjs/cloudflare,把 Next.js 构建产物适配到 Workers。

npm create cloudflare@latest my-app -- --framework=next
cd my-app
npm run preview   # 本地用 wrangler 跑,看到 Workers 实际行为
npm run deploy
# wrangler.jsonc 示例
{
  "name": "my-next-app",
  "main": ".open-next/worker.js",
  "compatibility_date": "2026-05-01",
  "compatibility_flags": ["nodejs_compat"],
  "assets": { "directory": ".open-next/assets", "binding": "ASSETS" },
  "d1_databases": [{ "binding": "DB", "database_name": "prod", "database_id": "..." }],
  "r2_buckets": [{ "binding": "ASSETS_BUCKET", "bucket_name": "..." }]
}
// app/api/users/route.ts — Next.js Route Handler 里直接用 bindings
import { getRequestContext } from '@opennextjs/cloudflare';

export async function GET() {
  const { env } = getRequestContext();
  const { results } = await env.DB.prepare('SELECT * FROM users LIMIT 10').all();
  return Response.json(results);
}

SvelteKit on Cloudflare

// svelte.config.js
import adapter from '@sveltejs/adapter-cloudflare';

export default {
  kit: { adapter: adapter() },
};
// src/routes/api/users/+server.ts
export async function GET({ platform }) {
  const r = await platform.env.DB.prepare('SELECT * FROM users').all();
  return new Response(JSON.stringify(r.results));
}

Remix / Astro

官方 @remix-run/cloudflare@astrojs/cloudflare adapter,流程一致:

  1. npm create cloudflare -- --framework=remixastro
  2. 本地 npm run dev(Vite 模式)或 npm run preview(wrangler 模式)
  3. npm run deploy → 几十秒后全球上线

Functions(老 Pages 模式)

老 Pages 项目里 functions/ 目录,文件系统路由:

functions/
├── api/
│   ├── users/
│   │   └── [id].ts          ← GET /api/users/42
│   └── index.ts             ← GET /api/
└── _middleware.ts           ← 所有路由前置中间件
// functions/api/users/[id].ts
interface Env { DB: D1Database }

export const onRequestGet: PagesFunction<Env> = async (ctx) => {
  const id = ctx.params.id;
  const r = await ctx.env.DB.prepare('SELECT * FROM users WHERE id=?').bind(id).first();
  return r ? Response.json(r) : new Response('404', { status: 404 });
};

Preview 环境

每次 PR 自动部署一个独立 URL <pr-id>.my-app.pages.dev,和生产完全隔离但共享 Bindings 配置。设计/产品 review 直接点链接看效果。

Preview 用独立 D1?
Pages 的 Preview 环境可以绑不同的 D1 / R2 / KV——wrangler.toml 配两套即可。这样 PR 随便改数据不影响生产。

自定义域名与 SSL

  1. Pages Dashboard → Custom Domains → 添加 www.example.com
  2. 域名需要在 Cloudflare 托管,DNS 自动配置
  3. SSL 证书自动签发,强制 HTTPS

构建配置

框架Build commandOutput directory
Next.jsnpx opennextjs-cloudflare build.open-next/worker.js
SvelteKitnpm run build.svelte-kit/cloudflare
Remixnpm run buildbuild/client
Astronpm run builddist
Vite SPAnpm run builddist

从 Vercel / Netlify 迁移

Edge Runtime 已兼容
Vercel Edge Functions / Middleware 基于 Web 标准,大部分代码能直接跑在 Workers。Node-only API(fspath)要换成 nodejs_compat 或重写。
ISR 替代
Next.js ISR 用 Cache API + KV 实现(@opennextjs/cloudflare 已内置)。
Image Optimization
Cloudflare Images 服务或 Image Resizing,替代 Next/image loader。

陷阱与诊断

本章小结