經過 26 個 canary 版本與 340 萬次下載後,我們很榮幸推出正式生產環境可用的 Next.js 7,主要特色包括:
- 開發體驗改進:啟動速度提升 57%,重新編譯速度提升 42%
- 更完善的錯誤報告,採用 react-error-overlay
- 升級編譯管線:採用 Webpack 4 與 Babel 7
- 標準化動態導入
- 靜態 CDN 支援
- 更小的初始 HTML 負載
- App 與 Pages 間的 SSR React Context 支援
最後,我們很興奮能在全新改版的 Nextjs.org 上分享這些消息
開發體驗改進
Next.js 的主要目標之一是在提供最佳生產環境效能的同時,也提供最佳的開發者體驗。此版本帶來了許多建置與除錯管線的重大改進
編譯速度
得益於 webpack 4、Babel 7 以及我們程式碼庫的諸多改進與優化,Next.js 現在在開發環境的啟動速度提升了 57%。
由於我們新增了增量編譯快取,您對程式碼的變更現在能_以快 40% 的速度建置_。
以下是我們收集的一些範例數據:
6.0 | 7.0 | 差異 | |
---|---|---|---|
啟動時間(基本應用程式) | 1947ms | 835ms | 57% 更快 |
程式碼變更(基本應用程式) | 304ms | 178ms | 42% 更快 |
作為額外好處,由於採用 webpackbar,您在開發與建置時現在能看到更好的即時回饋:
更完善的錯誤報告(React Error Overlay)
呈現準確且有幫助的錯誤訊息對於良好的開發與除錯體驗至關重要。在此之前,我們僅會呈現錯誤訊息及其堆疊追蹤。現在,我們利用 react-error-overlay
來增強堆疊追蹤,包含:
- 針對伺服器與客戶端錯誤的準確錯誤位置
- 原始碼高亮以提供上下文
- 完整的豐富堆疊追蹤
以下是我們錯誤報告改進前後的比較:
左為舊版錯誤覆蓋層,右為 react-error-overlay
作為額外好處,react-error-overlay
讓您只需點擊特定程式碼區塊就能輕鬆開啟文字編輯器。
Webpack 4
自首次發布以來,Next.js 一直使用 webpack 來打包您的程式碼並利用豐富的生態系統插件與擴充功能。我們很興奮地宣布 Next.js 現在採用最新的 webpack 4,帶來許多改進與錯誤修正。
其中包括:
- 支援
.mjs
原始檔 - 程式碼分割改進
- 更好的 tree-shaking(移除未使用程式碼)支援
另一個新功能是 WebAssembly 支援,Next.js 甚至能伺服器端渲染 WebAssembly,這裡有一個範例。
注意:此升級完全向下相容。然而,如果您透過 next.config.js 使用自訂 webpack loader 或插件,您可能需要升級它們。
CSS 導入
隨著 webpack 4 的推出,引入了一種從套件中提取 CSS 的新方法,稱為 mini-extract-css-plugin。
@zeit/next-css
、@zeit/next-less
、@zeit/next-sass
和 @zeit/next-stylus
現在都採用 mini-extract-css-plugin
。
這些 Next.js 插件的新版本解決了 20 個與 CSS 導入相關的現有問題;例如,現在支援在動態 import()
中導入 CSS:
一個重大改進是您不再需要在 pages/_document.js
中添加以下內容:
相反,Next.js 會自動注入 CSS 檔案。在生產環境中,Next.js 還會自動為 CSS URL 添加內容哈希值,以確保當有變更時,您的終端用戶永遠不會獲得過時的檔案版本,並能實現不可變的永久快取。
簡而言之,要在 Next.js 專案中支援導入 .css
檔案,您只需在 next.config.js
中註冊 withCSS 插件:
標準化動態導入
Next.js 從第 3 版開始就透過 next/dynamic
支援動態導入。
作為這項技術的早期採用者,我們必須編寫自己的解決方案來處理 import()
。
因此,Next.js 開始與 webpack 後來對其提供的支援產生分歧,並且缺少一些功能。
由於這個原因,Next.js 不支援 webpack 自那時起引入的一些 import()
功能。
例如,無法手動為某些檔案命名並將它們打包在一起:
另一個例子是使用 import()
而不將其包裝在 next/dynamic
模組中。
從 Next.js 7 開始,我們不再修改預設的 import()
行為。這意味著您開箱即用就能獲得完整的 import() 支援。
此變更也完全向下相容。使用動態元件仍然非常簡單:
此範例會為 my-component
建立一個新的 JavaScript 檔案,並僅在 <MyComponent />
被渲染時載入它。
最重要的是,如果它沒有被渲染,<script>
標籤不會包含在初始 HTML 文件負載中。
為了進一步簡化我們的程式碼庫並利用優秀的 React 生態系統,在 Next.js 7 中,next/dynamic
被重寫為在底層使用 react-loadable
(並進行了一些小修改)。這也為動態元件引入了兩個很棒的新功能:
- 使用
next/dynamic
的timeout
選項設定超時 - 使用
next/dynamic
的delay
選項設定載入元件延遲。此延遲允許您的loading
元件在渲染載入狀態前等待 x 時間,例如,當導入非常快時。
Babel 7
Next.js 6 在 Babel 7 仍處於測試階段時就引入了它。自那時起,Babel 7 的穩定版本已經發布,Next.js 7 現在使用此版本。
有關所有變更的完整列表,您可以參考 Babel 的發布說明。
一些主要功能包括:
- Typescript 支援,對於 Next.js 您可以使用
@zeit/next-typescript
- 支援片段語法
<>
- 支援
babel.config.js
overrides
屬性,僅對檔案或目錄的子集應用預設/插件
如果您的 Next.js 專案中沒有自訂 Babel 配置,則沒有破壞性變更。
然而,如果您確實有自訂 Babel 配置,則必須將相應的自訂插件/預設升級到最新版本。
如果您是從 Next.js 6 以下的版本升級,可以運行優秀的 babel-upgrade
工具。
除了升級到 Babel 7 之外,Next.js Babel 預設(next/babel
)現在預設在 NODE_ENV
設為 test
時將 modules
選項設為 commonjs
。
此配置選項通常是 Next.js 專案中建立自訂 .babelrc
的唯一原因:
在 Next.js 7 中,這變為:
此時,可以移除 .babelrc
,因為 Next.js 會在沒有 Babel 配置時自動使用 next/babel
。
更小的初始 HTML 負載
由於 Next.js 預渲染 HTML,它會將頁面包裝到預設結構中,包含 <html>
、<head>
、<body>
以及渲染頁面所需的 JavaScript 檔案。
此初始負載先前約為 1.62kB。在 Next.js 7 中,我們優化了初始 HTML 負載,現在為 1.5kB,減少了 7.4%,讓您的頁面更精簡。
6.0 | 7.0 | 差異 | |
---|---|---|---|
文件大小(伺服器端渲染) | 1.62kb | 1.50kb | 7.4% 更小 |
我們減少大小的主要方式包括:
- 移除了
__next-error
div - 內聯腳本被最小化,在未來版本中它們將被完全移除
- 當未使用時,編譯掉未使用的
__NEXT_DATA__
屬性,例如nextExport
和assetPrefix
屬性。
靜態 CDN 支援
在 Next.js 5 中,我們引入了 assetPrefix
支援,這是一種讓 Next.js 自動從特定位置(通常是 CDN)載入資源的方式。如果您的 CDN 支援代理,此選項效果很好,您請求的 URL 類似於
通常,CDN 會檢查其快取中是否有該檔案,否則直接從原始來源請求。
代理資源正是 Edge Network 的工作方式。
然而,有些解決方案需要將目錄直接預先上傳到 CDN。這樣做的問題是 Next.js 的 URL 結構與 .next
資料夾內的目錄結構不匹配。例如我們之前的範例
在 Next.js 7 中,我們已將 .next
的目錄結構更改為與 URL 結構匹配:
雖然我們推薦使用代理類型的 CDN,但這種新結構允許使用不同類型 CDN 的用戶將 .next
目錄上傳到他們的 CDN。
Styled JSX v3
我們很興奮地推出 styled-jsx 3,Next.js 中預設包含的 CSS-in-JS 解決方案現在已準備好支援 React Suspense。
一個經常不清楚的問題是如何為子元件設定樣式,如果該子元件不是當前元件範圍的一部分,例如,如果您包含了一個子元件,該子元件僅在父元件中使用時需要特定樣式:
上述程式碼嘗試選擇 p
標籤但不起作用,因為 styled-jsx 樣式僅限於當前元件,它們不會洩漏到子元件中。解決此問題的一種方法是使用 :global
方法,移除 p
標籤的前綴。然而,這會引入一個新問題,即樣式確實會洩漏到整個頁面。
在 styled-jsx 3 中,此問題已通過引入新的 API css.resolve
解決,它會為給定的 styled-jsx 字串生成 className
和 <style>
標籤(styles
屬性):
這個新 API 允許透明地將自訂樣式傳遞給子元件。
由於這是 styled-jsx 的一個主要版本,如果您使用 styles-jsx/css
,有一個破壞性變更可以改善套件大小。在 styled-jsx 2 中,我們會生成外部樣式的「scoped」和「global」版本,即使僅使用「scoped」版本,我們仍會包含這些外部樣式的「global」版本。
在 styled-jsx 3 中,全域樣式必須使用 css.global
而非 css
標記,以便 styled-jsx 可以優化套件大小。
有關所有變更,請參考發布說明。
App 與 Pages 間的 SSR React Context 支援
從 Next.js 7 開始,我們現在支援 pages/_app.js
與頁面元件之間的新 React context API。
先前在伺服器端無法在頁面之間使用 React context。原因是 webpack 保持內部模組快取而非使用 require.cache,我們編寫了一個自訂 webpack 插件來改變此行為,以在頁面之間共享模組實例。
這樣做不僅允許使用新的 React context,還減少了 Next.js 在頁面之間共享程式碼時的記憶體佔用。
6.0 | 7.0 | 差異 | |
---|---|---|---|
記憶體使用量 | 57.5MB | 48.1MB | -16% 記憶體 |
nextjs.org
與 Next.js 7 發布同時,我們推出了完全重新設計的 nextjs.org。
部落格
您目前正在閱讀的部落格文章已經是 nextjs.org 上新部落格部分的一部分。此部落格將成為 Next.js 相關通訊的新家,例如新版本公告。
全新的 nextjs.org
獲取靈感
隨著使用 Next.js 的應用程式數量持續增長,我們需要一個方式來集中展示這些優秀的作品。歡迎來到全新的 /showcase
頁面:
在 nextjs.org/showcase 獲取靈感
這個全新的展示平台讓我們能夠持續新增使用 Next.js 建構的應用程式。
誠邀您造訪 /showcase
獲取靈感,或提交您使用 Next.js 開發的應用程式!
社群
自首次發布以來,Next.js 已被廣泛應用於《財富》500 強企業的專案至個人部落格等各種場景。我們非常高興看到 Next.js 的採用率不斷攀升。
- 目前有超過 12,500 個公開索引的網域使用 Next.js
- 我們已有超過 500 位貢獻者提交至少 1 次提交 (commit)
- 在 GitHub 上,該專案已獲得超過 29,000 次星標 (star)
- 自首次發布以來,已提交近 2,200 個拉取請求 (pull request)
Next.js 社群擁有近 2,000 名成員。立即加入我們!