跳到内容
返回博客

2025年10月21日,星期二

Next.js 16

发布者

在即将到来的Next.js Conf 2025之前,Next.js 16 现已可用。

本次发布对 Turbopack、缓存和 Next.js 架构进行了最新的改进。自上一个 Beta 版本以来,我们增加了多项新功能和改进:

  • 缓存组件:使用部分预渲染(PPR)的新模型和使用缓存实现即时导航。
  • Next.js Devtools MCP:模型上下文协议集成,改进了调试和工作流程。
  • 代理:中间件被 proxy.ts 替换,以明确网络边界。
  • DX:改进了构建和开发请求的日志记录。

提醒一下,这些功能在之前的 Beta 版本中已经可用:

升级到 Next.js 16

终端
# Use the automated upgrade CLI
npx @next/codemod@canary upgrade latest
 
# ...or upgrade manually
npm install next@latest react@latest react-dom@latest
 
# ...or start a new project
npx create-next-app@latest

如果 codemod 无法完全迁移您的代码,请阅读升级指南

新功能和改进

缓存组件

缓存组件是一组新功能,旨在使 Next.js 中的缓存更明确、更灵活。它们围绕新的 "use cache" 指令展开,该指令可用于缓存页面、组件和函数,并利用编译器在使用时自动生成缓存键。

与 App Router 早期版本中隐式缓存不同,缓存组件中的缓存完全是可选的。任何页面、布局或 API 路由中的所有动态代码在默认情况下都会在请求时执行,这使得 Next.js 的开箱即用体验更好地与开发人员对全栈应用程序框架的期望保持一致。

缓存组件也完善了部分预渲染 (PPR) 的概念,该功能于 2023 年首次引入。在 PPR 之前,Next.js 必须选择将每个 URL 静态或动态渲染;没有中间地带。PPR 消除了这种二分法,并允许开发人员将其静态页面的部分内容选择动态渲染(通过 Suspense),而不会牺牲完全静态页面的快速初始加载。

您可以在 next.config.ts 文件中启用缓存组件。

next.config.ts
const nextConfig = {
  cacheComponents: true,
};
 
export default nextConfig;

我们将在 10 月 22 日的Next.js Conf 2025上分享更多关于缓存组件及其使用方法,我们将在未来几周内在我们的博客和文档中分享更多内容。

注意:正如之前在 Beta 版本中宣布的那样,以前的实验性 experimental.ppr 标志和配置选项已删除,取而代之的是缓存组件配置。

在此处文档中了解更多信息。

Next.js Devtools MCP

Next.js 16 引入了 Next.js DevTools MCP,这是一种模型上下文协议集成,可用于 AI 辅助调试,并提供对应用程序的上下文洞察。

Next.js DevTools MCP 为 AI 代理提供:

  • Next.js 知识:路由、缓存和渲染行为。
  • 统一日志:无需切换上下文即可查看浏览器和服务器日志。
  • 自动错误访问:无需手动复制即可获得详细的堆栈跟踪。
  • 页面感知:对活动路由的上下文理解。

这使得 AI 代理可以直接在您的开发工作流程中诊断问题、解释行为并建议修复方案。

在此处文档中了解更多信息。

proxy.ts(原 middleware.ts

proxy.ts 替换了 middleware.ts,并明确了应用程序的网络边界。proxy.ts 在 Node.js 运行时上运行。

  • 操作方式:将 middleware.ts 重命名为 proxy.ts,并将导出的函数重命名为 proxy。逻辑保持不变。
  • 原因:更清晰的命名和用于请求拦截的单一、可预测的运行时。
proxy.ts
export default function proxy(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url));
}

注意: middleware.ts 文件仍可用于 Edge 运行时用例,但它已弃用,并将在未来版本中删除。

在此处文档中了解更多信息。

日志记录改进

在 Next.js 16 中,开发请求日志得到了扩展,显示了时间花费在哪里。

  • 编译:路由和编译
  • 渲染:运行您的代码和 React 渲染

构建也得到了扩展,显示了时间花费在哪里。构建过程中的每个步骤现在都显示了完成所需的时间。

终端
    Next.js 16 (Turbopack)
 
  Compiled successfully in 615ms
  Finished TypeScript in 1114ms
  Collecting page data in 208ms
  Generating static pages in 239ms
  Finalizing page optimization in 5ms

