2024 年 5 月 23 日,星期四
Next.js 15 RC
发布者Next.js 15 候选发布版 (RC) 现已发布。此早期版本允许您在即将发布的稳定版本之前测试最新功能。
- React: 支持 React 19 RC、React Compiler(实验性)和 hydration 错误改进
- 缓存:
fetch
请求、GET
路由处理器和客户端导航默认不再缓存 - 部分预渲染(实验性): 用于增量采用的新布局和页面配置选项
next/after
(实验性): 用于在响应完成流式传输后执行代码的新 APIcreate-next-app
: 更新的设计和一个新标志,用于在本地开发中启用 Turbopack- 捆绑外部包(稳定版): App 和 Pages Router 的新配置选项
立即试用 Next.js 15 RC
npm install next@rc react@rc react-dom@rc
React 19 RC
Next.js App Router 构建于 React canary channel for frameworks,这使得开发人员可以在 v19 版本发布之前使用这些新的 React API 并提供反馈。
Next.js 15 RC 现在支持 React 19 RC,其中包括客户端和服务器的新功能,例如 Actions。
阅读 Next.js 15 升级指南、React 19 升级指南,并观看 React Conf Keynote 以了解更多信息。
注意: 某些第三方库可能尚不兼容 React 19。
React Compiler(实验性)
React Compiler 是 Meta 的 React 团队创建的一个新的实验性编译器。该编译器通过理解纯 JavaScript 语义和 React 规则,从深层理解您的代码,这使其能够自动优化您的代码。该编译器减少了开发人员必须通过 useMemo
和 useCallback
等 API 进行的手动 memoization 量 - 使代码更简单、更易于维护且不易出错。
在 Next.js 15 中,我们增加了对 React Compiler 的支持。
安装 babel-plugin-react-compiler
npm install babel-plugin-react-compiler
然后,在 next.config.js
中添加 experimental.reactCompiler
选项
const nextConfig = {
experimental: {
reactCompiler: true,
},
};
module.exports = nextConfig;
可选地,您可以将编译器配置为在“opt-in”模式下运行,如下所示
const nextConfig = {
experimental: {
reactCompiler: {
compilationMode: 'annotation',
},
},
};
module.exports = nextConfig;
注意: React Compiler 目前只能通过 Babel 插件在 Next.js 中使用,这可能会导致构建时间变慢。
了解有关 React Compiler 和 可用的 Next.js 配置选项 的更多信息。
Hydration 错误改进
Next.js 14.1 改进了 错误消息和 hydration 错误。Next.js 15 在此基础上继续构建,添加了改进的 hydration 错误视图。Hydration 错误现在显示错误源代码,并提供有关如何解决该问题的建议。
例如,这是 Next.js 14.1 中之前的 hydration 错误消息


Next.js 15 RC 已将其改进为


