2024年12月10日,星期二
Next.js 15.1
发布者Next.js 15.1 带来了核心升级、新的 API 和开发体验的改进。主要更新包括:
- React 19 (稳定版):Pages Router 和 App Router 均正式支持 React 19。
- 改进的错误调试:增强了开发体验,并为浏览器和终端提供了更好的源映射。
after(稳定版):新的 API,用于在响应流结束后执行代码。forbidden/unauthorized(实验性):新的 API,用于实现更精细的认证错误处理。
立即升级,或开始使用
# 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@latestReact 19 (稳定版)
Next.js 15.1 现已完全支持 React 19。
- 对于 Pages Router:您现在可以使用 React 19 稳定版,而无需使用发布候选版或 Canary 版,并继续支持 React 18。
- 对于 App Router:我们将继续提供内置的 React Canary 版本。这些版本包括所有稳定的 React 19 更改,以及在新的 React 版本发布之前,在框架中进行验证的更新功能。
自 Next.js 15 发布以来,React 19 的一个重要新增功能是“兄弟预热”。
有关 React 19 更新的全面概述,请参阅官方 React 19 博客文章。
改进的错误调试
我们改进了 Next.js 中的错误调试,确保您可以快速定位问题源,无论它们出现在终端、浏览器还是附加的调试器中。这些增强功能适用于 Webpack 和 Turbopack(现已随 Next.js 15 稳定)。
源映射增强功能
现在,通过改进的源映射使用,错误更容易追溯到其源头。我们实现了源映射的ignoreList属性,这允许 Next.js 隐藏外部依赖项的堆栈帧,使您的应用程序代码成为主要焦点。
为了更准确地映射方法名,我们建议采用 Turbopack(现已稳定),它比 Webpack 具有更好的源映射处理和检测能力。
对于库作者:我们建议在发布库时填充源映射中的
ignoreList属性,特别是当它们被配置为外部库时(例如,在serverExternalPackages配置中)。
折叠堆栈帧
我们改进了堆栈帧折叠逻辑,以突出显示代码中最相关的部分。
- 在浏览器和错误覆盖层中:默认情况下,第三方依赖项的堆栈帧是隐藏的,重点关注您的应用程序代码。您可以通过点击开发工具或覆盖层中的“显示忽略的帧”来显示隐藏的帧。
- 在终端中:第三方依赖项的帧也默认折叠,错误格式现在与浏览器输出保持一致,以提供一致的调试体验。错误会在浏览器中重放,以确保您在开发过程中不会错过重要的信息,如果您需要完整的堆栈跟踪。
增强的性能分析
忽略的堆栈帧也受到内置浏览器分析器的识别。这使得您的应用程序性能分析更容易,您可以准确定位代码中的慢函数,而不会受到外部库的干扰。
通过 Edge Runtime 改进
在使用 Edge Runtime 时,错误现在在开发环境中一致显示,确保无缝调试。以前,日志错误只会包含消息,而不包含堆栈。
之前和之后
终端 之前
⨯ app/page.tsx (6:11) @ eval
⨯ Error: boom
at eval (./app/page.tsx:12:15)
at Page (./app/page.tsx:11:74)
at AsyncLocalStorage.run (node:async_hooks:346:14)
at stringify (<anonymous>)
at AsyncLocalStorage.run (node:async_hooks:346:14)
at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
digest: "380744807"
4 | export default function Page() {
5 | const throwError = myCallback(() => {
> 6 | throw new Error('boom')
| ^
7 | }, [])
8 |
9 | throwError()
GET / 500 in 2354ms终端 之后
⨯ Error: boom
at eval (app/page.tsx:6:10)
at Page (app/page.tsx:5:32)
4 | export default function Page() {
5 | const throwError = myCallback(() => {
> 6 | throw new Error('boom')
| ^
7 | }, [])
8 |
9 | throwError() {
digest: '225828171'
}错误覆盖层 之前

错误覆盖层 之后

这些改进使得错误更清晰、更直观,让您可以将时间集中于构建应用程序而非调试。
我们也很高兴地宣布,在即将发布的版本中,将推出重新设计的错误覆盖层 UI。
after (稳定版)
在 Next.js 15 RC 的首次引入之后,after() API 现已稳定。
after() 提供了一种在响应流向用户结束后执行日志记录、分析和其他系统同步任务的方式,而不会阻塞主要响应。
主要变化
自引入以来,我们已经稳定了 after() 并解决了包括以下反馈:
- 改进了对自托管 Next.js 服务器的支持。
- 修复了
after()与其他 Next.js 功能交互的场景中的错误。 - 增强了可扩展性,使其他平台能够注入自己的
waitUntil()原语来支持after()。 - 在服务器动作和路由处理程序中支持运行时 API,例如
cookies()和headers()。
import { after } from 'next/server';
import { log } from '@/app/utils';
export default function Layout({ children }) {
// Secondary task
after(() => {
log();
});
// Primary task
return <>{children}</>;
}阅读文档以了解有关 after API 及其使用方法的更多信息。
forbidden 和 unauthorized (实验性)
Next.js 15.1 包含了两个实验性 API,forbidden() 和 unauthorized(),它们是基于社区反馈而开发的。
我们期待您的反馈 — 请在您的开发环境中尝试并在此讨论帖中分享您的想法。
概述
如果您熟悉 App Router,您可能使用过 notFound() 来触发 404 行为以及可定制的 not-found.tsx 文件。在 15.1 版本中,我们将此方法扩展到授权错误:
• forbidden() 通过 forbidden.tsx 触发403 错误并显示可定制的 UI。
• unauthorized() 通过 unauthorized.tsx 触发401 错误并显示可定制的 UI。
温馨提示:与
notFound()错误一样,如果错误在初始响应头发送后触发,则状态码将为200。了解更多。
启用此功能
由于此功能仍处于实验阶段,您需要在 next.config.ts 文件中启用它:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
authInterrupts: true,
},
};
export default nextConfig;注意:
next.config.ts支持在 Next.js 15 中引入。了解更多。
使用 forbidden() 和 unauthorized()
您可以在服务器动作、服务器组件、客户端组件或路由处理程序中使用 forbidden() 和 unauthorized()。示例如下:
import { verifySession } from '@/app/lib/dal';
import { forbidden } from 'next/navigation';
export default async function AdminPage() {
const session = await verifySession();
// Check if the user has the 'admin' role
if (session.role !== 'admin') {
forbidden();
}
// Render the admin page for authorized users
return <h1>Admin Page</h1>;
}创建自定义错误页面
要自定义错误页面,请创建以下文件:
import Link from 'next/link';
export default function Forbidden() {
return (
<div>
<h2>Forbidden</h2>
<p>You are not authorized to access this resource.</p>
<Link href="/">Return Home</Link>
</div>
);
}import Link from 'next/link';
export default function Unauthorized() {
return (
<div>
<h2>Unauthorized</h2>
<p>Please log in to access this page.</p>
<Link href="/login">Go to Login</Link>
</div>
);
}我们衷心感谢Clerk通过拉取请求提出此功能并协助我们进行 API 原型设计。在我们于 15.2 版本中稳定此功能之前,我们计划为 API 添加更多功能和改进,以支持更广泛的使用场景。
请阅读 unauthorized 和 forbidden API 的文档以获取更多详细信息。
其他更改
- [功能] 在
create-next-app中使用 ESLint 9 (PR) - [功能] 将最大缓存标签增加到 128 个 (PR)
- [功能] 添加禁用实验性 CssChunkingPlugin 的选项 (PR)
- [功能] 添加实验性 CSS 内联支持 (PR)
- [改进] 消除 Sass
legacy-js-api警告 (PR) - [改进] 修复使用重写时未处理的拒绝问题 (PR)
- [改进] 确保 Webpack worker 失败时父进程退出 (PR)
- [改进] 修复了包罗万象路由上的路由拦截问题 (PR)
- [改进] 修复了请求去重中的响应克隆问题 (PR)
- [改进] 修复了多个根布局之间服务器动作重定向的问题 (PR)
- [改进] 支持将 MDX 插件作为字符串提供以实现 Turbopack 兼容性 (PR)
贡献者
Next.js 是超过 3,000 名独立开发者共同努力的成果。此版本由以下团队提供
- Next.js 团队:Andrew、Hendrik、Janka、Jiachi、Jimmy、Jiwon、JJ、Josh、Jude、Sam、Sebastian、Sebbie、Wyatt 和 Zack。
- Turbopack 团队:Alex、Benjamin、Donny、Maia、Niklas、Tim、Tobias 和 Will。
- Next.js 文档 团队:Delba、Rich、Ismael 和 Lee。
非常感谢 @sokra、@molebox、@delbaoliveira、@eps1lon、@wbinnssmith、@JamBalaya56562、@hyungjikim、@adrian-faustino、@mottox2、@lubieowoce、@bgw、@mknichel、@wyattjoh、@huozhi、@kdy1、@mischnic、@ijjk、@icyJoseph、@acdlite、@unstubbable、@gaojude、@devjiwonchoi、@cena-ko、@lforst、@devpla、@samcx、@styfle、@ztanner、@Marukome0743、@timneutkens、@JeremieDoctrine、@ductnn、@karlhorky、@reynaldichernando、@chogyejin、@y-yagi、@philparzer、@alfawal、@Rhynden、@arlyon、@MJez29、@Goodosky、@themattmayfield、@tobySolutions、@kevinmitch14、@leerob、@emmanuelgautier、@mrhrifat、@lid0a、@boar-is、@nisabmohd、@PapatMayuri、@ovogmap、@Reflex2468、@LioRael、@betterthanhajin、@HerringtonDarkholme、@bpb54321、@ahmoin、@Kikobeats、@abdelrahmanAbouelkheir、@lumirlumir、@yeeed711、@petter 和 @suu3 的帮助!

