跳到內容
返回部落格

2020 年 5 月 11 日 星期一

Next.js 9.4

發布者

我們很高興在今天介紹 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 模組)、標記、事件處理器和效果(透過 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(),
    // we will attempt to re-generate the page:
    // - when a request comes in
    // - at most once every second
    unstable_revalidate: 1,
  };
}

與 SSR 不同,增量靜態重新產生確保您保留靜態的優點

  • 延遲時間沒有峰值。 頁面服務始終如一地快速。
  • 頁面永遠不會離線。 如果背景頁面重新產生失敗,則舊頁面保持不變。
  • 資料庫和後端負載低。 頁面最多同時重新計算一次。

增量功能(新增頁面和延遲更新頁面)以及 預覽模式,都已完全支援 next startVercel edge platform,開箱即用。

接下來,我們將致力於補充 RFC,以解決兩個額外的增量靜態產生功能

  • 一次重新產生和使多個頁面失效(例如您的部落格索引和特定的部落格文章)
  • 透過監聽事件(例如 CMS webhook)在使用者流量之前重新產生

CMS 範例

在我們發布 新一代靜態網站產生 的公告之後,我們想要分享從 Headless CMS API 擷取內容並將其渲染為 Next.js HTML 的真實世界情境。

我們與世界上一些最佳 CMS 系統的建立者合作:ContentfulDatoCMSPrismicSanityTakeShape,還有更多範例即將推出。

這些範例不僅隨時可用,而且 100% 開放原始碼並獲得 MIT 授權,而且它們還結合了可用的最佳實務

DatoCMS achieves impeccable results due to their built-in image optimization support.
DatoCMS 因為其內建的圖片最佳化支援而獲得完美的結果。

DatoCMS 因為其內建的圖片最佳化支援而獲得完美的結果

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

新的環境變數支援

我們從使用 Next.js 的公司收到的常見意見回饋是,不清楚環境變數何時內嵌到瀏覽器套件中,以及何時僅在 Node.js 環境中可用。

今天,我們宣布兩項完全向後相容的功能,將有助於簡化此流程。

首先,您現在可以為環境變數加上 NEXT_PUBLIC_ 前綴,以將環境變數公開給瀏覽器。 當使用該環境變數時,它將內嵌到瀏覽器 JavaScript 套件中。

您不再需要新增 next.config.js 並新增 env 鍵來公開這些變數。

pages/index.js
// The environment variable will be exposed to the browser
console.log('My Application Version', 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 中,我們宣布在瀏覽器中 polyfill fetch() API。 今天,這個 polyfill 也已擴展到 Node.js 環境。

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

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

pages/blog.js
export async function getStaticProps() {
  // fetch no longer needs to be imported from isomorphic-unfetch
  const res = await fetch('https://.../posts');
  const posts = await res.json();
 
  return {
    props: {
      posts,
    },
  };
}
 
function Blog({ posts }) {
  // Render posts...
}
 
export default Blog;

整合的 Web Vitals 報告

上週,Google Chrome 團隊推出了 Core Web Vitals。 Core Web Vitals 是在網路上提供出色 UX 的關鍵品質訊號,著名的 Lighthouse 報告 建構於其之上。

如果您希望您的網站或 Web 應用程式盡可能快速,那麼追蹤這些指標非常有用,而這也是 Next.js 的核心目標之一。

Chrome 團隊發布了 Core Web Vitals Chrome 擴充功能,讓身為開發人員的您可以獲得有關頁面效能的可視化回饋。

在建置生產 Web 應用程式時,您也想知道您的網站對訪客和(潛在)客戶的效能如何。 您甚至可能想要追蹤這些指標隨時間的改進或衰退,以查看您的變更是否對您的受眾產生了預期的影響。

為了協助將 Core Web Vitals 報告給您的分析服務,我們與 Google 合作,引入了一種稱為 reportWebVitals 的新方法,可以從 pages/_app.js 匯出

pages/_app.js
// Will be called once for every metric that has to be reported.
export function reportWebVitals(metric) {
  // These metrics can be sent to any analytics service
  console.log(metric);
}
 
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}
 
export default MyApp;

若要將此方法與您的分析服務結合使用,請參閱文件中的 「將結果傳送到分析」 章節。 如果您想了解有關 Core Web Vitals 的更多資訊,可以參考 web.dev/vitals

絕對路徑匯入和別名

如果您正在處理大型專案,您的一些 import 陳述式可能會受到 ../../../ 義大利麵式路徑的困擾

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

在這種情況下,我們可能想要使用絕對路徑匯入來取代相對路徑匯入。 假設 components 目錄存在於根目錄中,我們可能希望 import 陳述式看起來像這樣

import Button from 'components/button';

我們很高興宣布 Next.js 9.4 讓設定絕對路徑匯入對於 JavaScript 和 TypeScript 專案都變得非常簡單。 您只需要將 baseUrl 配置新增到 jsconfig.json(JS 專案)tsconfig.json(TS 專案)

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/*"]
    }
  }
}

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

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

如果您指定 paths,則必須指定 baseUrl。您可以前往 TypeScript 文件深入瞭解 paths 選項:TypeScript 文件中的路徑映射

可配置的 Sass 支援

當 Next.js 9.3 版本推出內建 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')],
  },
};

改進的日誌輸出

我們重新設計了命令列輸出,使其更一致,並減少重複資料的輸出,例如部署網址、等待開發伺服器啟動等等。我們也更改了訊息類型之間的間距,使其在訊息之間保持一致,意味著它們不再會在行與行之間跳動。

在 9.4 之前的版本上執行 next dev

在 9.4 版本上執行 next dev

社群

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

  • 我們已經有超過 1066 位獨立貢獻者。
  • 在 GitHub 上,此專案已被標註超過 48,000 次星號。

加入 Next.js 社群,請前往 GitHub Discussions。Discussions 是一個社群空間,您可以在這裡與其他 Next.js 使用者交流並提出問題。

如果您正在使用 Next.js,歡迎與社群分享您的專案網址

我們感謝我們的社群以及所有外部的回饋和貢獻,這些都幫助塑造了這個版本。