Prompt-to-PR:将 Next.js 14 迁移至 16
分步 SOP,用于将 Next.js 14 App Router 项目迁移至 Next.js 16 — 涵盖 Turbopack、React 19、异步 API 和缓存变更。
CursorClaude CodeCodexWindsurf Next.jsTypeScript
Next.js 16 搭载了 React 19,异步 params 和 searchParams,重构了 fetch 缓存机制,并将 Turbopack 设为默认开发打包工具。本手册将代理的注意力集中在破坏性变更上,并防止其重写可正常运行的代码。
1. 需求
将 next 从 14.x 升级到 16.x(并将 react/react-dom 升级到 19.x),确保零功能回归。处理官方 codemod 报告的所有破坏性变更以及其未捕获的残留问题。
2. 初始提示
Migrate this project from Next.js 14 to Next.js 16. Follow these steps exactly.
Step 1 — run the official codemod: npx @next/codemod@latest upgrade latest --yes
Step 2 — manual fixes the codemod does not cover: a. `params` and `searchParams` in page.tsx/layout.tsx files are now Promises. Await them: `const { id } = await params;` Do NOT destructure params in the function signature. b. `cookies()`, `headers()`, `draftMode()` are now async. Add `await` before every call. c. `fetch()` is no longer cached by default in Route Handlers. Where caching is intentional, add `{ next: { revalidate: N } }`. d. Remove any `export const dynamic = 'force-dynamic'` that is now the default. e. Replace `<Image>` with the new `onLoad` prop signature if present.
Step 3 — update package.json: "next": "^16.0.0" "react": "^19.0.0" "react-dom": "^19.0.0" "@types/react": "^19.0.0" "@types/react-dom": "^19.0.0"
Do not change any business logic, UI, or database code.List every file you changed and why.3. 预期文件变更
package.json (next, react, react-dom, @types/react*)src/app/**/page.tsx (await params / searchParams)src/app/**/layout.tsx (await params where used)src/app/api/**/route.ts (await cookies/headers; fetch cache opts)src/middleware.ts (if it uses deprecated config keys)next.config.ts (remove deprecated options)4. 审查清单
package.json将next锁定为^16.0.0,React 锁定为^19.0.0。- 每个解构了
params的页面/布局现在必须先 await 它。 - 服务器组件中不再存在同步的
cookies()或headers()调用。 - 之前依赖隐式缓存的
fetch调用现在具有明确的revalidate或no-store选项。 next.config.ts中没有已弃用的experimental.appDir或swcMinify键。- TypeScript 通过
bun tsc --noEmit编译,零错误。 - 代理没有重写任何 UI 组件或业务逻辑。
5. 测试命令
# Install updated depsbun install
# Type-checkbun tsc --noEmit
# Dev build (Turbopack default in Next.js 16)bun dev
# Production build — catches async-params errors at compile timebun run build
# Run existing test suitebun test6. 常见失败
params.id在 await 之前使用 — TypeScript 错误:Property 'id' does not exist on type 'Promise<...>'。代理有时在一个文件中 await 了params,但在另一个文件中没有。cookies()未 await — 运行时错误:cookies() was called outside of a Server Component。添加await。- Turbopack 不兼容的 webpack 插件 —
next dev在自定义webpack()配置上出错。Turbopack 忽略 webpack 插件;迁移或进行条件性门控。 @types/react版本冲突 — 旧组件库与 React 19 类型之间的 peer-dep 不匹配。将@types/react锁定到 19,必要时覆盖。useFormState已移除 — 被react的useActionState替代。codemod 通常能捕获到这一点,但请确认。
7. 修复提示
TypeScript reports: "Property 'slug' does not exist on type'Promise<{ slug: string }>'" in src/app/blog/[slug]/page.tsx.
The page function signature must be: export default async function Page({ params }: { params: Promise<{ slug: string }> })
Then at the top of the function body: const { slug } = await params;
Apply the same fix to every other page or layout that destructures paramswithout awaiting. List every file changed.8. PR 描述
## Chore: Migrate Next.js 14 → 16 + React 19
**Breaking changes addressed**:- `params` / `searchParams` are now `Promise`s — awaited in all pages/layouts- `cookies()` / `headers()` are now async — awaited in all Server Components- Fetch caching defaults changed — explicit `revalidate` added where needed- Removed deprecated `next.config.ts` keys (`swcMinify`, `experimental.appDir`)
**Tooling**: dev server now uses Turbopack by default (`next dev --turbopack`).
Run `bun run build` to confirm zero type errors before merging.