Back返回部落格

Next.js 9.4 版本發布

Next.js 9.4 引入了 React Fast Refresh、增量靜態再生 (Incremental Static Regeneration)、 新增環境變數支援、內建 Fetch 等多項功能!

我們很高興今天推出 Next.js 9.4,主要功能包括:

Fast Refresh

Fast Refresh 是一種新的熱重載體驗,可即時反饋您對 React 組件的編輯。現在,Next.js 9.4 或更高版本的所有專案 預設啟用 此功能。

熱重載 已存在很長時間,但 歷史上一直 過於脆弱,無法預設在工作流程中啟用。因此,Next.js 之前實現了一種粗略的熱重載形式,會重置整個應用程式的狀態。

舊的熱重載實現對編譯或運行時錯誤不具彈性,如果您在編輯 CSS 或 JavaScript 時出現拼寫錯誤,它會完全重新載入您的應用程式。這不是最佳選擇,並且會打斷您的思路。

Fast Refresh 深度整合到 React 本身(通過 React Refresh),使 Next.js 能夠對 React 組件樹執行精確的預測性更新。

這意味著 Next.js 只會更新您編輯的文件中的代碼,並且只重新渲染該組件,而不會丟失組件狀態。這包括樣式(內聯、CSS-in-JS 或 CSS/Sass Modules)、標記、事件處理程序和效果(通過 useEffect)。

一個包含編譯和運行時錯誤(快速恢復)以及保留狀態的編輯會話。

作為此體驗的一部分,我們完全重新設計了錯誤覆蓋層,使其更有幫助,並使您的應用程式對拼寫錯誤或運行時錯誤更具彈性。這包括但不限於:

  • 準確的錯誤位置,解析為您代碼的 原始行和列,在編譯之前
  • 上下文相關的 原始碼片段,具有 點擊在編輯器中打開 的能力
  • 修復語法錯誤後 恢復開發會話不丟失應用程式狀態
  • 修復錯誤時 自動解除 未處理的運行時錯誤

我們要感謝 Dan Abramov 在實現此功能方面的寶貴貢獻和協助。

增量靜態再生 (beta)

Next.js 在 9.3 版本中引入了靜態網站生成方法,目標明確:我們應該獲得 靜態的好處(始終快速、始終在線、全球分發),同時對動態數據提供出色的支援,這是 Next.js 的優勢所在。

為了兼顧兩者的優點,Next.js 支援 增量靜態生成,在您已經建構網站後更新靜態內容。例如,在 9.3 版本中,我們引入了 getStaticPaths 中的 fallback: true 選項,允許您在運行時添加 新頁面

我們最近 整理了一個範例 展示 Next.js 如何以這種方式靜態預渲染無限數量的頁面。

今天,我們還推出了 增量靜態再生 (beta),這是一種 更新現有頁面 的機制,通過在流量到來時在後台重新渲染它們。受 stale-while-revalidate 啟發,這確保流量不間斷地提供服務,始終靜態,並且新建構的頁面僅在生成完成後推送。

pages/blog/[slug].js
export async function getStaticProps() {
  return {
    props: await getDataFromCMS(),
    // 我們將嘗試重新生成頁面:
    // - 當請求到來時
    // - 最多每秒一次
    unstable_revalidate: 1,
  };
}

與 SSR 不同,增量靜態再生確保您保留靜態的優勢:

  • 沒有延遲峰值。頁面始終快速提供。
  • 頁面永遠不會離線。如果後台頁面重新生成失敗,舊頁面保持不變。
  • 低數據庫和後端負載。頁面最多同時重新計算一次。

這兩種增量功能(添加頁面和懶惰更新它們)以及 預覽模式,已經完全支援 next startVercel 邊緣平台 開箱即用。

接下來,我們將制定一個補充 RFC,以解決兩種額外的增量靜態生成功能:

  • 同時重新生成和失效多個頁面(如您的博客索引和某篇博客文章)
  • 通過監聽事件(如 CMS webhooks)提前重新生成,而不是等待用戶流量

CMS 範例

在我們宣布 次世代靜態網站生成 之後,我們希望分享從 Headless CMS API 獲取內容並將其渲染為 Next.js HTML 的真實場景。

我們與世界上一些最佳 CMS 系統的創建者合作:ContentfulDatoCMSPrismicSanityTakeShape,還有更多在路上。

這些範例不僅可以立即使用,而且是 100% 開源並採用 MIT 許可證,並且結合了可用的最佳實踐:

DatoCMS 由於其內建的圖像優化支援而取得了無可挑剔的結果。

DatoCMS 由於其內建的圖像優化支援而取得了無可挑剔的結果。

我們還與 TinaCMS 合作,探索 CMS 的一個令人興奮的新方向:頁面內內容編輯查看他們的指南 了解如何為您的專案實現它。

新增環境變數支援

我們從使用 Next.js 的公司那裡得到的一個常見反饋是,不清楚環境變數何時被內聯到瀏覽器套件中,以及何時僅在 Node.js 環境中可用。

今天我們宣布兩項完全向後兼容的功能,將幫助簡化此過程。

首先,您現在可以在環境變數前添加 NEXT_PUBLIC_ 前綴,將其暴露給瀏覽器。當使用該環境變數時,它將被內聯到瀏覽器 JavaScript 套件中。

您不再需要添加 next.config.js 並添加 env 鍵來暴露這些變數。

