2021年10月26日 星期二
Next.js 12
發布者如同我們在 Next.js Conf 上宣布的,Next.js 12 是我們有史以來最大的版本發布
- Rust 編譯器:~3 倍更快的快速刷新和 ~5 倍更快的建置速度
- 中介層 (beta):透過程式碼而非設定,在 Next.js 中實現完整彈性
- React 18 支援:現在支援原生 Next.js API 以及 Suspense
<Image />
AVIF 支援:選擇啟用可減少 20% 圖片大小- 機器人感知 ISR 回退:針對網路爬蟲優化的 SEO
- 原生 ES 模組支援:與標準化模組系統對齊
- URL 引入 (alpha):從任何 URL 引入套件,無需安裝
- React 伺服器元件 (alpha):立即試用,包含 SSR 串流
立即執行 npm i next@latest
來更新。
使用 Rust 編譯器實現更快的建置和快速刷新
我們希望讓每個 Next.js 應用程式在生產環境中建置更快,並在本地開發中獲得即時回饋。Next.js 12 包含一個全新的 Rust 編譯器,它利用了原生編譯。
我們的 Rust 編譯器建立在 SWC 之上,SWC 是下一代快速工具的開放平台。我們優化了捆綁和編譯,本地刷新速度快了約 3 倍,生產環境建置速度快了約 5 倍。其他改進和功能包括:

- 大型代碼庫的進一步速度提升: 我們已在全球一些最大的 Next.js 代碼庫中驗證了 Rust 編譯器。
- 提升效能的可觀察性: Next.js 現在會在主控台中輸出客戶端和伺服器編譯的快速刷新計時,包括編譯的模組和檔案數量。
- 底層 webpack 的改進: 我們對 webpack 進行了許多改進,包括優化快速刷新並使按需載入的入口點更可靠。
使用 Rust 進行編譯比 Babel 快 17 倍,並在 Next.js 12 中預設啟用,取代了轉換 JavaScript 和 TypeScript 檔案。這意味著我們必須將 Next.js 中的 Babel 轉換移植到 Rust,包括一個全新的 Rust CSS 解析器,用於實現 styled-jsx
轉換。
新的 Rust 編譯器向下相容。如果您有現有的 Babel 設定,您將會自動退出使用。我們計劃很快移植對 styled-components
、emotion
和 relay
等流行函式庫的解析。如果您正在使用自訂 Babel 設定,請分享您的設定。
您也可以選擇啟用 Rust 編譯器進行程式碼壓縮。這比 Terser 快 7 倍。程式碼壓縮功能目前為選擇性啟用,直到經過徹底驗證,因為它取代了多年的基礎架構。
module.exports = {
swcMinify: true,
};
除了聘請 SWC 的創建者 DongYoon Kang 和 Parcel 的貢獻者 Maia Teegarden 之外,我們將繼續投資 Rust 生態系統。如果您有使用 Rust 的經驗,請申請加入我們的團隊。
如需更多資訊,請觀看我們在 Next.js Conf 上的演示。
介紹中介層
中介層讓您可以使用程式碼而非設定。這為您在 Next.js 中提供了完整的彈性,因為您可以在請求完成之前執行程式碼。根據使用者傳入的請求,您可以透過重寫、重新導向、新增標頭,甚至串流 HTML 來修改回應。

