Back返回部落格

Next.js 15.1

Next.js 15.1 帶來 React 19 穩定版支援、改進的錯誤除錯功能、新的實驗性授權 API 等更新。

Next.js 15.1 帶來了核心升級、新 API 和開發者體驗的改進。主要更新包括:

立即升級,或透過以下指令開始使用:

Terminal
# 使用自動升級 CLI
npx @next/codemod@canary upgrade latest
 
# ...或手動升級
npm install next@latest react@latest react-dom@latest
 
# ...或建立新專案
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 中穩定)。

原始碼映射 (Source Maps) 改進

透過改進原始碼映射的使用,現在更容易追蹤錯誤的來源。我們實作了 原始碼映射的 ignoreList 屬性,讓 Next.js 可以隱藏外部依賴的堆疊框架 (stack frames),使您的應用程式碼成為主要焦點。

為了獲得更準確的方法名稱原始碼映射,我們建議採用 Turbopack(現已穩定),它在原始碼映射的處理和檢測方面比 Webpack 更優異。

給函式庫作者:我們建議在發布函式庫時填充原始碼映射中的 ignoreList 屬性,尤其是當它們被配置為外部依賴時(例如在 serverExternalPackages 配置中)。

折疊堆疊框架

我們改進了折疊堆疊框架的邏輯,以突出顯示程式碼中最相關的部分。

  • 在瀏覽器和錯誤覆蓋層中:預設隱藏來自第三方依賴的堆疊框架,專注於您的應用程式碼。您可以點擊開發工具或覆蓋層中的「顯示忽略的框架」來顯示隱藏的框架。
  • 在終端機中:第三方依賴框架也預設折疊,錯誤格式化現在與瀏覽器輸出一致,提供一致的除錯體驗。錯誤會在瀏覽器中重播,確保您在開發過程中不會錯過重要資訊,如果需要完整的堆疊追蹤。

增強的性能分析

忽略的堆疊框架也被內建的瀏覽器性能分析工具識別。這使得分析您的應用程式更容易,讓您能準確定位程式碼中的慢速函式,而不受外部函式庫的干擾。

在 Edge Runtime 中的改進

使用 Edge runtime 時,錯誤現在在開發環境中一致顯示,確保無縫除錯。以前,記錄的錯誤僅包含訊息而不包含堆疊。

改進前後對比

終端機 改進前

Terminal
 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

終端機 改進後

Terminal
 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'
}

錯誤覆蓋層 改進前

Next.js 15.1 版本前的錯誤覆蓋層範例

錯誤覆蓋層 改進後

Next.js 15.1 版本後的錯誤覆蓋層範例

這些改進使錯誤更清晰直觀,讓您能將時間專注於構建應用程式,而非除錯。

我們也很高興地宣布,錯誤覆蓋層的重新設計 UI 將在未來的版本中推出。

after (穩定版)

after() API 在 Next.js 15 的第一個 RC 版本中引入後,現已穩定。

after() 提供了一種方式,可以在回應串流結束後執行如日誌記錄、分析和其他系統同步的任務,而不會阻擋主要回應。

主要變更

自引入以來,我們已穩定 after() 並解決了以下反饋:

  • 改進支援 自託管 Next.js 伺服器。
  • 錯誤修復 針對 after() 與其他 Next.js 功能互動的情境。
  • 增強擴展性,讓其他平台可以注入自己的 waitUntil() 原語來驅動 after()
  • 支援 runtime API,例如在 Server Actions 和 Route Handlers 中使用 cookies()headers()
app/layout.js
import { after } from 'next/server';
import { log } from '@/app/utils';
 
export default function Layout({ children }) {
  // 次要任務
  after(() => {
    log();
  });
 
  // 主要任務
  return <>{children}</>;
}

閱讀更多關於 after API 的資訊,並在文件中了解如何利用它。

forbiddenunauthorized (實驗性)

Next.js 15.1 包含兩個實驗性 API,forbidden()unauthorized(),基於社群反饋。

我們期待您的反饋 — 請在您的開發環境中試用,並在 討論串 中分享您的想法。

概述

如果您熟悉 App Router,您可能已經使用過 notFound() 來觸發 404 行為,並搭配可自訂的 not-found.tsx 檔案。在 15.1 版本中,我們將此方法擴展到授權錯誤:

forbidden() 觸發 403 錯誤,並透過 forbidden.tsx 自訂 UI。

unauthorized() 觸發 401 錯誤,並透過 unauthorized.tsx 自訂 UI。

須知:與 notFound() 錯誤一樣,如果錯誤在初始回應標頭已發送後觸發,狀態碼將為 200了解更多

啟用功能

由於此功能仍處於實驗階段,您需要在 next.config.ts 檔案中啟用它:

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()

您可以在 Server Actions、Server Components、Client Components 或 Route Handlers 中使用 forbidden()unauthorized()。以下是一個範例:

import { verifySession } from '@/app/lib/dal';
import { forbidden } from 'next/navigation';
 
export default async function AdminPage() {
  const session = await verifySession();
 
  // 檢查使用者是否具有 'admin' 角色
  if (session.role !== 'admin') {
    forbidden();
  }
 
  // 為授權使用者渲染管理頁面
  return <h1>管理頁面</h1>;
}

建立自訂錯誤頁面

要自訂錯誤頁面,請建立以下檔案:

app/forbidden.tsx
import Link from 'next/link';
 
export default function Forbidden() {
  return (
    <div>
      <h2>禁止訪問</h2>
      <p>您無權訪問此資源。</p>
      <Link href="/">返回首頁</Link>
    </div>
  );
}
app/unauthorized.tsx
import Link from 'next/link';
 
export default function Unauthorized() {
  return (
    <div>
      <h2>未授權</h2>
      <p>請登入以訪問此頁面。</p>
      <Link href="/login">前往登入</Link>
    </div>
  );
}

我們要感謝 Clerk 透過 PR 提出此功能並協助我們原型設計 API。在我們於 15.2 版本中穩定此功能之前,我們計劃為 API 添加更多功能和改進,以支援更廣泛的使用案例。

閱讀 unauthorizedforbidden API 的文件以獲取更多詳細資訊。

其他變更

  • [功能]create-next-app 中使用 ESLint 9 (PR)
  • [功能] 將最大快取標籤數增加至 128 (PR)
  • [功能] 新增選項以停用實驗性 CssChunkingPlugin (PR)
  • [功能] 新增實驗性 CSS 內聯支援 (PR)
  • [改進] 靜默 Sass legacy-js-api 警告 (PR)
  • [改進] 修正使用重寫時未處理的拒絕 (PR)
  • [改進] 確保當 webpack worker 失敗時父進程退出 (PR)
  • [改進] 修正 catch-all 路由上的路由攔截 (PR)
  • [改進] 修正請求去重複中的回應克隆問題 (PR)
  • [改進] 修正多個根佈局間的 Server Action 重新導向 (PR)
  • [改進] 支援以字串形式提供 MDX 插件以相容 Turbopack (PR)

貢獻者

Next.js 是超過 3,000 名開發者共同努力的成果。此版本由以下人員帶給您:

特別感謝 @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 的協助!