团队5 分钟阅读
Next.js 16 vs 15: 完整升级指南
Next.js 16 是框架最重要的更新之一,Turbopack 成为默认打包器,并引入了革命性的缓存策略。本指南涵盖了从 Next.js 15 升级到 16 所需了解的所有内容。
快速开始
使用自动迁移工具升级到 Next.js 16:
# 使用 codemod 自动升级
npx @next/codemod@canary upgrade latest
# 手动升级
npm install next@latest react@latest react-dom@latest
# TypeScript 用户
npm install @types/react@latest @types/react-dom@latest
性能亮点
- 生产构建速度提升 2-5 倍 - 得益于 Turbopack
- 开发时 Fast Refresh 速度提升高达 10 倍
- 共享布局的网络传输减少 50%
- Cache Components 和 PPR 实现即时导航
主要变更概览
| 功能 | Next.js 15 | Next.js 16 |
|---|---|---|
| 默认打包器 | Webpack(Turbopack 可选) | Turbopack(无需配置) |
| 构建速度 | 标准 | 快 2-5 倍 |
| Fast Refresh | 标准 | 快高达 10 倍 |
| 缓存 | 隐式、基于时间 | 显式、基于 "use cache" 的事件驱动 |
| 中间件文件 | middleware.ts | proxy.ts |
| 请求 API | 同步 | 异步/Promise |
| React Compiler | 实验性 | 稳定版 |
| Node.js 最低版本 | 18.x | 20.9+ |
| React 版本 | 19.x | 19.2+ |
Turbopack 成为默认
这是影响最大的变更。在 Next.js 15 中,Turbopack 是可选的,需要显式配置。现在它是默认打包器,无需任何标志。
之前(Next.js 15)
{
"scripts": {
"dev": "next dev --turbopack",
"build": "next build --turbopack"
}
}
之后(Next.js 16)
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
Turbopack 配置
experimental.turbopack 配置现在是顶级选项:
import type { NextConfig } from 'next'
// Next.js 15 - experimental.turbopack
const nextConfig: NextConfig = {
experimental: {
turbopack: {
// 选项
},
},
}
// Next.js 16 - 顶级 turbopack
const nextConfig: NextConfig = {
turbopack: {
// 选项
},
}
export default nextConfig
退出 Turbopack
如果需要继续使用 Webpack:
{
"scripts": {
"dev": "next dev",
"build": "next build --webpack",
"start": "next start"
}
}
破坏性变更
1. 异步请求 API(影响约 95% 的应用)
这是最大的破坏性变更。在 Next.js 15 中,params、searchParams、cookies()、headers() 和 draftMode() 直接返回值。在 Next.js 16 中,它们返回 Promise。
之前(Next.js 15)
export default function Page({ params, searchParams }) {
const slug = params.slug
const query = searchParams.q
const cookieStore = cookies()
return <div>{slug} - {query}</div>
}
之后(Next.js 16)
export default async function Page({ params, searchParams }) {
const { slug } = await params
const { q } = await searchParams
const cookieStore = await cookies()
return <div>{slug} - {q}</div>
}
使用 codemod 进行迁移:
npx @next/codemod@canary upgrade latest
2. 需要 Node.js 20.9+
Next.js 16 需要 Node.js 20.9 或更高版本。不再支持 Node.js 18。
# 检查 Node 版本
node --version
3. 中间件重命名为代理
middleware.ts 文件现在是 proxy.ts:
# 重命名中间件文件
mv middleware.ts proxy.ts
// 之前(Next.js 15)
export function middleware(request: Request) {}
// 之后(Next.js 16)
export function proxy(request: Request) {}
配置标志也已重命名:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
// 之前: skipMiddlewareUrlNormalize
skipProxyUrlNormalize: true,
}
export default nextConfig
4. Image 组件变更
多个默认值已更改:
minimumCacheTTL默认值从 60 秒改为 4 小时(14400 秒)- 默认
imageSizes数组中移除了16 qualities默认值改为仅[75]- 默认阻止本地 IP 优化
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
images: {
// 如需恢复之前的行为
minimumCacheTTL: 60,
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
qualities: [50, 75, 100],
dangerouslyAllowLocalIP: true, // 仅用于私有网络
},
}
export default nextConfig
新功能
使用 "use cache" 的 Cache Components
Next.js 16 引入了 "use cache" 指令实现显式缓存:
// next.config.ts
const nextConfig = {
cacheComponents: true,
}
export default nextConfig
'use cache'
async function MyComponent() {
const data = await fetch('/api/users')
return <div>{data}</div>
}
新的缓存 API
'use server'
import { revalidateTag, updateTag } from 'next/cache'
// revalidateTag - 适用于可接受轻微延迟的内容
export async function updateArticle(articleId: string) {
revalidateTag(`article-${articleId}`, 'max')
}
// updateTag - 适用于即时更新(read-your-writes)
export async function updateUserProfile(userId: string, profile: Profile) {
await db.users.update(userId, profile)
updateTag(`user-${userId}`)
}
React 19.2 集成
Next.js 16 搭载 React 19.2,包括:
- View Transitions:导航期间的元素动画
- useEffectEvent:从 Effect 中提取非响应式逻辑
- Activity:使用
display: none渲染后台 UI 同时保持状态
React Compiler(稳定版)
React Compiler 现已稳定,自动对组件进行记忆化:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
reactCompiler: true,
}
export default nextConfig
npm install -D babel-plugin-react-compiler
增强的路由和导航
- 布局去重:共享布局只下载一次
- 增量预取:只预取缓存中没有的部分
并行路由要求
所有并行路由插槽现在需要显式的 default.js 文件:
// app/@modal/default.tsx
import { notFound } from 'next/navigation'
export default function Default() {
notFound()
}
// 或返回 null
export default function Default() {
return null
}
移除的功能
- AMP 支持:所有 AMP API 和配置已移除
- next lint 命令:直接使用 ESLint
- 运行时配置:
serverRuntimeConfig和publicRuntimeConfig已移除 - next/legacy/image:使用
next/image - images.domains:使用
images.remotePatterns
运行时配置迁移
之前(Next.js 15)
// next.config.js
module.exports = {
serverRuntimeConfig: {
dbUrl: process.env.DATABASE_URL,
},
publicRuntimeConfig: {
apiUrl: '/api',
},
}
之后(Next.js 16)
// 服务器端专用值
async function fetchData() {
const dbUrl = process.env.DATABASE_URL
return await db.query(dbUrl, 'SELECT * FROM users')
}
// 客户端可访问的值使用 NEXT_PUBLIC_ 前缀
// .env.local
// NEXT_PUBLIC_API_URL="/api"
'use client'
export default function ClientComponent() {
const apiUrl = process.env.NEXT_PUBLIC_API_URL
return <p>API URL: {apiUrl}</p>
}
迁移清单
- ✅ 为升级创建新分支
- ✅ 将 Node.js 更新到 20.9+
- ✅ 运行 codemod:
npx @next/codemod@canary upgrade latest - ✅ 更新所有异步 API 用法(params、searchParams、cookies、headers)
- ✅ 将
middleware.ts重命名为proxy.ts - ✅ 将 Turbopack 配置更新到顶级
- ✅ 为并行路由添加
default.js文件 - ✅ 检查并更新图片配置
- ✅ 移除已弃用的功能(AMP、运行时配置)
- ✅ 在部署到生产环境之前在预发布环境充分测试
总结
Next.js 16 带来了显著的性能改进和更明确的缓存方法。虽然有需要注意的破坏性变更,但自动化的 codemod 处理了大部分迁移工作。仅 Turbopack 一项就使大多数项目值得升级。
""预测未来的最好方法就是创造它。" - 彼得·德鲁克
今天就开始迁移,享受更快的构建、更好的开发体验,以及对应用程序缓存行为的更多控制!