缓存更新
Next.js App Router 启动时采用了固定的缓存默认设置。这些设置旨在默认提供最佳性能选项,并在需要时可以选择退出。
根据您的反馈,我们重新评估了我们的 缓存启发式方法 以及它们如何与部分预渲染 (PPR) 等项目以及使用 fetch
的第三方库交互。
在 Next.js 15 中,我们将 fetch
请求、GET
路由处理器和客户端路由缓存的缓存默认设置从默认缓存更改为默认不缓存。如果您想保留以前的行为,您可以继续选择启用缓存。
我们将在未来几个月内继续改进 Next.js 中的缓存,我们将在 Next.js 15 GA 公告中分享更多详细信息。
fetch
请求默认不再缓存
Next.js 使用 Web fetch
API 缓存选项来配置服务器端 fetch 请求如何与框架的持久 HTTP 缓存交互
fetch('https://...', { cache: 'force-cache' | 'no-store' });
no-store
- 每次请求都从远程服务器获取资源,并且不更新缓存force-cache
- 从缓存(如果存在)或远程服务器获取资源并更新缓存
在 Next.js 14 中,如果未提供 cache
选项,则默认使用 force-cache
,除非使用了动态函数或动态配置选项。
在 Next.js 15 中,如果未提供 cache
选项,则默认使用 no-store
。这意味着 fetch 请求默认将不被缓存。
您仍然可以通过以下方式选择启用 fetch
请求的缓存
- 在单个
fetch
调用中,将cache
选项 设置为force-cache
- 对于单个路由,将
dynamic
路由配置选项 设置为'force-static'
- 将
fetchCache
路由配置选项 设置为'default-cache'
,以覆盖布局或页面中的所有fetch
请求以使用force-cache
,除非它们显式指定自己的cache
选项
GET
路由处理器默认不再缓存
在 Next 14 中,使用 GET
HTTP 方法的路由处理器默认会被缓存,除非它们使用了动态函数或动态配置选项。在 Next.js 15 中,GET
函数默认不缓存。
您仍然可以使用静态路由配置选项(例如 export dynamic = 'force-static'
)选择启用缓存。
特殊路由处理器(如 sitemap.ts
、opengraph-image.tsx
和 icon.tsx
以及其他 metadata 文件 默认保持静态,除非它们使用动态函数或动态配置选项。
客户端路由缓存默认不再缓存页面组件
在 Next.js 14.2.0 中,我们引入了一个实验性的 staleTimes
标志,以允许自定义配置 路由缓存。
在 Next.js 15 中,此标志仍然可用,但我们将默认行为更改为页面分段的 staleTime
为 0
。这意味着当您在应用程序中导航时,客户端将始终反映从作为导航一部分变为活动的页面组件获取的最新数据。但是,仍有一些重要的行为保持不变
- 共享布局数据将不会从服务器重新获取,以继续支持 部分渲染。
- 后退/前进导航仍将从缓存恢复,以确保浏览器可以恢复滚动位置。
- Loading.js 将保持缓存 5 分钟(或
staleTimes.static
配置的值)。
您可以通过设置以下配置来选择使用之前的客户端路由缓存行为
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30,
},
},
};
module.exports = nextConfig;
部分预渲染的增量采用(实验性)
在 Next.js 14 中,我们 引入了部分预渲染 (PPR) - 一种优化,它将 静态渲染和动态渲染 结合在同一页面上。
Next.js 当前默认为静态渲染,除非您使用 动态函数,例如 cookies()
、headers()
和未缓存的数据请求。这些 API 将整个路由选择为动态渲染。使用 PPR,您可以将任何动态 UI 包装在 Suspense 边界中。当新的请求进入时,Next.js 将立即提供静态 HTML shell,然后在同一 HTTP 请求中渲染和流式传输动态部分。
为了允许增量采用,我们为选择将特定布局和页面加入 PPR 添加了 experimental_ppr
路由配置选项
import { Suspense } from "react"
import { StaticComponent, DynamicComponent } from "@/app/ui"
export const experimental_ppr = true
export default function Page() {
return {
<>
<StaticComponent />
<Suspense fallback={...}>
<DynamicComponent />
</Suspense>
</>
};
}
要使用新选项,您需要在 next.config.js
文件中将 experimental.ppr
配置设置为 'incremental'
const nextConfig = {
experimental: {
ppr: 'incremental',
},
};
module.exports = nextConfig;
一旦所有分段都启用了 PPR,就可以认为将 ppr
值设置为 true
是安全的,并为整个应用程序和所有未来的路由启用它。
我们将在 Next.js 15 GA 博客文章中分享更多关于我们的 PPR 路线图的信息。
了解有关 部分预渲染 的更多信息。
使用 next/after
(实验性)在响应后执行代码
在处理用户请求时,服务器通常执行与计算响应直接相关的任务。但是,您可能需要执行诸如日志记录、分析和其他外部系统同步之类的任务。
由于这些任务与响应没有直接关系,因此用户不应等待它们完成。在响应用户后推迟工作会带来挑战,因为无服务器函数在响应关闭后立即停止计算。
after()
是一个新的实验性 API,它通过允许您安排在响应完成流式传输后处理的工作来解决此问题,从而使辅助任务能够在不阻塞主响应的情况下运行。
要使用它,请将 experimental.after
添加到 next.config.js
const nextConfig = {
experimental: {
after: true,
},
};
module.exports = nextConfig;
然后,在服务器组件、服务器操作、路由处理器或中间件中导入该函数。
import { unstable_after as after } from 'next/server';
import { log } from '@/app/utils';
export default function Layout({ children }) {
// Secondary task
after(() => {
log();
});
// Primary task
return <>{children}</>;
}
了解有关 next/after
的更多信息。
create-next-app
更新
对于 Next.js 15,我们更新了 create-next-app
,采用了新的设计。


