
成为全栈·Next.js 网站前台篇·OpenNext 部署 Cloudflare构建成功不等于缓存正确next build成功只证明 Next.js 能生成生产产物OpenNext 打包成功只证明 Worker 产物形成。域名、Cookie、R2 增量缓存和重新验证仍要在目标环境逐项验收。前言App Router 的输出不是一包普通静态文件。公开页面包含服务端执行、RSC 响应、流式渲染和增量缓存会员功能还依赖同源代理与 Cookie。因此部署到 Cloudflare 不能只上传.next/static。项目使用 OpenNext 将 Next.js 产物适配为 Worker并用 R2 保存增量缓存。适配器解决运行形式不能替我们证明生产行为。部署链路包含四层Next.js 源码 → next build → OpenNext Cloudflare 打包 → Worker 静态 Assets R2 增量缓存 → 域名、Cookie、后端 API 与真实流量层次成功意味着尚未证明Next build路由与生产产物可生成Worker 可运行OpenNext buildWorker 适配打包完成远程资源已配置wrangler local本地 workerd 可运行真实 R2 与 CDN 行为远程部署资源可访问缓存、Cookie、性能均正确OpenNext 配置增量缓存import{defineCloudflareConfig}fromopennextjs/cloudflareimportr2IncrementalCachefromopennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cacheexportdefaultdefineCloudflareConfig({incrementalCache:r2IncrementalCache,queue:direct,})R2 为公开页面和数据的增量缓存提供跨请求存储。queue: direct影响重新验证任务执行方式但不会改变文章定义的 60 秒业务窗口。Wrangler 绑定必须与代码约定一致{name:web-frontend-codex,main:.open-next/worker.js,compatibility_flags:[nodejs_compat],assets:{directory:.open-next/assets,binding:ASSETS},r2_buckets:[{binding:NEXT_INC_CACHE_R2_BUCKET,bucket_name:web-frontend-codex-cache}]}binding 名称、桶名和环境要对应。预览、正式环境最好使用独立 Worker 与 R2避免测试重新验证污染生产缓存。本地模拟 R2 不等于远程 R2pnpmbuild:cfpnpmexecwrangler dev--local本地模式使用模拟桶不会创建远程资源。它可以证明 Worker 产物在 workerd 中启动、路由和代理能运行却不能证明多节点传播、远程 R2 权限、配额与延迟。项目本地测试观察到公开设置过期后能更新也记录过一次后台重新验证连接中断后续请求恢复。正确表述是“本地链路有成功证据并保留过异常记录”不是“生产缓存已完全可靠”。环境变量分服务端与公开构建值API_ORIGINhttps://api.example.com NEXT_PUBLIC_SITE_URLhttps://www.example.com NEXT_PUBLIC_API_BASE_URL/api/v1API_ORIGIN只在服务端 Worker 中使用NEXT_PUBLIC_SITE_URL参与 canonical、sitemap 和分享地址通常在构建时确定浏览器 API 地址保持同源/api/v1。用本地域名构建后再直接上传会把 localhost 写进公开元数据。生产部署必须使用正式变量重新构建而不是只在 Worker 运行时补一项 secret。Cookie 必须在真实域名和 HTTPS 下复核登录 → Set-Cookie(codex_refresh; HttpOnly; Secure; SameSiteLax) 刷新页面 → /auth/refresh 自动携带 Cookie 退出 → 清除同名、同 Path Cookie本地回环主机允许去掉 Secure生产域名必须保留。还要检查反向代理后的 Host/Origin 比较、Cookie Domain 与 Path以及新旧前台是否共享主机。本地端口隔离不了 Cookie因为 Cookie 不按端口区分项目采用独立codex_refresh名称正是为了避免同主机旧前台冲突。HTML、RSC 与缓存版本要一致App Router 客户端导航会请求 RSC Payload。若 CDN 分别以错误规则缓存 HTML 与 RSC首次打开可能看到版本 A站内导航却合并版本 B。因此不要在 OpenNext 外再套一层“缓存所有 GET”的粗暴规则。平台缓存必须理解 Next.js 生成的响应头与变体重新验证也要覆盖对应条目。生产缓存验收脚本curl-sShttps://www.example.com/-o/tmp/home-a.htmlcurl-sShttps://www.example.com/sitemap.xml-o/tmp/sitemap.xmlcurl-ihttps://www.example.com/api/v1/me/profile1. 发布唯一标题 A访问首页与详情 2. 后台改成 B在 TTL 内观察可接受旧值 3. 过期后触发再验证再次访问确认 B 4. 从站内 Link 导航确认 RSC 与直接打开一致 5. 两个账号检查私有响应始终 no-store 且不串用户 6. 登录、刷新恢复、退出检查 Cookie 完整生命周期 7. 停止上游确认代理 502 与旧公开内容策略 8. 检查 Worker 日志、R2 写入和错误率远程部署前的资源清单项目上线前动作Worker创建独立服务与环境R2创建正式增量缓存桶并绑定域名配置正式域名、HTTPS 与路由后端设置生产 API_ORIGIN 与网络访问站点 URL用正式 NEXT_PUBLIC_SITE_URL 重建Cookie验证 Secure、SameSite、Path、清除行为回退保留上一版本和域名切回方案构建与部署命令要分开理解pnpmbuild:cf# 生成 Worker 产物pnpmdeploy:cf# 构建并执行远程发布本项目只完成了本地构建与 Worker 验收没有执行远程资源创建、域名切换和线上发布。部署命令存在不等于部署已经发生。适用边界OpenNext 与 Cloudflare 的兼容能力会随版本变化。升级 Next.js、OpenNext 或 Wrangler 时应重新阅读对应版本文档并重跑构建、代理、Cookie 和缓存用例。需要强一致发布、全球低延迟或大规模个性化时当前 60 秒 ISR 与 R2 方案还需结合业务重新设计。小结Cloudflare 部署不是构建命令的最后一行而是一条从 Next 产物到 Worker、Assets、R2、域名、Cookie 和后端的完整链路。构建成功值得记录但缓存正确、登录可恢复和公开 URL 无误只能由目标环境的行为证据证明。延伸阅读数据获取与缓存如果这篇文章对你有帮助欢迎订阅我的 CSDN 专栏「成为全栈」 专栏地址https://blog.csdn.net/fungleo/category_13204651.html 本系列配套代码仓库https://github.com/fengcms/become-a-full-stack-developer