以下功能已在 Beta 版本中发布

开发者体验

Turbopack(稳定版)

Turbopack 在开发和生产构建方面均已达到稳定,现已成为所有新 Next.js 项目的默认打包器。自今年夏天发布 Beta 版以来,采用率迅速增长:Next.js 15.3+ 上超过 50% 的开发会话和 20% 的生产构建已在使用 Turbopack。

使用 Turbopack,您可以期待:

  • 生产构建速度提高 2-5 倍
  • 快速刷新速度提高多达 10 倍

我们将 Turbopack 作为默认设置,将这些性能提升带给每个 Next.js 开发人员,无需任何配置。对于使用自定义 webpack 设置的应用程序,您可以通过运行以下命令继续使用 webpack:

终端
next dev --webpack
next build --webpack

Turbopack 文件系统缓存(测试版)

Turbopack 现在支持开发中的文件系统缓存,在运行之间将编译器工件存储在磁盘上,从而显著加快重启时的编译时间,尤其是在大型项目中。

在您的配置中启用文件系统缓存

next.config.ts
const nextConfig = {
  experimental: {
    turbopackFileSystemCacheForDev: true,
  },
};
 
export default nextConfig;

所有 Vercel 内部应用程序都在使用此功能,我们注意到大型存储库的开发人员生产力显著提高。

我们期待您在迭代文件系统缓存时提供反馈。请尝试使用并分享您的经验。

简化 create-next-app

create-next-app 经过重新设计,简化了设置流程,更新了项目结构,并改进了默认值。新模板默认包含 App Router、TypeScript 优先配置、Tailwind CSS 和 ESLint。

构建适配器 API (alpha)

构建适配器 RFC之后,我们与社区和部署平台合作,发布了 Build Adapters API 的第一个 Alpha 版本。

构建适配器允许您创建自定义适配器,这些适配器可以连接到构建过程,使部署平台和自定义构建集成能够修改 Next.js 配置或处理构建输出。

next.config.js
const nextConfig = {
  experimental: {
    adapterPath: require.resolve('./my-adapter.js'),
  },
};
 
module.exports = nextConfig;

RFC 讨论中分享您的反馈。

React 编译器支持(稳定版)

在 React Compiler 1.0 发布后,Next.js 16 中对 React Compiler 的内置支持现已稳定。React Compiler 自动记忆组件,无需手动代码更改即可减少不必要的重新渲染。

reactCompiler 配置选项已从 experimental 升级到稳定版。它默认未启用,因为我们仍在收集不同应用程序类型的构建性能数据。启用此选项时,由于 React Compiler 依赖于 Babel,因此开发和构建期间的编译时间预计会更高。

next.config.ts
const nextConfig = {
  reactCompiler: true,
};
 
export default nextConfig;

安装最新版本的 React Compiler 插件

终端
npm install babel-plugin-react-compiler@latest

核心功能和架构

增强的路由和导航

Next.js 16 包含了对路由和导航系统的全面改进,使页面转换更精简、更快速。

布局去重:当预取多个共享布局的 URL 时,布局只会下载一次,而不是每个链接单独下载。例如,一个包含 50 个产品链接的页面现在只会下载一次共享布局,而不是 50 次,从而显著减少了网络传输大小。

增量预取:Next.js 只预取尚未缓存的部分,而不是整个页面。预取缓存现在:

  • 当链接离开视口时取消请求
  • 在悬停或重新进入视口时优先预取链接
  • 当数据失效时重新预取链接
  • 与即将推出的缓存组件等功能无缝协作

权衡:您可能会看到更多的单个预取请求,但总传输大小会大大降低。我们相信这对于几乎所有应用程序来说都是正确的权衡。如果增加的请求数量导致问题,请告诉我们。我们正在研究额外的优化方案,以更高效地内联数据块。

这些更改无需修改代码,旨在提高所有应用程序的性能。

改进的缓存 API

Next.js 16 引入了经过优化的缓存 API,可更明确地控制缓存行为。

revalidateTag()(已更新)

revalidateTag() 现在需要一个 cacheLife 配置文件 作为第二个参数,以启用陈旧时重新验证 (SWR) 行为。

import { revalidateTag } from 'next/cache';
 
// ✅ Use built-in cacheLife profile (we recommend 'max' for most cases)
revalidateTag('blog-posts', 'max');
 
