跳至內容
返回網誌

2021 年 10 月 26 日,星期二

Next.js 12

由以下人員發佈

如我們在Next.js 大會上所宣布的,Next.js 12 是我們有史以來最大發布

立即透過執行 npm i next@latest 更新。

使用 Rust 編譯器進行更快的建置與快速重新整理

我們希望讓每個 Next.js 應用程式都能更快地建置成可運用在生產環境中,並在本地端開發環境中獲得即時回饋。Next.js 12 內建了全新的 Rust 編譯器,它能對原生編譯進行最佳化。

我們的 Rust 編譯器是以 SWC 為建構基礎,這是個供下一代快速建構工具使用的開放平台。我們透過此編譯器最佳化了組合和編譯動作,讓本地端快速重新整理的時間加快了大約3 倍,而建置成可運用在生產環境中的速度則加快了大約5 倍。其他改進和功能包括

Results from using the new Rust compiler with large Next.js codebases.
使用新的 Rust 編譯器處理大型 Next.js 程式碼庫所得到的結果。
  • 進一步對大型程式碼庫進行速度提升:我們已使用世界上一些最大的 Next.js 程式碼庫來驗證 Rust 編譯器。
  • 改進效能可觀察性:Next.js 現在會在主控台輸出快速重新整理時間,包括處理客戶端和伺服器編譯所需的時間,以及編譯的模組和檔案數目。
  • 改善 webpack 基礎架構:我們已對 webpack 進行多項改進,包括最佳化快速重新整理並使按需條目更為可靠。

使用 Rust 進行編譯比 Babel 快 17 倍,且預設會在 Next.js 12 中啟用,用以取代 JavaScript 和 TypeScript 檔案的轉換。這表示我們必須將 Next.js 中的 Babel 轉換移植到 Rust 中,包括用於實作 styled-jsx 轉換的全新的 Rust CSS 解析器

新的 Rust 編譯器具有向下相容性。如果您有現有的 Babel 設定檔,您將會自動取消選擇。我們計畫盡快移植對諸如 styled-componentsemotionrelay 等熱門函式庫的解析功能。如果您正在使用自訂的 Babel 設定,請分享您的設定檔

您也可以選擇使用 Rust 編譯器進行縮小化處理。這比 Terser 快 7 倍。在對多年來的基礎架構進行徹底驗證前,縮小化處理是選擇性的功能。

next.config.js
module.exports = {
  swcMinify: true,
};

除了雇用 SWC 創建者 DongYoon Kang 以及 Maia TeegardenParcel 的貢獻者)之外,我們正在繼續投資 Rust 生態系統。如果您有與 Rust 合作的經驗,請應徵加入我們的團隊

如需更多資訊,觀看我們的 Next.js Conf. 示範

推出中間層

中間層讓您可以使用程式碼,而不是設定檔。這讓您在 Next.js 中有完全的彈性,因為您可以在請求完成之前執行程式碼。根據使用者的內部請求,您可以透過重寫、重新導向、新增標頭,甚至串流 HTML 來修改回應。

Middleware gives you complete flexibility inside Next.js.
中間層在 Next.js 中讓您有完全的彈性。

中間層可以用於任何與多個頁面共享邏輯的事情,包括

中間件使用一個嚴格的運行時,支援標準的網路 API,例如fetch。這使用 next start 立即運作,也適用於 Vercel 這種使用 邊緣中間件 的邊緣平台。

若要於 Next.js 中使用中間件,您可以建立一個檔案 pages/_middleware.js。在此範例中,我們使用標準網路 API 回應 (MDN)

pages/_middleware.js
export function middleware(req, ev) {
  return new Response('Hello, world!');
}

如需更多資訊,觀賞我們的 Next.js Conf 示範查看說明文件

準備迎接 React 18

React 18 將新增以下功能:Suspense、更新的自動批次處理、startTransition 等 API 以及適用於伺服器端渲染的串流 API,並支援 React.lazy

我們與 Facebook 的 React 團隊緊密合作,在 React 18 朝向穩定版本前進時為 Next.js 做好準備。我們將在 Next.js 12 中的實驗性標幟內提供這些功能讓您即刻試用。

终端
npm install react@alpha react-dom@alpha

伺服器端串流

React 18 中同時進行的相關功能包括內建的伺服器端 Suspense 支援和 SSR 串流支援。這允許您使用 HTTP 串流伺服器端渲染頁面。這是 Next.js 12 中的實驗性功能,但一旦啟用,SSR 將使用與 Middleware 相同的嚴格執行時間。

若要啟用,請使用實驗性標幟 concurrentFeatures: true

next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
  },
};

React 伺服器元件

React 伺服器元件允許我們在伺服器上渲染所有內容,包括元件本身。這與您在伺服器上預先產生 HTML 的伺服器端渲染有根本上的不同。有了伺服器元件,不再需要使用任何客戶端 JavaScript,能讓頁面渲染更快。這改善了您應用程式的使用者體驗,將伺服器端渲染的優點與客戶端互動性相結合。

next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
    serverComponents: true,
  },
};

Next.js 現在讓您能夠在元件層級進行資料擷取,而且所有這些都是以 JSX 表示。透過使用 React 伺服器元件,我們可以簡化事情。不再需要使用像是 getServerSidePropsgetStaticProps 之類的特殊函式。這符合 React Hook 將資料擷取與元件配置於同一處的模式。

您可以將任何 Next.js 頁面重新命名為 .server.js 以建立伺服器元件,並直接在伺服器元件內匯入客戶端元件。這些客戶端元件會自動建立並具備互動性,因此您可以新增類似讚數的功能。