运行 create-next-app
时,会弹出一个新提示,询问您是否要为本地开发启用 Turbopack(默认为 否
)。
✔ Would you like to use Turbopack for next dev? … No / Yes
可以使用 --turbo
标志来启用 Turbopack。
npx create-next-app@rc --turbo
为了使新项目的入门更加容易,CLI 中添加了一个新的 --empty
标志。这将删除任何无关的文件和样式,从而生成一个最简化的“hello world”页面。
npx create-next-app@rc --empty
优化外部包的捆绑(稳定版)
捆绑外部包可以提高应用程序的冷启动性能。在 App Router 中,默认情况下会捆绑外部包,您可以使用新的 serverExternalPackages
配置选项选择退出特定包。
在 Pages Router 中,默认情况下不捆绑外部包,但是您可以使用现有的 transpilePackages
选项提供要捆绑的包列表。使用此配置选项,您需要指定每个包。
为了统一 App Router 和 Pages Router 之间的配置,我们引入了一个新的选项,bundlePagesRouterDependencies
,以匹配 App Router 的默认自动捆绑行为。如果需要,您可以使用 serverExternalPackages
选项来选择退出特定的包。
const nextConfig = {
// Automatically bundle external packages in the Pages Router:
bundlePagesRouterDependencies: true,
// Opt specific packages out of bundling for both App and Pages Router:
serverExternalPackages: ['package-name'],
};
module.exports = nextConfig;
了解更多关于 优化外部包的信息。
其他更改
- [重大变更] 最低 React 版本现在为 19 RC
- [重大变更] next/image: 移除
squoosh
,转而使用sharp
作为可选依赖项 (PR) - [重大变更] next/image: 将默认
Content-Disposition
更改为attachment
(PR) - [重大变更] next/image: 当
src
包含前导或尾随空格时报错 (PR) - [重大变更] Middleware: 应用
react-server
条件来限制不推荐的 react API 导入 (PR) - [重大变更] next/font: 移除对外部
@next/font
包的支持 (PR) - [重大变更] next/font: 移除
font-family
哈希处理 (PR) - [重大变更] 缓存:
force-dynamic
现在将为 fetch 缓存设置no-store
默认值 (PR) - [重大变更] 配置: 默认启用
swcMinify
(PR),missingSuspenseWithCSRBailout
(PR) 和outputFileTracing
(PR) 行为,并移除已弃用的选项 - [重大变更] 移除 Speed Insights 的自动插桩 (现在必须使用专用的 @vercel/speed-insights 包) (PR)
- [重大变更] 移除动态站点地图路由的
.xml
扩展名,并对齐开发环境和生产环境之间的站点地图 URL (PR) - [改进] Metadata: 更新了在 Vercel 上托管时
metadataBase
的环境变量回退 (PR) - [改进] 修复了来自
optimizePackageImports
的混合命名空间和命名导入的 tree-shaking 问题 (PR) - [改进] Parallel Routes: 为未匹配的 catch-all 路由提供所有已知的参数 (PR)
- [改进] 配置
bundlePagesExternals
现在已稳定,并重命名为bundlePagesRouterDependencies
- [改进] 配置
serverComponentsExternalPackages
现在已稳定,并重命名为serverExternalPackages
- [改进] create-next-app: 新项目默认忽略所有
.env
文件 (PR) - [文档] 改进了身份验证文档 (PR)
- [文档]
@next/env
包 (PR)
要了解更多信息,请查看升级指南。
贡献者
Next.js 是超过 3,000 名个人开发者、Google 和 Meta 等行业合作伙伴以及 Vercel 核心团队共同努力的成果。此版本由以下人员为您带来:
- Next.js 团队:Andrew、Balazs、 Ethan、 Janka、Jiachi、Jimmy、JJ、Josh、 Sam、Sebastian、 Sebbie、Shu、Steven、Tim、Wyatt 和 Zack。
- Turbopack 团队:Alex、 Benjamin、 Donny、Leah、Maia、OJ、Tobias 和 Will。
- Next.js 文档:Delba、Steph、Michael、 Anthony 和 Lee。
非常感谢 @devjiwonchoi、@ijjk、@Ethan-Arrowood、@sokra、@kenji-webdev、@wbinnssmith、@huozhi、@domdomegg、@samcx、@Jaaneek、@evanwinter、@wyattjoh、@kdy1、@balazsorban44、@feedthejim、@ztanner、@ForsakenHarmony、@kwonoj、@delbaoliveira、@stipsan、@leerob、@shuding、@xiaohanyu、@timneutkens、@dvoytenko、@bobaaaaa、@bgw、@gaspar09、@souporserious、@unflxw、@kiner-tang、@Ehren12、@EffectDoplera、@IAmKushagraSharma、@Auxdible、@sean-rallycry、@Jeffrey-Zutt、@eps1lon、@jeanmax1me、@unstubbable、@NilsJacobsen、@PaulAsjes、@adiguno、@ryan-nauman、@zsh77、@KagamiChan、@steveluscher、@MehfoozurRehman、@vkryachko、@chentsulin、@samijaber、@begalinsaf、@FluxCapacitor2、@lukahartwig、@brianshano、@pavelglac、@styfle、@symant233、@HristovCodes、@karlhorky、@jonluca、@jonathan-ingram、@mknichel、@sopranopillow、@Gomah、@imddc、@notrab、@gabrielrolfsen、@remorses、@AbhiShake1、@agadzik、@ryota-murakami、@rishabhpoddar、@rezamauliadi、@IncognitoTGT、@webtinax、@BunsDev、@nisabmohd、@z0n、@bennettdams、@joeshub、@n1ckoates、@srkirkland、@RiskyMH、@coopbri、@okoyecharles、@diogocapela、@dnhn、@typeofweb、@davidsa03、@imranolas、@lubieowoce、@maxhaomh、@mirasayon、@blvdmitry、@hwangstar156、@lforst、@emmerich、@christian-bromann、@Lsnsh、@datner、@hiro0218、@flybayer、@ianmacartney、@ypessoa、@ryohidaka、@icyJoseph、@Arinji2、@lovell、@nsams、@Nayeem-XTREME、@JamBalaya56562、@Arindam200、@gaojude、@qqww08、@todor0v、@coltonehrman 和 @wiesson 的帮助!