// Or use other built-in profiles
revalidateTag('news-feed', 'hours');
revalidateTag('analytics', 'days');
 
// Or use an inline object with a custom revalidation time
revalidateTag('products', { revalidate: 3600 });
 
// ⚠️ Deprecated - single argument form
revalidateTag('blog-posts');

配置文件参数接受内置的 cacheLife 配置文件名称(例如 'max''hours''days')或在 next.config 中定义的自定义配置文件。您也可以传入一个内联的 { expire: number } 对象。我们建议在大多数情况下使用 'max',因为它为长期存在的内容启用了后台重新验证。当用户请求带标签的内容时,他们会立即收到缓存数据,而 Next.js 会在后台重新验证。

当您希望仅通过陈旧时重新验证行为使正确标记的缓存条目失效时,请使用 revalidateTag()。这非常适合可以容忍最终一致性的静态内容。

迁移指南:为 SWR 行为添加带有 cacheLife 配置文件的第二个参数(我们建议使用 'max'),或者如果您需要读写一致性语义,请在服务器操作中使用 updateTag()

updateTag()(新)

updateTag() 是一个新的仅限服务器操作的 API,提供读写一致性语义,在同一请求中过期并立即读取新鲜数据。

'use server';
 
import { updateTag } from 'next/cache';
 
export async function updateUserProfile(userId: string, profile: Profile) {
  await db.users.update(userId, profile);
 
  // Expire cache and refresh immediately - user sees their changes right away
  updateTag(`user-${userId}`);
}

这确保了交互式功能能够立即反映更改。非常适合表单、用户设置以及任何用户期望立即看到其更新的工作流程。

refresh()(新)

refresh() 是一个新的仅限服务器操作的 API,用于刷新仅未缓存的数据。它根本不触及缓存。

'use server';
 
import { refresh } from 'next/cache';
 
export async function markNotificationAsRead(notificationId: string) {
  // Update the notification in the database
  await db.notifications.markAsRead(notificationId);
 
  // Refresh the notification count displayed in the header
  // (which is fetched separately and not cached)
  refresh();
}

此 API 是客户端 router.refresh() 的补充。当您在执行操作后需要刷新页面上其他地方显示的未缓存数据时使用它。您的缓存页面外壳和静态内容保持快速,而动态数据(如通知计数、实时指标或状态指示器)会刷新。

React 19.2 和 Canary 功能

Next.js 16 中的 App Router 使用最新的 React Canary 版本,其中包括新发布的 React 19.2 功能和其他正在逐步稳定的功能。亮点包括:

  • 视图过渡:动画在过渡或导航内部更新的元素
  • useEffectEvent:将 Effects 中的非反应式逻辑提取到可重用的 Effect Event 函数中
  • 活动:通过使用 display: none 隐藏 UI 同时保持状态并清理 Effects 来渲染“后台活动”

React 19.2 公告中了解更多信息。

重大更改和其他更新

版本要求

更改详情
Node.js 20.9+最低版本现为 20.9.0 (LTS);不再支持 Node.js 18
TypeScript 5+最低版本现为 5.1.0
浏览器Chrome 111+、Edge 111+、Firefox 111+、Safari 16.4+

移除

这些功能以前已被弃用,现在已移除

