跳到内容
返回博客

2025年10月9日,星期四

Next.js 16 (Beta)

发布者

Next.js 16 (Beta) 现已发布。此早期版本在稳定版发布之前,提供了 Turbopack、缓存和 Next.js 架构的最新改进。此版本亮点包括:

我们鼓励您试用 Beta 版并分享您的反馈。您的测试有助于我们在稳定版发布之前发现问题并改进 Next.js。请在 GitHub 上报告您遇到的任何错误或问题。

升级到 Beta 版

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

开发者体验

Turbopack (稳定版)

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

使用 Turbopack,您可以期待:

  • 生产构建速度提升 2-5 倍
  • Fast Refresh 速度提升高达 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)

Build Adapters 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 编译器 1.0 版本的发布,Next.js 16 中对 React 编译器的内置支持现已稳定。React 编译器自动记忆化组件,无需手动更改代码即可减少不必要的重新渲染。

reactCompiler 配置选项已从 experimental 升级到稳定版。由于我们仍在收集不同应用程序类型的构建性能数据,因此它默认未启用。启用此选项后,由于 React 编译器依赖 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 只预取缓存中没有的部分,而不是整个页面。预取缓存现在:

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

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

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

PPR 和缓存组件

Next.js 16 移除了实验性的局部预渲染 (PPR) 标志和配置选项。PPR 正在集成到缓存组件中。

从 Next.js 16 开始,您可以使用 experimental.cacheComponents 配置选择 PPR。实现上存在差异,缓存组件带来了额外的功能和行为,这些将在 Next.js Conf 和 Next.js 16 稳定版发布之前进行文档和公布。

如果您的应用程序依赖 PPR (experimental.ppr = true):请继续使用您当前使用的 Next.js canary 锁定版本。如果您在迁移时遇到困难,请暂时停留在当前版本,我们将在稳定版发布之前提供迁移指南。

改进的缓存 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 中定义的自定义配置文件。您也可以传入内联的 { revalidate: number } 对象。我们建议在大多数情况下使用 'max',因为它为长期内容启用了后台重新验证。当用户请求标记内容时,他们会立即收到缓存数据,而 Next.js 会在后台进行重新验证。

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

迁移指南:为 SWR 行为添加带有 cacheLife 配置文件的第二个参数(我们推荐 'max'),或者如果您需要读后写语义,请在 Server Actions 中使用 updateTag()

updateTag() (新)

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

行为变更

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

已更改的行为详情
默认打包工具Turbopack 现已成为所有应用程序的默认打包工具;通过 next build --webpack 选择退出
images.minimumCacheTTL 默认值从 60 秒更改为 4 小时 (14400 秒);减少了没有 cache-control 头部的图像的重新验证成本
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 的帮助!