中介層可用於任何為一組頁面共享邏輯的功能,包括
- 身份驗證
- 機器人保護
- 重新導向
- 重寫
- 功能標誌和 A/B 測試
- 進階 i18n 路由需求
- 以及更多!更多!
中介層使用嚴格的執行環境,支援標準 Web API,例如 fetch
。這在使用 next start
以及 Vercel 等 Edge 平台(使用 Edge 中介層)時皆可立即使用。
若要在 Next.js 中使用中介層,您可以建立一個檔案 pages/_middleware.js
。在此範例中,我們使用標準 Web API Response (MDN)
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,因為 React 18 正朝著穩定版本邁進。我們在 Next.js 12 中以實驗性標誌的形式提供這些功能,供您今天試用。
npm install react@alpha react-dom@alpha
伺服器端串流
React 18 中的並行功能包括對伺服器端 Suspense 和 SSR 串流支援的內建支援。這讓您可以使用 HTTP 串流來伺服器渲染頁面。這是 Next.js 12 中的實驗性功能,但一旦啟用,SSR 將使用與中介層相同的嚴格執行環境。
若要啟用,請使用實驗性標誌 concurrentFeatures: true
module.exports = {
experimental: {
concurrentFeatures: true,
},
};
React 伺服器元件
React 伺服器元件讓我們能夠在伺服器上渲染所有內容,包括元件本身。這與在伺服器上預先產生 HTML 的伺服器端渲染有根本的不同。使用伺服器元件,完全不需要客戶端 JavaScript,從而加快頁面渲染速度。這改善了您應用程式的使用者體驗,將伺服器渲染的最佳部分與客戶端互動性結合。
module.exports = {
experimental: {
concurrentFeatures: true,
serverComponents: true,
},
};
Next.js 現在讓您能夠在元件層級執行資料獲取,所有這些都以 JSX 表示。透過使用 React 伺服器元件,我們可以簡化事情。不再需要 getServerSideProps
或 getStaticProps
等特殊函式。這與 React Hooks 模型將資料獲取與您的元件放在一起的做法一致。
您可以將任何 Next.js 頁面重新命名為 .server.js
以建立伺服器元件,並在您的伺服器元件內部直接引入客戶端元件。這些客戶端元件將會水合並變得可互動,因此您可以新增諸如投票之類的功能。
我們目前正在 Next.js 中開發伺服器端 Suspense、選擇性水合和串流渲染,並將在未來的部落格文章中分享我們的進展。
特別感謝 Google Aurora 團隊的合作夥伴 Kara Erickson 和 Gerald Monaco 在 Google Aurora 團隊在 React 18 和伺服器元件方面的工作。
如需更多資訊,請觀看我們在 Next.js Conf 上的演示,並查看文件。
ES 模組支援和 URL 引入
ES 模組為 JavaScript 帶來了官方、標準化的模組系統。所有主流瀏覽器以及 Node.js 都支援它們。
此標準透過啟用更小的套件大小和 JavaScript 捆綁包來推動 Web 生態系統向前發展,最終帶來更好的使用者體驗。隨著 JavaScript 生態系統從 Common JS(舊標準)過渡到 ES 模組,我們致力於協助開發人員逐步採用這些改進,而不會造成不必要的重大變更。
從 Next.js 11.1 開始,我們新增了實驗性支援,優先考慮 ES 模組 而非 CommonJS 模組。在 Next.js 12 中,這現在是預設設定。仍然支援引入僅提供 CommonJS 的 NPM 模組。
URL 引入
Next.js 12 包含透過 URL 引入 ES 模組的實驗性支援,無需安裝或單獨的建置步驟。
URL 引入讓您可以直接透過 URL 使用任何套件。這使 Next.js 能夠像處理本地依賴項一樣處理遠端 HTTP(S) 資源。
如果偵測到 URL 引入,Next.js 將產生一個 next.lock
檔案來追蹤遠端資源。URL 引入會在本地快取,以確保您仍然可以離線工作。Next.js 支援客戶端和伺服器 URL 引入。
若要選擇啟用,請在 next.config.js
內新增允許的 URL 前綴
module.exports = {
experimental: {
urlImports: ['https://cdn.skypack.dev'],
},
};
然後,您可以直接從 URL 引入模組
import confetti from 'https://cdn.skypack.dev/canvas-confetti';
任何提供 ES 模組的 CDN 都可以使用,包括像 Framer 這樣的無程式碼和設計工具
欲瞭解更多資訊,請觀看我們在 Next.js Conf 的示範影片,並查閱文件。
機器人感知 ISR 回退
目前,使用 fallback: true
的 漸進式靜態重新產生 (ISR) 會在首次請求尚未產生的頁面時,先呈現回退狀態,然後才呈現頁面內容。若要阻止頁面載入(伺服器端渲染),您需要使用 fallback: 'blocking'
。
在 Next.js 12 中,網路爬蟲(例如搜尋引擎機器人) 將自動伺服器端渲染使用 fallback: true
的 ISR 頁面,同時仍對非爬蟲 User-Agent 提供先前的回退狀態行為。這可防止爬蟲索引載入狀態。
使用 AVIF 的更小圖片
內建的影像最佳化 API 現在支援 AVIF 圖片,相較於 WebP,可實現縮小 20% 的圖片大小。
相較於 WebP,AVIF 圖片可能需要更長的優化時間,因此我們將此功能設為選擇性加入,透過在 next.config.js
中使用新的 images.formats
屬性來啟用。
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
};
此格式列表用於根據請求的 Accept
header 隨需決定最佳化的圖片格式。由於 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 自動提供的追蹤資訊。
這些變更也最佳化了使用 Docker 等工具透過 next start
部署的應用程式。透過利用 @vercel/nft
,我們未來將能夠使 Next.js 輸出成為獨立的。運行應用程式將無需安裝任何依賴項,大幅縮減 Docker 映像檔大小。
將 @vercel/nft
引入 Next.js 取代了 target
方法,使 target
在 Next.js 12 中被棄用。查閱文件以瞭解更多資訊。
其他改進
- 現在將
pages/_app.js
或pages/_document.js
新增至您的應用程式,會自動取代內建版本,而無需重新啟動 Next.js CLI。 - ESLint 整合現在支援在
next lint
中使用--file
標誌進行單一檔案 linting。 - Next.js 12 現在支援設定自訂的
tsconfig.json
路徑。 - 現在支援使用
next.config.mjs
以 ES modules 格式編寫配置。 - 現在針對
getStaticProps
對進行中的請求進行重複資料刪除。 - 現在使用共享工作池執行靜態頁面檢查。
- Fast Refresh 現在使用 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
,這是第一個具有原生 ES modules 支援的 Node.js 版本。
若要瞭解更多資訊,請查看升級指南。
社群
五年前,我們向公眾發布了 Next.js。我們著手建構一個零配置的 React 框架,以簡化您的開發人員體驗。回顧過去,令人難以置信的是看到社群的成長,以及我們共同交付的成果。讓我們繼續努力。
Next.js 是超過 1,800 位獨立開發人員、Google 和 Facebook 等產業合作夥伴,以及我們核心團隊共同努力的成果。
本次發布是由以下人員貢獻:@ka2n, @housseindjirdeh, @rojserbest, @lobsterkatie, @thibautsabot, @javivelasco, @sokra, @rishabhpoddar, @kdy1, @huozhi, @georgegach, @ionut-botizan, @paul-creates, @TimBarley, @kimizuy, @devknoll, @matamatanot, @christianvuerings, @pgrodrigues, @mohamedbhy, @AlfonzAlfonz, @kara, @molebox, @angelopoole, @oste, @genetschneider, @jantimon, @kyliau, @mxschmitt, @PhattOZ, @finn-orsini, @kriswuollett, @harryheman, @GustavoEdinger, @AryanBeezadhur, @Blevs, @colevscode, @atcastle, @ijjk, @velocity23, @jonowu, @timneutkens, @whitep4nth3r, @micro-chipset, @TyMick, @padmaia, @arthurdenner, @vitorbal, @zNeb, @jacksonhardaker, @shuding, @kylemh, @Bundy-Mundi, @ctjlewis, @thien-do, @leerob, @Dev-CasperTheGhost, @janicklas-ralph, @rezathematic, @KonstHardy, @fracture91, @lorensr, @Sheraff, @HaNdTriX, @emilio, @oluan, @ddzieduch, @colinclerk, @x4th, @volcareso, @oiva, @sinchang, @scottrepreneur, @smakosh, @catnose99, @adrienharnay, @donsn, @andersonleite, @msp5382, @tim-hanssen, @appsplash99, @alexvilchis, @RobEasthope, @royal, @Perry-Olsson, @well-balanced, @mrmckeb, @buraksakalli, @espipj, @prateekbh, @AleksaC, @eungyeole, and @rgabs