跳到內容
返回部落格

2022 年 12 月 22 日 星期四

Next.js 13.1

由以下作者發布

Next.js 13.1 包含了針對 pages/ (穩定版) 和 app/ (beta 版) 目錄的改進

立即執行以下指令來更新

終端機
npm i next@latest react@latest react-dom@latest eslint-config-next@latest

提升了 app 目錄的可靠性和支援度

在 Next.js 13 中,我們發布了新的 app 目錄 (beta 版)。這個新的路由和資料獲取系統可以與您現有的 pages 目錄一起逐步採用。

app 目錄提供了許多優點,包括增強的版面配置、組件的協同定位、測試和樣式、組件層級的資料獲取等等。感謝您的回饋和早期測試,我們對 app 目錄的可靠性進行了多項改進

  • 沒有版面配置 Div: 以前,當導航時,app 目錄會新增額外的 <div> 元素,以將版面配置捲動到視圖中。在 13.1 版本中,不再建立這些額外元素。捲動行為仍然保留。
  • TypeScript 外掛程式: 我們建立了一個新的 TypeScript 外掛程式,可針對頁面和版面配置設定選項提供建議、將文件直接帶入您的 IDE 中,並針對伺服器和用戶端組件提供有用的使用提示 (例如,防止在伺服器組件中使用 useState)。 深入瞭解
  • 可靠性改進: 我們修復了許多錯誤,包括改進的 CSS 模組支援、正確地為版面配置和頁面取消重複 cache()fetch()、記憶體洩漏等等。
  • 更少的用戶端 JavaScript: 現在,app 目錄包含的用戶端 JavaScript 比 pages 目錄少了 9.3kB。無論您向應用程式新增 1 個或 1000 個伺服器組件,這個基準都不會增加。React 執行環境暫時稍微大一點,增加的原因是 React 伺服器組件執行環境,它處理了 Next.js 以前處理的機制。我們正在努力進一步縮減這個大小。
pages/app/差異
總首次載入 JS基準-9.3kB12.1% 更小
Next.js 執行環境基準-12kB56.8% 更小
React 執行環境基準+2.7kB5.2% 更大

我們很高興能持續在 app 目錄的穩定性方面取得進展。app 目錄的 beta 文件 已經根據您的 回饋 進行了數百次更新。

內建模組轉譯 (穩定版)

您現在可以將來自本機套件 (如 monorepos) 或外部依賴項 (node_modules) 的依賴項標記為要轉譯和捆綁。這種內建支援取代了廣受歡迎的 next-transpile-modules 套件。

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@acme/ui', 'lodash-es'],
};
 
module.exports = nextConfig;

我們感謝 Pierre de la Martinière (@martpie) 在這個套件上的工作,以及他們協助確保內建支援滿足社群需求的協助。

導入解析以縮減套件大小

許多受歡迎的 npm 套件使用「barrel 檔案」來提供重新匯出其他模組的單一檔案。例如

@acme/ui/index.ts
export { default as Button } from './dist/Button';
export { default as Slider } from './dist/Slider';
export { default as Dropdown } from './dist/Dropdown';

這讓套件的使用者可以在單行中使用具名匯出

import { Button, Slider, Dropdown } from '@acme/ui';

雖然捆綁器了解這些 barrel 檔案,並且可以移除未使用的重新匯出 (稱為「dead code elimination」),但這個過程涉及剖析/編譯所有重新匯出的檔案。如果是發布的程式庫,有些 npm 套件隨附重新匯出數千個模組的 barrel 檔案,這會減慢編譯時間。這些程式庫建議使用 babel-plugin-transform-imports 來避免這個問題,但對於使用 SWC 的人來說,之前沒有任何支援。我們在 Next.js 中新增了一個新的 SWC 轉換,稱為 modularizeImports

這個新設定啟用了 SWC 轉換,它會根據定義的模式變更您的 import 陳述式。例如,上述使用三個組件的程式碼會自動轉換為使用直接匯入,而開發人員無需手動編寫此程式碼

// Before (with barrel file)
import { Button, Slider, Dropdown } from '@acme/ui';
 