我們目前正致力於在 Next.js 中實作伺服器端 Suspense、選擇性自動建立和串流渲染,並將在未來的部落格貼文中分享我們的進度。

特別感謝我們的合作者 Kara EricksonGerald MonacoGoogle Aurora 團隊中針對 React 18 和伺服器元件所做的工作。

如需更多資訊,請觀看我們的示範 來自 Next.js Conf 並 查看文件

ES 模組支援和 URL 匯入

ES 模組為 JavaScript 帶來了正式的標準化模組系統。它們受到所有主要瀏覽器和 Node.js 的支援。

這個標準透過啟用更小的封包大小和 JavaScript 捆綁程式,推進了網路生態系統的發展,最終帶來更好的使用者體驗。隨著 JavaScript 生態系統從 Common JS(舊標準)轉移到 ES 模組,我們致力於協助開發人員逐步採用這些改進,而不會造成不必要的破壞性變更。

Next.js 11.1 開始,我們增加了 ES 模組 的實驗性支援,優先於 CommonJS 模組。在 Next.js 12 中,這是目前的預設值。還是有支援僅提供 CommonJS 的 NPM 模組匯入。

網址匯入

Next.js 12 包含透過網址匯入 ES 模組的實驗支援,不需要安裝或分開的建置步驟。

網址匯入讓你可以透過網址直接使用任何套件。這使得 Next.js 能夠處理遠端 HTTP(S) 資源,就像處理本機相依項一樣。

如果偵測到網址匯入,Next.js 會產生一個 next.lock 檔案來追蹤遠端資源。網址匯入會暫存到本機,以確保你仍能離線工作。Next.js 支援用戶端和伺服器端的 URL 匯入。

若要啟用,請在 next.config.js 中新增已允許的 URL 字首

next.config.js
module.exports = {
  experimental: {
    urlImports: ['https://cdn.skypack.dev'],
  },
};

然後,你便可以直接從網址匯入模組

import confetti from 'https://cdn.skypack.dev/canvas-confetti';

任何提供 ES 模組服務的 CDN 皆可使用,其中包含無程式碼和設計工具等,例如 Framer

更多資訊,觀看 Next.js 研討會的示範查看文件

Bot-Aware ISR 回退 漸進式靜態重新產生fallback: true 會在尚未生成的頁面第一次請求時呈現備用狀態,再呈現頁面內容。要阻止頁面載入(伺服器端呈現),需要使用fallback: 'blocking'

在 Next.js 12 中,網路爬子(例如搜尋機器人)會使用 fallback: true 自動伺服器端呈現 ISR 頁面,同時仍對非爬蟲使用者代理顯示備用狀態的先前行為。這可防止爬蟲對載入狀態編製索引。

使用 AVIF 讓圖片更小

內建的圖片最佳化 API 現在支援 AVIF 圖片,能讓圖片比 WebP 小 20%。

與 WebP 相比,AVIF 圖片的最佳化時間可能會更長,因此我們讓這項功能透過 next.config.js 中新的 images.formats 屬性能夠選擇加入。

next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
};

這份格式清單用於根據請求的 Accept 標頭,按需決定最佳化的圖片格式。由於 AVIF 排在第一,因此如果瀏覽器支援 AVIF,就會提供 AVIF。如果不支援,則如果瀏覽器支援 WebP,就會提供 WebP。如果不支援這兩種格式,則會提供原始的圖片格式。

輸出檔案追蹤

在 Next.js 8 中,我們推出了 target 選項。透過利用 webpack 在建置期間將所有依賴項捆綁起來,這個選項可以輸出 Next.js 頁面作為獨立的 JavaScript 檔案。很快我們就發現這不是理想的作法,於是創造了 @vercel/nft@vercel/nft 已在 Vercel 平台的所有部署上使用了 2 年以上。

現在,我們將這些改進預設直接導入 Next.js 框架,適用於所有部署平台,提供比 target 選項大幅進步的方式。

Next.js 12 會自動使用 @vercel/nft 追蹤每個頁面和 API 路徑所需要的檔案,並在 next build 輸出旁邊輸出這些追蹤結果,讓整合器可以利用 Next.js 自動提供的追蹤資訊。

這些變更也優化了應用程式的部署,透過 next start 使用 Dockers 等工具。透過使用 @vercel/nft,我們將能夠讓 Next.js 輸出在未來獨立運行。不需要安裝相依性來執行應用程式,大幅降低 Docker 映像大小。

@vercel/nft 納入 Next.js 會取代 target 方法,因此在 Next.js 12 中,target 已被標示為不建議使用。請參閱文件取得更多資訊。

其他改善事項

  • 現在將 pages/_app.jspages/_document.js 新增到你的應用程式即可自動取代內建版本,無須重新啟動 Next.js CLI。
  • ESLint 整合現在支援在 next lint 中使用 --file 旗標進行單一檔案格式化
  • Next.js 12 現在支援設定自訂的 tsconfig.json 路徑。
  • 現在支援 next.config.mjs 以 ES 模組來撰寫組態。
  • 現在針對 getStaticProps 進行中的要求會去重。
  • 現在使用共用工作者池來檢查靜態頁面。
  • 熱刷新現在使用 WebSocket 連線,而非 EventSource 連線。

重大變更

  • Next.js 11 中將 webpack 5 設為預設後,我們現在已正式移除 webpack 4。我們已與社群緊密合作,以確保順利過渡到 webpack 5。
  • next.config.js 中的 target 不再需要。
  • next/image 現在使用 span 作為包裝元素,而非 div
  • 已將最低 Node.js 版本從 12.0.0 升級至 12.22.0,這是 Node.js 第一個支援原生 ES 模組的版本。

如需了解更多資訊,請參閱升級指南

社群