我們非常興奮地宣布推出 Next.js 9.2,主要功能包括:
- 全域樣式表的內建 CSS 支援:應用程式現在可以直接導入
.css
檔案作為全域樣式表。 - 元件級樣式的內建 CSS 模組支援:透過
.module.css
命名約定,可以在應用程式中任何地方導入和使用局部作用域的 CSS。 - 改進的程式碼分割策略:Google Chrome 團隊深度優化了 Next.js 的程式碼分割策略,使客戶端套件 (bundle) 顯著縮小。此外,他們還最大化利用了 HTTP/2 來提升頁面載入速度,同時不影響 HTTP/1.1 的效能。
- 萬用動態路由:Next.js 的動態路由現在支援萬用路由,可滿足各種新用例,例如由 CMS 驅動的網站。
所有這些改進都是非破壞性且完全向後兼容的。您只需執行以下指令即可更新:
全域樣式表的內建 CSS 支援
Next.js 5 通過名為 next-css
的自訂插件引入了對導入 CSS 的支援,該插件擴展了 Next.js 的行為。
隨著時間推移,我們從 Next.js 的公司和用戶那裡獲得了持續的反饋,提到他們經常需要在應用程式中添加 next-css
。
此外,next-css
在導入 CSS 時有一些缺失的限制。例如,您可以在專案的每個檔案中導入 CSS 檔案,但這個導入的 CSS 檔案會成為整個應用程式的全域樣式。
為了改善開發者體驗並解決這些不一致性,我們開始著手將 CSS 導入支援預設整合到 Next.js 中。
我們很高興地宣布,Next.js 現在原生支援將樣式表導入您的應用程式。
要開始在應用程式中使用 CSS 導入,請在 pages/_app.js
中導入 CSS 檔案。
例如,考慮專案根目錄中名為 styles.css
的樣式表:
如果尚未存在,請建立一個 pages/_app.js
檔案。
然後,導入 styles.css
檔案:
由於樣式表本質上是全域的,它們必須在 自訂 <App>
元件 中導入。這對於避免全域樣式的類名和順序衝突是必要的。
在開發環境中,這種表達樣式表的方式允許您在編輯時自動更新頁面上的樣式。
在生產環境中,所有 CSS 檔案將自動串接成一個壓縮後的 .css
檔案。這個 CSS 檔案將通過 <link>
標籤載入,並自動注入到 Next.js 生成的預設 HTML 標記中。
這個新功能完全向後兼容。如果您正在使用 @zeit/next-css
或其他 CSS 相關插件,該功能將被禁用以避免衝突。
如果您目前正在使用 @zeit/next-css
,我們建議從您的 next.config.js
和 package.json
中移除該插件,從而升級後使用內建的 CSS 支援。
元件級樣式的內建 CSS 模組支援
Next.js 現在支援使用 [name].module.css
檔案命名約定的 CSS 模組。
與 Next.js 5 中使用 next-css
提供的支援不同,全域 CSS 和 CSS 模組現在可以 共存 — next-css
要求應用程式中所有的 .css
檔案都作為全域或局部處理,但不能同時兩者。
CSS 模組通過自動建立唯一的類名來局部作用域 CSS。這允許您在不同的檔案中使用相同的 CSS 類名,而不用擔心衝突。
這種行為使 CSS 模組成為包含元件級 CSS 的理想方式。CSS 模組檔案 可以在應用程式的任何地方導入。
例如,考慮 components/
資料夾中的可重用 Button
元件:
首先,建立包含以下內容的 components/Button.module.css
:
然後,建立 components/Button.js
,導入並使用上述 CSS 檔案:
CSS 模組是一個 可選 功能,僅對具有 .module.css
副檔名的檔案啟用。常規的 <link>
樣式表 和 全域 CSS 檔案 仍然支援。
在生產環境中,所有 CSS 模組檔案將自動串接成 多個壓縮且程式碼分割後的 .css
檔案。這些 .css
檔案代表了應用程式中的熱門執行路徑,確保為您的應用程式繪製每個頁面載入的 CSS 量最小。
與上述相同,這個新功能完全向後兼容。如果您正在使用 @zeit/next-css
或其他 CSS 相關插件,該功能將被禁用以避免衝突。
如果您目前正在使用 @zeit/next-css
,我們建議從您的 next.config.js
和 package.json
中移除該插件,從而使用內建的 CSS 支援。
改進的程式碼分割策略
Next.js 9.2 之前的版本有一組固定的 JavaScript 套件 (bundles) 需要載入並使頁面互動:
- 頁面的 JavaScript 檔案
- 包含通用 JavaScript 的檔案
- Next.js 客戶端運行時套件
- Webpack 客戶端運行時套件
- 動態導入(使用
next/dynamic
時添加)
為了使頁面互動,所有這些套件都必須載入,因為它們彼此依賴以在瀏覽器中啟動 React。
由於所有這些套件都是應用程式變得互動所必需的,因此它們必須盡可能優化。實際上,這意味著不要從應用程式的其他部分過度下載程式碼。
因此,Next.js 使用了一個 commons
套件,其中包含頁面之間的通用 JavaScript。舊的套件分割策略生成 commons
的計算是一種使用率啟發式方法。如果一個模組在超過 50% 的頁面中使用,它將被標記為通用模組。否則,它將被打包到頁面的 JavaScript 檔案中。
然而,應用程式可以包含許多不同類型的頁面。例如,行銷頁面、部落格和儀表板。如果行銷頁面的數量比其他頁面類型多得多,則通用計算將導致優化主要集中在行銷頁面上。
我們的目標是優化單一應用程式中的所有頁面類型。
Alex Castle 提出了一種新的分塊方法(建立獨立的 JavaScript 檔案),允許在涉及多種頁面類型時進行優化的通用分塊。
今天,我們很高興地宣布這種新的分塊行為在 Next.js 9.2 中預設啟用。我們要深深感謝 Google Chrome 團隊 和 Alex Castle 貢獻了這一變更。這一變更反映了數週的研究、實驗室測試、實際測試和實施的累積努力。
新的分塊實現利用 HTTP/2 來傳遞更多數量的小型分塊。
在新的啟發式方法下,分塊為:
- 每個頁面的最小分塊。
- 包含 React、ReactDOM、React 的 Scheduler 等的框架分塊。
- 任何大於 160kb(預壓縮/最小化前)的
node_module
依賴的函式庫分塊。 - 用於所有頁面之間共用程式碼的通用分塊。
- 盡可能多的共用分塊(由 2 個或更多頁面使用),優化整體應用程式大小和初始載入速度。
- Next.js 的客戶端運行時。
- Webpack 運行時。
讓我們看看這在實際應用程式中的意義:
早期採用的行業合作夥伴 Barnebys® 看到整體應用程式大小減少了 23%。
此外,他們最大的 JS 套件減少了 30% — 從 605kB 減少到 425kB — 無需任何程式碼變更。
另一個行業合作夥伴 SumUp® 看到他們最大的 JS 套件減少了 70% — 從 395kB 減少到 122kB — 無需任何程式碼變更。
最大的 JavaScript 套件
之前 | 之後 | 差異 | |
---|---|---|---|
Barnebys | 605kB | 425kB | 30% 更小 |
SumUp | 395kB | 122kB | 70% 更小 |
新的分塊行為不僅減少了您的整體和初始載入大小,還減少了連續的客戶端導航。Barnebys® 看到在六 (6) 次頁面導航後載入的 JavaScript 量減少了 87%:
多次客戶端轉換載入的 JavaScript
之前 | 之後 | 差異 | |
---|---|---|---|
Barnebys | 136kB | 18kB | 87% 更小 |
這種新行為完全向後兼容。升級到最新版本的 Next.js 是您利用此效能改進所需做的一切。
萬用動態路由
隨著 Next.js 9 的發布,我們引入了 動態路由分段,目標是在不需要自訂伺服器的情況下簡化 Next.js 中的動態分段。這一功能已被 Next.js 用戶廣泛採用。
但仍有一些情況是動態路由分段功能未涵蓋的。
其中之一是萬用路由。例如,將像 /post/**
這樣的萬用字元路由為頁面。這在您有一個由內容源(如 CMS)定義的嵌套結構時特別有用。
您現在可以使用 [...name]
語法建立萬用動態路由。
例如,pages/post/[...slug].js
將匹配 /post/a
、/post/a/b
、/post/a/b/c
等。
slug
將在路由查詢物件中作為單獨路徑部分的陣列提供。因此,對於路徑 /post/foo/bar
,查詢物件將是 { slug: ['foo', 'bar'] }
。
社群
我們非常高興看到 Next.js 的採用持續增長:
- 我們已經有超過 880 位獨立貢獻者。
- 在 GitHub 上,該專案已經被加星超過 44,000 次。
- 範例目錄 有超過 220 個範例。
Next.js 社群現在有超過 13,800 名成員。加入我們!
我們感謝我們的社群以及所有幫助塑造此版本的外部反饋和貢獻。