2024年12月10日,星期二
Next.js 15.1
發布者Next.js 15.1 帶來了核心升級、全新 API 以及開發者體驗的改進。主要更新包括
- React 19 (穩定版):Pages Router 和 App Router 皆已正式支援 React 19。
- 改善錯誤除錯:增強 DX 以及針對瀏覽器和終端機提供更佳的原始碼地圖。
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@latest
React 19 (穩定版)
Next.js 15.1 現在完全支援 React 19
- 對於 Pages Router:您現在可以使用 React 19 穩定版,而無需 Release Candidate 或 Canary 版本,同時繼續支援 React 18。
- 對於 App Router:我們將繼續內建提供 React Canary 版本。這些版本包含所有 React 19 穩定版的變更,以及在新的 React 版本發布之前,於框架中驗證的較新功能。
自 Next.js 15 版本發布以來,React 19 的一項重大新增功能是「sibling pre-warming」。
如需 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
(穩定版)
after()
API 在 Next.js 15 RC 的第一個版本中推出後,現在已穩定。
after()
提供一種方法,可以在回應完成串流傳輸到使用者後,執行記錄、分析和其他系統同步等工作,而不會阻礙主要回應。
主要變更
自推出以來,我們已將 after()
穩定化,並解決了包括下列項目的意見回饋
- 改善對自架設 Next.js 伺服器的支援。
- 針對
after()
與其他 Next.js 功能互動的情境進行錯誤修正。 - 增強可擴充性,讓其他平台能夠注入自己的
waitUntil()
原語來支援after()
。 - 支援 Server Actions 和 Route Handlers 中的執行階段 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.js 15 中引入了
next.config.ts
支援。深入瞭解。
使用 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 透過 PR 提出此功能,並協助我們建立 API 原型。在我們於 15.2 版本中將此功能穩定化之前,我們計畫為 API 新增更多功能和改進,以支援更廣泛的使用案例。
請閱讀 unauthorized
和 forbidden
API 的文件,以取得更多詳細資訊。
其他變更
- [功能] 在
create-next-app
中使用 ESLint 9 (PR) - [功能] 將最大快取標籤增加到 128 個 (PR)
- [功能] 新增選項以停用實驗性 CssChunkingPlugin (PR)
- [功能] 新增實驗性 CSS 內嵌支援 (PR)
- [改進] 靜止 Sass
legacy-js-api
警告 (PR) - [改進] 修正使用 rewrites 時未處理的拒絕 (PR)
- [改進] 確保在 webpack worker 失敗時父程序結束 (PR)
- [改進] 修正 catch-all 路由上的路由攔截 (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、 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 的協助!