// After (with modularized imports from plugin)
import Button from '@acme/ui/dist/Button';
import Slider from '@acme/ui/dist/Slider';
import Dropdown from '@acme/ui/dist/Dropdown';

可以使用 next.config.js 中的 modularizeImports 選項來進行此轉換

next.config.js
module.exports = {
  modularizeImports: {
    '@acme/ui': {
      transform: '@acme/ui/dist/{{member}}',
    },
  },
};

將此轉換與 @mui/icons-materiallodash 搭配使用,可以略過編譯未使用的檔案。深入瞭解

觀看示範 以查看實際運作情況。

適用於 edge 的輕量 Node.js 執行環境,現在 API 路由已穩定

Next.js 內部的 Edge Runtime 使用了 Node.js API 的嚴格子集 (例如 RequestResponse 等),這些 API 與 Vercel 等 Edge 運算平台或自架主機時相容。這些 API 可以在任何地方執行,包括在瀏覽器中,讓開發人員可以學習一次,並在任何地方編寫程式碼。

pages/api/hello.ts
// "experimental-" prefix is no longer needed
export const config = {
  runtime: 'edge',
};
 
export default function handler(req: Request) {
  return new Response('Hello World');
}

Next.js Middleware 已經預設使用這個輕量 edge runtime 以獲得更佳的效能。由於 Middleware 可以在應用程式中的每個請求之前執行,因此擁有輕量型的執行環境對於確保低延遲至關重要。在 Next.js 12.2 中,我們新增了選擇性地將這個執行環境用於 API 路由 的功能。

在 13.1 版本中,Next.js 內部的 Edge Runtime 對於 API 路由現在已穩定。當自架主機時,使用 Edge Runtime 的 Middleware 和 API 路由預設會作為單一區域工作負載在 next start 中執行。在 Vercel 上,Next.js Middleware 和 API 路由會使用 Vercel Edge Functions 全域部署,以獲得最低的可能延遲。Vercel Edge Functions 現在也已正式推出

Turbopack 的改進

在 Next.js 13 中發布 Turbopack alpha 版之後,我們一直專注於改進可靠性、新增對最受歡迎功能的支援,以及定義外掛程式和在其他框架中使用它的計畫。

自 Next.js 13.0.0 以來,Turbopack

  • 支援 PostCSS,包括 Tailwind CSS
  • 支援 next/image
  • 支援 @next/font (Google Fonts)
  • 支援從動態 import() 陳述式載入 CSS
  • 支援 CSS 原始碼地圖 (感謝 @ahabhgk貢獻)
  • 改進了 next dev 錯誤覆蓋中的錯誤處理
  • 改進了記憶體使用率
  • 改進了 CSS 模組支援
  • 改進了 HMR 更新的區塊演算法
  • 改進了 HMR 原始碼地圖的可靠性

我們感謝 Evan You 和 Vite 社群的回饋和貢獻,以確保 Turbopack 基準盡可能準確。我們與 Vite 團隊合作,驗證了最新的 Turbopack 基準,並對我們的測試方法進行了許多改進。

由於這次協作,我們現在使用更準確的指標,其中包括在 React 更新機制中花費的時間。我們能夠將 Turbopack 以及 webpack 上的 Next.js 13.1 的 React Fast Refresh 時間縮短 30 毫秒。我們還新增了一個使用 Vite 和 SWC 的新基準,與使用預設 Vite 和 Babel 相比,它顯示出更高的效能。檢視更新的基準 或閱讀關於測試方法

立即在 Next.js 13 中使用 next dev --turbo 試用 Turbopack alpha 版本。如果您有任何回饋意見,請在GitHub 討論區 中告訴我們。

Next.js 進階 Middleware

感謝您的回饋,我們正在讓 Next.js Middleware 比以往更強大。在 13.1 版本中,您現在可以從 Middleware 回傳回應,以及在請求中設定標頭。

這些 API 的改進為您提供了強大的新彈性,可以自訂 Next.js 路由生命週期的每個部分。不再需要 next.config.js 內的 experimental.allowMiddlewareResponseBody 設定選項。

您現在可以更輕鬆地在請求中設定標頭,以及直接回應,而無需 rewriteredirect

middleware.ts
import { NextResponse } from 'next/server';
 