pages/index.js
// 環境變數將暴露給瀏覽器
console.log('我的應用程式版本', process.env.NEXT_PUBLIC_VERSION);
 
export default function HomePage() {
  return <h1>Hello World</h1>;
}

第二個變化是 Next.js 現在預設支援 .env 加載。允許您輕鬆定義開發和生產環境變數。

您可以在 環境變數文檔 中閱讀更多關於 .env 加載的信息。

這些新功能將通過以下約定簡化環境變數的使用:

  • 環境變數預設僅在 Node.js 環境中可用
  • NEXT_PUBLIC_ 為前綴的環境變數暴露給瀏覽器

改進的內建 Fetch 支援

Next.js 9.1.7 中,我們宣布在瀏覽器中對 fetch() API 進行 polyfill。今天,這種 polyfill 已擴展到 Node.js 環境。

實際上,您不再需要使用任何類型的服務器端 fetch polyfill(例如 isomorphic-unfetchnode-fetch),因為 Next.js 將在所有環境中自動提供 fetch()

例如,在使用 getStaticProps 時,它會在 Next.js 建置時執行:

pages/blog.js
export async function getStaticProps() {
  // 不再需要從 isomorphic-unfetch 導入 fetch
  const res = await fetch('https://.../posts');
  const posts = await res.json();
 
  return {
    props: {
      posts,
    },
  };
}
 
function Blog({ posts }) {
  // 渲染文章...
}
 
export default Blog;

整合式 Web Vitals 報告

上週,Google Chrome 團隊推出了 核心 Web Vitals。核心 Web Vitals 是在網絡上提供出色 UX 的關鍵質量信號,著名的 Lighthouse 報告 就是基於此構建的。

如果您希望您的網站或網絡應用程式盡可能快,跟踪這些指標非常有用,這也是 Next.js 的核心目標之一。

Chrome 團隊發布了一個 核心 Web Vitals Chrome 擴展,允許您作為開發人員獲得有關頁面性能的視覺反饋。

在構建生產網絡應用程式時,您還希望了解您的網站對訪問者和(潛在)客戶的表現如何。您甚至可能希望跟踪這些指標隨時間的改進或回歸,以查看您的更改是否對您的受眾產生了預期的影響。

為了幫助將核心 Web Vitals 報告給您的分析服務,我們 與 Google 合作 引入了一個名為 reportWebVitals 的新方法,可以從 pages/_app.js 導出:

pages/_app.js
// 將為每個需要報告的指標調用一次。
export function reportWebVitals(metric) {
  // 這些指標可以發送到任何分析服務
  console.log(metric);
}
 
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}
 
export default MyApp;

要將此方法與您的分析服務結合使用,請參考文檔中的 「將結果發送到分析」 部分。如果您想了解更多關於核心 Web Vitals 的信息,可以參考 web.dev/vitals

絕對導入與別名

如果您正在處理一個大型專案,您的一些 import 語句可能會受到 ../../../ 混亂的困擾:

import Button from '../../../../components/button';

在這種情況下,我們可能希望使用 絕對導入 而不是相對導入。假設 components 目錄存在於根目錄,我們可能希望 import 語句看起來像:

import Button from 'components/button';

我們很高興地宣布,Next.js 9.4 使得為 JavaScript 和 TypeScript 專案設置絕對導入變得非常簡單。您需要做的就是在 jsconfig.json(JS 專案)tsconfig.json(TS 專案) 中添加 baseUrl 配置。

jsconfig.json / tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "."
  }
}

這將允許從 .(根目錄)進行絕對導入。它還與 VSCode 和其他編輯器集成,支援代碼導航和其他編輯器功能。

注意: 如果您之前修改了 Webpack 模塊別名配置 以啟用絕對導入,現在可以刪除該配置。

此外,Next.js 9.4 還支援 paths 選項,允許您創建自定義模塊別名。例如,以下允許您使用 @/design-system 代替 components/design-system

jsconfig.json / tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/design-system/*": ["components/design-system/*"]
    }
  }
}

然後您可以像這樣使用您的別名:

// 導入 'components/design-system/button'
import Button from '@/design-system/button';

如果您指定 paths,則必須指定 baseUrl。您可以在 TypeScript 文檔 中了解更多關於 paths 選項的信息。

可配置的 Sass 支援

當內建 Sass 支援在 Next.js 9.3 中推出時,我們得到反饋,一部分用戶希望配置 sass 編譯器。例如配置 includePaths

現在可以通過在 next.config.js 中使用 sassOptions 鍵來實現:

next.config.js
const path = require('path');
 
module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')],
  },
};

改進的日誌輸出

我們重新設計了命令行輸出,使其更加一致,並減少輸出重複數據,如部署 URL、等待開發服務器啟動等。我們還更改了消息類型的間距,使其在消息之間保持一致,這意味著它們不再從一行跳到另一行。

在 9.4 之前版本運行 next dev

在 9.4 運行 next dev

社群

我們很高興看到 Next.js 的採用持續增長:

  • 我們已經有超過 1066 位獨立貢獻者。
  • 在 GitHub 上,該專案已經獲得了超過 48,000 次星標。

加入 GitHub Discussions 上的 Next.js 社群。Discussions 是一個社群空間,允許您與其他 Next.js 用戶聯繫並提問。

如果您正在使用 Next.js,請隨時 分享您的專案 URL 與社群。

我們感謝我們的社群以及所有幫助塑造此版本的外部反饋和貢獻。