已移除替换
AMP 支持所有 AMP API 和配置已删除(useAmpexport const config = { amp: true }
next lint 命令直接使用 Biome 或 ESLint;next build 不再运行 linting。提供了 codemod:npx @next/codemod@canary next-lint-to-eslint-cli .
devIndicators 选项appIsrStatusbuildActivitybuildActivityPosition 已从配置中删除。指示器仍然存在。
serverRuntimeConfigpublicRuntimeConfig使用环境变量(.env 文件)
experimental.turbopack 位置配置已移至顶级 turbopack(不再位于 experimental 中)
experimental.dynamicIO 标志重命名为 cacheComponents
experimental.ppr 标志PPR 标志已删除;演变为缓存组件编程模型
export const experimental_ppr路由级别 PPR 导出已删除;演变为缓存组件编程模型
自动 scroll-behavior: smooth在 HTML 文档中添加 data-scroll-behavior="smooth" 以重新选择
unstable_rootParams()我们正在开发一个替代 API,并将在即将发布的次要版本中提供
同步 paramssearchParams 属性访问必须使用异步:await params, await searchParams
同步 cookies()headers()draftMode() 访问必须使用异步:await cookies()await headers()await draftMode()
元数据图像路由 params 参数更改为异步 paramsgenerateImageMetadata 中的 id 现在是 Promise<string>
带有查询字符串的 next/image 本地 src现在需要 images.localPatterns 配置以防止枚举攻击

行为变更

这些功能在 Next.js 16 中具有新的默认行为

更改的行为详情
默认打包器Turbopack 现在是所有应用程序的默认打包器;通过 next build --webpack 选择退出
images.minimumCacheTTL 默认值从 60 秒更改为 4 小时 (14400 秒);降低了没有缓存控制头部的图像的重新验证成本
images.imageSizes 默认值从默认尺寸中删除 16(仅 4.2% 的项目使用);减少了 srcset 大小和 API 变体
images.qualities 默认值[1..100] 更改为 [75]quality 属性现在被强制转换为 images.qualities 中最接近的值
images.dangerouslyAllowLocalIP新的安全限制默认阻止本地 IP 优化;仅对私有网络设置为 true
images.maximumRedirects 默认值从无限制更改为最多 3 次重定向;设置为 0 禁用或增加以应对罕见边缘情况
@next/eslint-plugin-next 默认值现在默认采用 ESLint Flat Config 格式,与将放弃旧版配置支持的 ESLint v10 对齐
预取缓存行为通过布局去重和增量预取进行了完全重写
revalidateTag() 签名现在需要 cacheLife 配置文件作为第二个参数以实现陈旧时重新验证行为
Turbopack 中的 Babel 配置如果找到 Babel 配置,则自动启用 Babel(以前会以硬错误退出)
终端输出重新设计,具有更清晰的格式、更好的错误消息和改进的性能指标
开发和构建输出目录next devnext build 现在使用单独的输出目录,从而实现并发执行
锁文件行为添加了锁文件机制,以防止在同一项目上运行多个 next devnext build 实例
并行路由 default.js所有并行路由槽位现在都需要显式的 default.js 文件;没有它们将导致构建失败。创建调用 notFound() 或返回 nulldefault.js 以获得之前的行为
现代 Sass APIsass-loader 升级到 v16,支持现代 Sass 语法和新功能

弃用

这些功能在 Next.js 16 中已弃用,并将在未来版本中移除

已弃用详情
middleware.ts 文件名重命名为 proxy.ts 以明确网络边界和路由重点
next/legacy/image 组件改用 next/image 以获得改进的性能和功能
images.domains 配置改用 images.remotePatterns 配置以提高安全限制
revalidateTag() 单参数对于 SWR,使用 revalidateTag(tag, profile);对于读写一致性,在 Actions 中使用 updateTag(tag)

额外改进

  • 性能改进next devnext start 命令的显著性能优化
  • Node.js next.config.ts 的原生 TypeScript:运行 next devnext buildnext start 命令时带上 --experimental-next-config-strip-types 标志,以启用 next.config.ts 的原生 TypeScript 支持。

我们将在文档中发布稳定版本之前,提供更全面的迁移指南。

反馈与社区

分享您的反馈,帮助塑造 Next.js 的未来

贡献者

Next.js 是超过 3,000 名独立开发者共同努力的成果。此版本由以下团队提供

衷心感谢 @mischnic、@timneutkens、@unstubbable、@wyattjoh、@Cy-Tek、@lukesandberg、@OoMNoO、@ztanner、@icyJoseph、@huozhi、@gnoff、@ijjk、@povilasv、@dwrth、@obendev、@aymericzip、@devjiwonchoi、@SyMind、@vercel-release-bot、@Shireee、@eps1lon、@dharun36、@kachkaev、@bgw、@yousefdawood7、@TheAlexLichter、@sokra、@ericx0099、@leerob、@Copilot、@fireairforce、@fufuShih、@anvibanga、@hayes、@Milancen123、@martinfrancois、@lubieowoce、@gaojude、@lachlanjc、@liketiger、@styfle、@aaronbrown-vercel、@Samii2383、@FelipeChicaiza、@kevva、@m1abdullahh、@F7b5、@Anshuman71、@RobertFent、@poteto、@chloe-yan、@sireesha-siri、@brian-lou、@joao4xz、@stefanprobst、@samselikoff、@acdlite、@gwkline、@bgub、@brock-statsig 和 @karlhorky 的帮助!