export function middleware(request: Request) {
  // Check if a user has access...
  if (!isAuthorized(request)) {
    return NextResponse.json({ message: 'Unauthorized' });
  }
 
  // Add a new header, this will change the incoming request headers
  // that you can read in getServerSideProps and API routes
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-version', '13.1');
 
  return NextResponse.next({
    request: {
      // Apply new request headers
      headers: requestHeaders,
    },
  });
}

深入瞭解Next.js 進階 Middleware

其他改進

  • @next/font 現在支援在同一個字型宣告中新增多個字重和樣式。深入瞭解
  • next/dynamic 現在使用 React 原語 lazy()<Suspense>。不再需要先前的 suspense 選項。透過這些變更,next/dynamic 現在與 app 目錄相容。
  • create-next-app 已更新為新設計,現在預設包含 @next/font,用於自動自架主機字型,且版面配置偏移為零。使用 npx create-next-app@latest部署範本 來試用看看。
  • 我們對 App Directory Playground 進行了許多改進,它展示了 Next.js 13 中 app 目錄 (beta 版) 的一些最新功能和慣例。部署您自己的版本
  • 我們建立了一個高效能圖片庫範本,其中包括圖片預留位置、延遲載入、自動最佳化、鍵盤支援及更多功能。部署您自己的版本
  • 我們建立了一個資源,用於了解如何將大型開放原始碼 React 和 Express.js 應用程式 遷移到 Next.js,包括詳細的逐步解說和返回特定提交的連結。

社群

Next.js 是超過 2,400 位個別開發人員、Google 和 Meta 等產業合作夥伴以及我們 Vercel 核心團隊共同努力的成果。Next.js 每週的 npm 下載量超過 360 萬次,GitHub 星星數超過 97,900 顆,是建構 Web 最受歡迎的方式之一。

加入 GitHub DiscussionsRedditDiscord 社群。

本次發布由以下人員為您帶來

以及以下貢獻者: @aarnadlr、@aaronbrown-vercel、@aaronjy、@abayomi185、@ademilter、@adictonator、@adilansari、@adtc、@alantoa、@aleksa-codes、@alfred-mountfield、@alpha-xek、@andarist、@andykenward、@anujssstw、@artdevgame、@artechventure、@arturbien、@aziyatali、@bennettdams、@bertho-zero、@blue-devil1134、@bot08、@brkalow、@brvnonascimento、@chanceaclark、@chibicode、@chrisipanaque、@chunsch、@colinking、@craigwheeler、@ctjlewis、@cvolant、@danmindru、@davidnx、@delbaoliveira、@devvspaces、@dtinth、@ducanhgh、@duncanogle、@ethomson、@fantaasm、@feugy、@fomichroman、@gruz0、@haschikeks、@hughlilly、@idoob、@iiegor、@imranbarbhuiya、@ingovals、@inokawa、@ishaqibrahimbot、@ismaelrumzan、@jakemstar、@janicklas-ralph、@jaredpalmer、@jaykch、@jimcresswell、@joliss、@josephcsoti、@joshuaslate、@joulev、@jueungrace、@juliusmarminge、@karlhorky、@kikobeats、@kleintorres、@koenpunt、@koltong、@kosai106、@labyrinthitis、@lachlanjc、@laityned、@leerob、@leoortizz、@lorenzobloedow、@lucasassisrosa、@m7yue、@manovotny、@marcus-rise、@matthew-heath、@mattpr、@maxleiter、@maxproske、@meenie、@mmaaaaz、@mnajdova、@moetazaneta、@mrkldshv、@nathanhammond、@nekochantaiwan、@nfinished、@niedziolkamichal、@nocell、@notrab、@nuta、@nutlope、@obusk、@orionmiz、@peraltafederico、@reshmi-sriram、@reyrodrigez、@rightones、@rishabhpoddar、@saseungmin、@serkanbektas、@sferadev、@silvioprog、@sivtu、@soonoo、@sqve、@steven-tey、@sukkaw、@superbahbi、@teobler、@theevilhead、@thomasballinger、@timeyoutakeit、@valentinh、@ws-jm、@wxh06、@yasath、@yutsuten 和 @zekicaneksi。