升级与迁移
本教程共 42 篇 · 第 37 篇 · 更新于 2026-07-30 · 约 8 分钟阅读
37. 升级与迁移
本节目标:了解从 Next.js 15 升级到 16 的重大变更,学会使用 Codemod 自动迁移和手动处理破坏性变更。
升级方法
自动升级
Next.js 16 新增了 upgrade 命令:
npx next upgrade
旧版本(16.1.0 之前)需要用 Codemod:
npx @next/codemod@canary upgrade latest
手动升级
直接安装最新版本:
npm install next@latest react@latest react-dom@latest eslint-config-next@latest
如果用 TypeScript,别忘了升级类型包:
npm install -D @types/react@latest @types/react-dom@latest
Next.js 16 重大变更
1. Turbopack 成为默认
Next.js 16 中 next dev 和 next build 默认使用 Turbopack。如果你的项目有自定义 webpack 配置,构建会失败。
解决方案:
- 迁移到 Turbopack 配置
- 或者用
--webpack标志回退:
{
"scripts": {
"build": "next build --webpack"
}
}
2. 异步请求 API(破坏性变更)
Next.js 16 完全移除了同步访问方式,以下 API 必须异步调用:
cookies()headers()draftMode()params(在 layout、page、route 等)searchParams(在 page 中)
// Next.js 15(旧写法)
export default function Page({ params }) {
const { slug } = params // 同步访问
}
// Next.js 16(新写法)
export default async function Page({ params }) {
const { slug } = await params // 必须 await
}
可以用 npx next typegen 自动生成类型辅助:
export default async function Page(props: PageProps<'/blog/[slug]'>) {
const { slug } = await props.params
const query = await props.searchParams
return <h1>{slug}</h1>
}
3. middleware 改名为 proxy
middleware.ts 文件已弃用,改名为 proxy.ts:
mv middleware.ts proxy.ts
函数名也要改:
// 旧写法
export function middleware(request) {}
// 新写法
export function proxy(request) {}
注意:Next.js 16 中 Proxy 默认使用 Node.js 运行时,且不支持设置
runtime = 'edge'(会抛出错误)。middleware.ts虽然已弃用但仍可使用(会显示弃用警告),如果项目强依赖 Edge Runtime,可以暂时保留middleware.ts,但建议尽快迁移到 Proxy 并使用 Node.js 运行时。
4. 图片相关变更
minimumCacheTTL 默认值:从 60 秒改为 4 小时(14400 秒)。如果需要旧行为:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
images: {
minimumCacheTTL: 60,
},
}
export default nextConfig
imageSizes 默认值:移除了 16px。如果需要:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}
export default nextConfig
qualities 默认值:从允许所有质量改为只允许 [75]。
本地 IP 限制:默认阻止本地 IP 优化,私有网络需要手动开启:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
images: {
dangerouslyAllowLocalIP: true,
},
}
export default nextConfig
最大重定向次数:从无限制改为最多 3 次。
5. 移除的功能
| 移除项 | 替代方案 |
|---|---|
| AMP 支持 | 不再需要,现代 Web 标准已覆盖 |
next lint 命令 | 用 ESLint CLI 或 Biome |
serverRuntimeConfig / publicRuntimeConfig | 用环境变量 |
images.domains | 用 images.remotePatterns |
next/legacy/image | 用 next/image |
experimental.dynamicIO / experimental.useCache | 用 cacheComponents |
6. 并行路由 default.js 要求
所有并行路由槽位必须有 default.js 文件,否则构建失败:
// app/@modal/default.tsx
import { notFound } from 'next/navigation'
export default function Default() {
notFound()
}
或者返回 null。
Codemod 自动迁移
Next.js 提供了 Codemod 来自动处理大部分迁移工作:
npx @next/codemod@canary upgrade latest
它能自动完成:
- 更新
next.config.ts中的turbopack配置 - 从
next lint迁移到 ESLint CLI - 从
middleware迁移到proxy - 移除
unstable_前缀 - 移除
experimental_ppr配置
缓存 API 变更
revalidateTag 需要第二个参数
// 旧写法
revalidateTag('posts')
// 新写法
revalidateTag('posts', 'max')
updateTag 新 API
updateTag 提供”读你所写”语义,用户操作后立即看到变化:
'use server'
import { updateTag } from 'next/cache'
export async function updateProfile(userId, profile) {
await db.users.update(userId, profile)
updateTag(`user-${userId}`) // 立即刷新缓存
}
cacheLife 和 cacheTag 稳定
不再需要 unstable_ 前缀:
import { cacheLife, cacheTag } from 'next/cache'
升级检查清单
升级前按这个清单检查:
- Node.js 版本:确保 ≥ 20.9.0
- TypeScript 版本:确保 ≥ 5.1.0
- 自定义 webpack 配置:准备迁移到 Turbopack
- middleware:改名为 proxy
- params/searchParams:改为异步访问
- 图片配置:检查是否需要调整默认值
- 移除的 API:替换 AMP、next lint 等
- 测试:升级后跑一遍完整测试
迁移建议
- 先升级到最新的 15.x:确保当前版本稳定
- 运行 Codemod:自动处理大部分变更
- 手动处理剩余:Codemod 处理不了的,按文档手动改
- 本地测试:
npm run build和npm run start验证 - 灰度发布:生产环境先小流量验证
升级是个持续的过程。Next.js 团队会定期发布新版本,保持关注官方博客和 Release Notes,能帮你提前做好准备。