作为React生态中最强大的全栈框架,Next.js的每一次更新都牵动着无数开发者的心。Next.js 16带来了自App Router推出以来最重大的一次版本迭代:Turbopack正式取代Webpack成为默认构建工具,整个路由和导航系统得到全面优化,React Compiler也终于稳定可用。
本文将基于官方文档,系统性地解析Next.js 16的所有重要变化。无论你是正在考虑升级的老用户,还是准备深入学习Next.js的新人,这篇文章都将帮助你全面理解新版本的特性和升级策略。
升级准备工作
环境要求变化
Next.js 16对运行环境提出了更高的要求:
| 要求 | 变化详情 |
|---|---|
| Node.js | 最低版本20.9.0(必须为LTS),Node.js 18不再支持 |
| TypeScript | 最低版本5.1.0 |
| 浏览器 | Chrome 111+、Edge 111+、Firefox 111+、Safari 16.4+ |
一键升级
Next.js官方提供了强大的Codemod工具,可以自动完成大部分迁移工作:
# pnpm |
Codemod能够自动完成以下工作:
- 更新next.config.js使用新的turbopack配置
- 从next lint迁移到ESLint CLI
- 将废弃的middleware convention迁移到proxy
- 移除stable APIs的unstable_前缀
- 移除pages和layouts中的experimental_ppr配置
AI辅助升级
如果你使用支持MCP(Model Context Protocol)的AI编码助手,还可以使用Next.js DevTools MCP来自动化升级过程:
{ |
配置完成后,只需告诉AI助手”帮助我升级到Next.js 16”即可自动完成升级。
手动升级
如果 prefer 手动升级,需要安装最新版本:
# pnpm |
注意:如果使用TypeScript,记得同时升级
@types/react和@types/react-dom。
Turbopack默认启用
重大变化
Next.js 16最重要的变化之一是Turbopack正式稳定,并在next dev和next build中默认使用。在此之前,你需要通过--turbopack或--turbo标志手动启用。
{ |
不再需要添加--turbopack标志。
解决Webpack配置冲突
如果你的项目有自定义Webpack配置,运行next build(现在默认使用Turbopack)将会失败,以防止配置错误带来的问题。
有以下几种解决方案:
- 继续使用Turbopack:运行
next build --turbopack,忽略你的webpack配置 - 完全迁移到Turbopack:将webpack配置迁移为Turbopack兼容选项
- 继续使用Webpack:使用
--webpack标志来退出Turbopack
{ |
Turbopack配置位置变化
experimental.turbopack配置已经移出experimental,现在是顶层配置项:
import type { NextConfig } from 'next' |
Turbopack文件系统缓存(Beta)
Turbopack现在支持开发模式下的文件系统缓存,可以在重启之间存储编译产物,显著加快编译速度:
import type { NextConfig } from 'next' |
Sass导入语法变化
Turbopack完全支持从node_modules导入Sass文件。但需要注意,Webpack允许的波浪号(~)前缀语法不再支持:
// Webpack写法(不再支持) |
异步Request APIs:完全异步化
重要变化
Next.js 15引入了异步Request APIs作为重大变化,并提供了临时的同步兼容性。从Next.js 16开始,同步访问已完全移除,这些API只能异步访问。
需要异步访问的API包括:
cookiesheadersdraftModelayout.js、page.js、route.js等文件中的paramspage.js中的searchParams
// Next.js 15(过渡期兼容) |
建议使用codemod来自动迁移到异步API。
类型迁移助手
为了帮助迁移异步params和searchParams,可以运行npx next typegen自动生成全局可用的类型助手:
PageProps:页面组件属性LayoutProps:布局组件属性RouteContext:路由上下文
export default async function Page(props: PageProps<'/blog/[slug]'>) { |
icon和opengraph-image的异步参数
传递到opengraph-image、twitter-image、icon和apple-icon中的props现在都是Promise:
export async function generateImageMetadata({ params }) { |
sitemap的异步id参数
export async function generateSitemaps() { |
React 19.2与React Compiler
React 19.2新特性
Next.js 16使用最新的React Canary版本,包含React 19.2的新特性:
- View Transitions:在Transition或导航中更新元素时添加动画
- useEffectEvent:将非响应式逻辑从Effect提取到可重用的Effect Event函数中
- Activity:通过
display: none隐藏UI同时保持状态和清理Effect来渲染”后台活动”
React Compiler稳定支持
React Compiler的内置支持在Next.js 16中正式稳定。React Compiler可以自动memoize组件,减少不必要的重渲染,无需手动修改代码。
reactCompiler配置项已从experimental升级为稳定版:
import type { NextConfig } from 'next' |
安装最新版本的React Compiler插件:
npm install -D babel-plugin-react-compiler |
注意:启用此选项后,开发和构建时的编译时间可能会更长,因为React Compiler依赖Babel。
缓存API更新
revalidateTag新增签名
revalidateTag有新函数签名,可以传递cacheLife配置文件作为第二个参数:
'use server' |
updateTag:立即读取写入
updateTag是一个新的Server Actions专用API,提供”读取即写入”语义——用户做出更改后,UI立即显示更改,而不是显示过时数据。
'use server' |
这确保交互功能立即反映更改,非常适合表单、用户设置等场景。
refresh:刷新客户端路由
refresh允许从Server Action内部刷新客户端路由:
'use server' |
cacheLife和cacheTag稳定
cacheLife和cacheTag现在稳定了,不再需要unstable_前缀:
// 之前 |
路由和导航优化
Next.js 16包含路由和导航系统的全面改革,使页面转换更精简、更快速:
- 布局去重:当预取多个共享布局的URL时,布局只下载一次
- 增量预取:Next.js只预取缓存中不存在的部分,而不是整个页面
这些变化不需要代码修改,旨在提高所有应用的性能。
middleware更名proxy
重要变化
middleware文件名已废弃,重命名为proxy,以明确网络边界和路由焦点。
edge运行时在proxy中不支持。proxy运行时是nodejs,无法配置。如果想继续使用edge运行时,请继续使用middleware。
# 重命名middleware文件 |
命名导出middleware也已废弃,将函数重命名为proxy:
export function proxy(request: Request) {} |
包含middleware名称的配置标志也已重命名,例如skipMiddlewareUrlNormalize现在是skipProxyUrlNormalize。
next/image重要变化
带查询字符串的本地图片
带查询字符串的本地图片现在需要images.localPatterns.search配置来防止枚举攻击:
const nextConfig: NextConfig = { |
minimumCacheTTL默认值变化
images.minimumCacheTTL的默认值从60秒变为4小时(14400秒)。这减少了没有cache-control头的图片的重新验证成本。
如果需要以前的行为,可以将minimumCacheTTL设置回60秒。
imageSizes默认值变化
默认images.imageSizes数组中的值16已被移除。很少有项目会提供16像素宽的图片,移除这个设置可以减少next/image发送到浏览器的srcset属性大小。
qualities默认值变化
images.qualities的默认值从允许所有质量变为只允许[75]。
本地IP限制
新的安全限制默认阻止本地IP优化。只能为私有网络设置images.dangerouslyAllowLocalIP为true。
最大重定向数
images.maximumRedirects的默认值从无限制变为最多3次重定向。
next/legacy/image废弃
next/legacy/image组件已废弃,使用next/image代替。
images.domains配置废弃
images.domains配置已废弃,使用images.remotePatterns代替以提高安全性。
并行路由default.js要求
所有并行路由槽位现在需要显式的default.js文件。没有它们构建将失败。
import { notFound } from 'next/navigation' |
或返回null:
export default function Default() { |
部分预渲染(PPR)变化
Next.js 16移除了实验性PPR标志和配置选项,包括路由级别的experimental_ppr。
从Next.js 16开始,可以通过cacheComponents配置来选择使用PPR:
const nextConfig = { |
注意:Next.js 16的PPR与Next.js 15 canaries中的PPR工作方式不同。如果现在正在使用PPR,建议保持在当前使用的Next.js 15 canary版本。
其他重要变化
ESLint Flat Config
@next/eslint-plugin-next现在默认使用ESLint Flat Config格式,与ESLint v10对齐。
滚动行为覆盖
在Previous版本的Next.js中,如果全局在HTML元素上设置了scroll-behavior: smooth,Next.js会在SPA路由转换期间覆盖这个设置。
在Next.js 16中,默认情况下Next.js不再覆盖你的滚动行为设置。如果希望Next.js执行覆盖(之前的默认行为),在HTML元素上添加data-scroll-behavior="smooth"属性:
export default function RootLayout({ children }) { |
并发dev和build
next dev和next build现在使用不同的输出目录,启用并发执行。next dev命令输出到.next/dev。
AMP支持移除
AMP的采用已显著下降,维护这个功能增加了框架的复杂性。所有AMP API和配置都已移除。
next lint命令移除
next lint命令已被移除,使用Biome或直接使用ESLint。next build不再运行linting。
npx @next/codemod@canary next-lint-to-eslint-cli . |
运行时配置移除
serverRuntimeConfig和publicRuntimeConfig已被移除,使用环境变量代替。
之前通过运行时配置的值,现在应该:
- 服务器端值:直接在Server Components中访问环境变量
- 客户端可用值:使用
NEXT_PUBLIC_前缀
devIndicators选项移除
以下选项已从devIndicators中移除:
appIsrStatusbuildActivitybuildActivityPosition
指标本身仍然可用。
总结
Next.js 16是一次里程碑式的版本更新,带来了以下核心变化:
- Turbopack默认启用:Webpack不再是默认构建工具
- 异步API完全化:cookies、headers、params等必须异步访问
- React Compiler稳定:自动优化组件渲染性能
- 缓存API增强:updateTag实现立即读取写入
- middleware更名proxy:明确网络边界概念
- next/image配置调整:安全性和性能优化
- 多项功能移除:AMP、next lint、运行时配置等
虽然升级需要一定工作量,但这些变化都将大幅提升应用性能和开发体验。建议尽快规划升级计划,享受新版本带来的改进。