跳到內容
返回部落格

2024年5月23日 星期四

Next.js 15 RC

由以下作者發布

Next.js 15 候選發布版 (RC) 現已推出。這個早期版本讓您能在即將發布的穩定版本之前,測試最新的功能。

立即試用 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 規則,在深層次理解您的程式碼,使其能夠為您的程式碼新增自動最佳化。此編譯器透過 useMemouseCallback 等 API,減少開發人員必須進行的手動記憶化 (memoization) 數量,使程式碼更簡潔、更容易維護且更不易出錯。

在 Next.js 15 中,我們新增了對 React Compiler 的支援。

安裝 babel-plugin-react-compiler

終端機
npm install babel-plugin-react-compiler

然後,在 next.config.js 中新增 experimental.reactCompiler 選項

next.config.ts
const nextConfig = {
  experimental: {
    reactCompiler: true,
  },
};
 
module.exports = nextConfig;

您可以選擇性地將編譯器配置為以「opt-in」模式執行,如下所示

next.config.ts
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 錯誤訊息

Hydration error message in Next.js 14.1

Next.js 15 RC 已將其改善為

Hydration error message improved in Next.js 15 RC

快取更新

Next.js App Router 推出時,採用了帶有主觀判斷的預設快取設定。這些設定旨在預設提供效能最佳的選項,並在需要時能夠選擇退出。

根據您的意見回饋,我們重新評估了我們的 快取啟發法,以及它們如何與部分預先渲染 (PPR) 等專案以及使用 fetch 的第三方函式庫互動。

在 Next.js 15 中,我們正在變更 fetch 請求、GET Route Handlers 和 Client Router Cache 的預設快取行為,從預設快取變更為預設不快取。如果您想保留先前的行為,可以繼續選擇加入快取。

我們將在未來幾個月內繼續改善 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',以覆寫 Layout 或 Page 中的所有 fetch 請求,使其使用 force-cache,除非它們明確指定自己的 cache 選項

GET Route Handlers 不再預設快取

在 Next 14 中,除非 Route Handlers 使用動態函式或動態配置選項,否則使用 GET HTTP 方法的 Route Handlers 預設會快取。在 Next.js 15 中,GET 函式預設不會快取

您仍然可以使用靜態路由配置選項 (例如 export dynamic = 'force-static') 選擇加入快取。

特殊的 Route Handlers,例如 sitemap.tsopengraph-image.tsxicon.tsx,以及其他 metadata 檔案,預設仍為靜態,除非它們使用動態函式或動態配置選項。

Client Router Cache 不再預設快取 Page 組件

在 Next.js 14.2.0 中,我們引入了一個實驗性的 staleTimes 標記,以允許自訂配置 Router Cache

在 Next.js 15 中,此標記仍然可以存取,但我們正在變更預設行為,使 Page 區段的 staleTime0。這表示當您在應用程式中導航時,用戶端將始終反映 Page 組件 (在導航過程中變為活動狀態) 的最新資料。但是,仍有一些重要的行為保持不變

  • 共用版面配置資料不會從伺服器重新擷取,以繼續支援 部分渲染
  • 返回/前進導航仍將從快取還原,以確保瀏覽器可以還原捲動位置。
  • Loading.js 將保持快取 5 分鐘 (或 staleTimes.static 配置的值)。

您可以透過設定以下配置,選擇加入先前的 Client Router Cache 行為

next.config.ts
const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
    },
  },
};
 
module.exports = nextConfig;

部分預先渲染的逐步採用 (實驗性)

在 Next.js 14 中,我們 引入了部分預先渲染 (Partial Prerendering, PPR) - 這是一種最佳化,它結合了在同一頁面上的 靜態和動態渲染

Next.js 目前預設為靜態渲染,除非您使用 動態函式,例如 cookies()headers() 和未快取的資料請求。這些 API 會將整個路由選擇加入動態渲染。使用 PPR,您可以將任何動態 UI 包裝在 Suspense 邊界中。當新的請求進入時,Next.js 將立即提供靜態 HTML shell,然後在同一個 HTTP 請求中渲染和串流動態部分。

為了允許逐步採用,我們新增了 experimental_ppr 路由配置選項,用於將特定的 Layouts 和 Pages 選擇加入 PPR

app/page.jsx
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'

next.config.ts
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

next.config.ts
const nextConfig = {
  experimental: {
    after: true,
  },
};
 
module.exports = nextConfig;

然後,在伺服器組件、伺服器動作、Route Handlers 或 Middleware 中匯入函式。

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

New design for create-next-app in Next.js 15 RC

當執行 create-next-app 時,會出現一個新的提示,詢問您是否要為本地開發啟用 Turbopack (預設為 No)。

終端機
 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 和 Pages Router 之間的配置,我們正在引入一個新選項 bundlePagesRouterDependencies,以符合 App Router 的預設自動捆綁。然後,您可以視需要使用 serverExternalPackages 選擇退出特定的套件。

next.config.ts
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)
  • [重大變更] Caching: force-dynamic 現在會將 no-store 預設設為 fetch 快取 (PR)
  • [重大變更] Config: 預設啟用 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)
  • [改進] Config bundlePagesExternals 現已穩定,並重新命名為 bundlePagesRouterDependencies
  • [改進] Config serverComponentsExternalPackages 現已穩定,並重新命名為 serverExternalPackages
  • [改進] create-next-app: 新專案預設會忽略所有 .env 檔案 (PR)
  • [文件] 改善驗證文件 (PR)
  • [文件] @next/env 套件 (PR)

若要瞭解更多資訊,請查看升級指南

貢獻者

Next.js 是超過 3,000 位個人開發者、Google 和 Meta 等產業合作夥伴,以及 Vercel 核心團隊共同努力的成果。本次發行版本由以下團隊成員為您帶來:

非常感謝 @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 的協助!