今天,我們興奮地宣布 Next.js 9.1 版本,新增對 src
和 public
目錄的支援。
本版本新增功能
src
目錄支援:現在可以將pages
目錄嵌套在src
資料夾下,支援更多樣化的應用程式結構。public
目錄支援:定義應用程式 URL 根目錄下的檔案(例如favicon.ico
)。
本版本預覽功能
- 內建 CSS 支援:即將支援導入全域 CSS,並提供開發時的熱重載功能,以及生產環境的最佳化、編譯和 polyfill 支援。
- 靜態錯誤頁面:靜態導出預期的錯誤頁面(如 404),提升可用性(CDN 快取)。
- Module / Nomodule:為使用現代瀏覽器的終端使用者提供更小的 JavaScript 套件。
- 改進的套件分割:減少傳輸給終端使用者的資料量,提升 TTI(互動時間)和頁面轉換速度。大型函式庫套件也將在多次部署間保持長期快取。
一如既往,我們確保所有這些改進都保持向後兼容。您只需執行以下指令即可更新:
如果您的應用程式使用的是 9 之前的 Next.js 版本,可以參考 升級指南 了解可能需要進行的變更。
自上次重大版本發布以來,我們很高興看到 TikTok、Hilton、Elastic、Realtor 和 JW Player 等公司採用 Next.js 上線產品。查看 展示頁面 了解更多!
src
目錄支援
Next.js 有一個特殊的 pages
目錄,其中每個檔案都會成為獨立的路由。遵循「約定優於配置」的原則,這個目錄必須位於 Next.js 應用程式的根目錄下。
在與使用 Next.js 的公司交流並檢查一些閉源程式碼庫後,我們發現開發者普遍希望將程式碼放在 src
目錄中,並將 pages
目錄也放在其中。
從 Next.js 9.1 開始,現在可以建立 src/pages
目錄,而不必在應用程式根目錄下建立 pages
目錄。
使用 src
目錄是可選的,這項功能主要滿足那些已有此標準的公司需求。
src 目錄中的 pages 資料夾
public
目錄支援
除了 pages
目錄,Next.js 還有另一個特殊目錄叫做 static
,其中的檔案會被映射到 /static
路由。
例如,static/my-image.png
會映射到 /static/my-image.png
。
這個約定自 Next.js 首次發布以來一直運作良好,沒有特別的問題。
然而,隨著時間推移,我們發現 /static
並不能滿足網頁應用程式的所有需求。例如,robots.txt
必須從網域根目錄提供。
從 Next.js 9.1 開始,我們引入了一個名為 public
的新目錄。
public
目錄中的任何檔案都會映射到網域的根目錄。
例如,public/robots.txt
會映射到 /robots.txt
。
由於 public
也涵蓋了 static
目錄的功能,我們決定棄用 static
目錄,轉而建議建立 public/static
資料夾以實現相同功能。
我們始終保持向後兼容,因此 static
目錄將繼續工作,但會顯示棄用訊息。
即將推出
以下功能目前處於實驗階段,將在最終實現準備就緒後發布。
內建 CSS 支援
目前,Next.js 內建了一個 CSS-in-JS 解決方案 styled-jsx,適用於為單個 React 元件添加樣式。
然而,在與企業交流中,我們發現普遍需要重用基於 CSS 的現有樣式或設計系統。
這通常意味著需要添加 next-css
插件來支援 CSS 導入。
我們發現約 50% 的 Next.js 使用者會在其應用程式中添加此插件。
由於這種廣泛使用,我們正在添加對 CSS 導入的內建支援,包括開發時的自動樣式重載,以及先前在 next-css
插件中無法實現的生產環境最佳化。
初始實現目前正在生產環境的 Next.js 應用程式中進行測試。
首先將引入全域 CSS 導入:
在全域 CSS 導入之後,我們將透過 .module.css
副檔名引入對 CSS 模組的支援:
這將為使用 CSS 導入提供顯著更好的開發者體驗。
您可以在 GitHub 上的 RFC 中閱讀更多關於這項工作的內容。
靜態錯誤頁面
Next.js 有一個在發生錯誤時渲染的特殊頁面,內部稱為 /_error
。使用者可以透過建立一個導出 React 元件的 pages/_error.js
檔案來自定義此頁面。
渲染的錯誤通常分為兩種情況:預期錯誤和意外錯誤。
預期錯誤例如 404
頁面。
意外錯誤例如在 getInitialProps
中拋出錯誤或在渲染 React 樹時發生錯誤,這會渲染 500
頁面。
我們計劃為預期錯誤添加 自動靜態最佳化,因為這些頁面通常不需要動態渲染。
如果使用者希望動態渲染這些頁面,可以選擇退出,但預設情況下 404
將是一個靜態頁面。這在使用 server
目標時減輕伺服器負載,在使用 serverless
目標時降低成本。
使頁面靜態化的另一個好處是,在使用 CDN 時可以自動快取。
與 Google Chrome 團隊的合作
如 Next.js 9 發布公告 中所述,Google Chrome 團隊正在投入資源改進 Next.js,並致力於多項工作,為所有 Next.js 應用程式帶來大規模效能提升。
要了解更多關於這次合作的資訊,您可以閱讀 Next.js 9 發布公告 並觀看 Nicole Sullivan 在 React Rally 上的演講。
Module / Nomodule
在 Next.js 中編寫程式碼時,您通常會使用「現代」JavaScript。您可以使用所有最新的穩定功能,Next.js 會透過使用 Babel 編譯程式碼來自動確保這些功能被轉換或填充 polyfill。
目前,許多這些 JavaScript 功能已在大多數瀏覽器中得到支援。然而,通常情況下(包括在 Next.js 中),程式碼會以單一 JavaScript 套件的形式提供,運行在您的應用程式支援的所有瀏覽器上。
對於 Next.js 來說,這意味著將現代 JavaScript 編譯為與 Internet Explorer 11 兼容的格式。
例如,目前 Next.js 必須為 async/await 語法提供 polyfill,因為程式碼可能在不相容 async/await 的瀏覽器中執行,這會導致錯誤。
為了避免在舊版瀏覽器中出錯,同時向支援新語法的瀏覽器發送現代 JavaScript,Next.js 將採用 module/nomodule 模式。module/nomodule 模式提供了一種可靠的機制,可以向現代瀏覽器提供現代 JavaScript,同時讓舊版瀏覽器回退到填充了 polyfill 的 ES5 程式碼。
這項新功能目前正在多個大型 Next.js 應用程式的生產環境中進行測試,以收集真實世界的數據。這些測試的結果看起來很有希望,更多關於此變更帶來的效能改進的細節將很快分享。
改進的套件分割
Next.js 目前有多個 JavaScript 套件需要加載以使頁面具有互動性。最值得注意的是:
- 頁面 JavaScript 套件。
- 包含共用 JavaScript 的檔案。
- Next.js 客戶端運行時套件。
- 動態導入(通常透過
next/dynamic
添加)。
為了確保頁面具有互動性,必須加載所有這些套件,因為它們都相互依賴,以便能在瀏覽器中啟動 React。
由於這些套件是啟動 React 所必需的,因此它們必須盡可能最佳化,並且不會從應用程式的其他部分過度下載程式碼。
為此,有一個 commons
套件,其中包含頁面之間的共用 JavaScript。當前生成 commons
的套件分割策略基於比例啟發式,如果一個模組在 50% 的頁面中使用,它將被標記為共用模組。
然而,應用程式可能由許多不同的部分組成。例如,行銷頁面、部落格和儀表板。如果行銷頁面的數量遠多於儀表板,共用計算將導致對行銷頁面更最佳化的結果。
我們的目標是在同一個應用程式中同時最佳化這兩者。
Alex Castle 定義了一個新的分塊層(創建獨立的 JavaScript 檔案),允許在多個檔案和涉及大量頁面時進行更最佳化的共用分塊。
與 module/nomodule 支援類似,改進的套件分割正在多個大型 Next.js 應用程式的生產環境中進行測試,以收集真實世界的數據。這些測試的結果以及更多關於此變更帶來的效能改進的細節將很快在另一篇部落格文章中分享。
社群
我們對即將推出的改進感到興奮,這些改進將提升所有 Next.js 應用程式的效能。
此外,Next.js 社群仍在擴展:
- 我們已有超過 800 位貢獻者提交了至少 1 次提交。
- 在 GitHub 上,該專案已獲得超過 41,350 次星標。
- 範例目錄 中有超過 210 個範例。
Next.js 社群現在有超過 11,250 名成員。加入我們!
我們感謝我們的社群以及所有外部反饋和貢獻,這些幫助塑造了此版本。