跳到主要內容
返回部落格

2022 年 6 月 28 日 星期二

Next.js 12.2

作者:

我們正在為 Next.js 的未來奠定基礎,推出 12.2 版本

立即執行 npm i next@latest 來更新。

中介層 (穩定版)

我們很高興宣布中介層在 12.2 版本中已成為穩定版,並根據使用者的回饋改進了 API。

中介層允許您在請求完成之前執行程式碼。根據傳入的請求,您可以透過重新編寫、重新導向、新增標頭或設定 Cookie 來修改回應。

middleware.ts
import { NextRequest, NextResponse } from 'next/server';
 
// If the incoming request has the "beta" cookie
// then we'll rewrite the request to /beta
export function middleware(req: NextRequest) {
  const isInBeta = JSON.parse(req.cookies.get('beta') || 'false');
  req.nextUrl.pathname = isInBeta ? '/beta' : '/';
  return NextResponse.rewrite(req.nextUrl);
}
 
// Supports both a single value or an array of matches
export const config = {
  matcher: '/',
};

若要更新至中介層最新的 API 變更,請參閱移轉指南

Vercel 上免費試用中介層,或在使用 next start 自行託管時試用。

隨需應變增量靜態重新產生 (穩定版)

隨需應變增量靜態重新產生 (ISR) 讓您無需重新部署即可更新網站上的內容。這讓您在無頭 CMS 或商務平台中的資料變更時,可以輕鬆地立即更新網站。這是社群中最受歡迎的功能之一,我們很高興它現在已成為穩定版。

pages/api/revalidate.js
export default async function handler(req, res) {
  // Check for secret to confirm this is a valid request
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' });
  }
 
  try {
    await res.revalidate('/path-to-revalidate');
    return res.json({ revalidated: true });
  } catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send('Error revalidating');
  }
}

增量靜態重新產生適用於任何支援 Next.js Build API (next build) 的供應商。當部署到 Vercel時,當將頁面推送至邊緣時,隨需應變重新驗證會在約 300 毫秒內在全球範圍內傳播。

如需更多資訊,請查看文件,或查看我們的示範,以查看隨需應變重新驗證的實際運作情況。

邊緣 API 路由 (實驗性)

Next.js 現在也支援將 邊緣執行階段用於 API 路由。邊緣執行階段是比 Node.js 更輕量的執行階段,可為低延遲提供快速啟動。此外,邊緣 API 路由支援來自伺服器的串流回應。

您可以在 config 中設定 API 路由的執行階段,指定 nodejs (預設) 或 experimental-edge

pages/api/hello.js
import type { NextRequest } from 'next/server';
 
export default (req: NextRequest) => {
  return new Response(`Hello, from ${req.url} I'm now an Edge API Route!`);
};
 
export const config = {
  runtime: 'experimental-edge',
};

由於邊緣執行階段非常輕量,因此在容納快速啟動方面存在限制,例如,它不支援特定於 Node.js 的 API,如 fs。因此,API 路由的預設執行階段仍為 nodejs

如需更多資訊,請查看文件

邊緣伺服器端渲染 (實驗性)

Next.js 現在支援將 邊緣執行階段用於伺服器渲染。

如上所述,邊緣執行階段是比 Node.js 更輕量的執行階段,可為低延遲提供快速啟動。與 React 18 一起使用時,它可為頁面啟用串流伺服器端渲染。

Next.js 使用 Node.js 作為伺服器端渲染頁面的預設執行階段。從 12.2 版本開始,如果您使用 React 18,您可以選擇使用邊緣執行階段。

您可以在 next.config.js 中全域設定執行階段,指定 nodejsexperimental-edge

next.config.js
module.exports = {
  experimental: {
    runtime: 'experimental-edge',
  },
};

變更預設頁面執行階段會影響所有頁面,包括 SSR 串流伺服器組件功能。您也可以透過匯出 runtime 設定來覆寫每個頁面的此預設值

pages/index.js
export const config = {
  runtime: 'nodejs',
};
 
export default function Home() {}

您可以透過在執行階段查看 process.env.NEXT_RUNTIME 環境變數,以及在 webpack 編譯期間檢查 options.nextRuntime 變數來偵測您正在使用的執行階段。

如需更多資訊,請查看文件

next/image 的改進

next/future/image 組件 (實驗性)

我們聽取了您對目前 Image 組件的回饋,並很高興分享新的 next/image 的早期預覽版。這個經過改良的新圖片組件需要的用戶端 JavaScript 較少,並簡化了您設定圖片樣式的方式

  • 渲染單個 <img>,而沒有 <div><span> 包裝器
  • 新增對標準 style 屬性的支援
  • 移除 layoutobjectFitobjectPosition 屬性,改用 styleclassName
  • 移除 IntersectionObserver 實作,改用原生延遲載入
  • 移除 loader 設定,改用 loader 屬性
  • 注意:目前沒有 fill 模式,因此需要 widthheight 屬性

這改善了效能,因為原生 loading="lazy" 不需要等待 React hydration 和用戶端 JavaScript。

如需更多資訊,請查看文件

遠端模式 (實驗性)

next/image 現在支援實驗性設定選項 remotePatterns,讓您在使用內建 Image Optimization API 時,為遠端圖片指定萬用字元。這允許比現有的 images.domains 設定進行更強大的比對,該設定僅對網域名稱執行完全比對。

next.config.js
module.exports = {
  experimental: {
    images: {
      remotePatterns: [
        {
          // The `src` property hostname must end with `.example.com`,
          // otherwise this will respond with 400 Bad Request.
          protocol: 'https',
          hostname: '**.example.com',
        },
      ],
    },
  },
};

如需更多資訊,請查看文件

停用圖片最佳化

零設定 Image Optimization API 阻止使用 next export,因為它需要伺服器在圖片被請求時隨需應變地最佳化圖片。直到今天,以 next export 為目標的使用者需要設定 loader 以使用第三方 Image Optimization 供應商,但如果沒有可用的供應商,則沒有明確的解決方案。從今天開始,next export 使用者可以使用新的組態屬性,為 next/image 的所有實例停用 Image Optimization

next.config.js
module.exports = {
  experimental: {
    images: {
      unoptimized: true,
    },
  },
};

SWC 外掛程式 (實驗性)

Next.js 編譯器使用 SWC 來轉換和最小化您的 JavaScript 程式碼以用於生產環境。Next.js 12.0 中引入了 SWC,以改善本機開發和建置效能。

您現在可以新增外掛程式 (以 WebAssembly 撰寫) 以自訂編譯期間的 SWC 轉換行為

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      ['css-variable/swc', { displayName: true, basePath: __dirname }],
    ],
  },
};

如需更多資訊,請查看文件

React 18 支援改進

  • 改進了對 CSS-in-JS 程式庫 (如 styled-componentsemotion) 的支援,提供更順暢的升級體驗,且沒有重大變更。
  • AMP 和 HTML 後最佳化 (CSS、字型最佳化) 現在已獲得適當的支援。
  • next/head 現在支援 React 18。
  • Next.js 的路由宣告工具 (用於向螢幕閱讀器和其他輔助技術正確宣告頁面轉換) 現在支援 React 18。

其他改進

  • 支援 Next.js 編譯器中的 Emotion 轉換。現在支援 @emotion/babel-plugin 的大多數功能,除非您使用 importMap,否則可以移除它。如需更多資訊,請查看文件
  • 透過允許自訂預設選項 (包括 cssProp 選項),更好地支援 Next.js 編譯器中的 styled-components 轉換。如需更多資訊,請查看文件
  • 更好地支援 JavaScript ES Modules,因此可以正確地 import next/imagenext/link 等組件。
  • next/link 不再需要手動新增 <a> 作為子項。您現在可以選擇加入此行為,並以向後相容的方式進行。
  • 我們新增了實驗性支援,透過修改 browsersList 來僅發佈現代 JavaScript。您可以透過在 next.config.jsexperimental 選項中設定 browsersListForSwc: truelegacyBrowsers: false 來選擇加入此行為。
  • 新的 @swc/helpers 最佳化可防止跨套件重複,從而減少套件大小,在最小設定中減少約 2KB,在較大的應用程式中減少更多
  • 我們已大幅縮減 Next.js 的安裝大小。我們透過將我們的 monorepo 遷移到 pnpm 來實現這一點,這讓我們可以在建立我們使用的預編譯版本時移除重複的套件。這使得安裝大小減少了 14MB。
  • 在我們持續努力改進 Next.js 自行託管的過程中,我們正在將我們的實驗性 outputStandalone: true 設定穩定化為 output: 'standalone'。此設定僅包含必要檔案/資產,包括移除在建置的部署套件中安裝所有 node_modules 的需求,從而大幅縮減部署大小。可以在我們的 with-docker 範例中看到此設定的實際運作情況。

版面配置 RFC & 進階路由支援

如果您錯過了,上個月我們宣布了版面配置 RFC – 這是自 2016 年推出以來 Next.js 最大的更新,包括

  • 巢狀版面配置: 使用巢狀路由建置複雜的應用程式。
  • 專為伺服器組件設計: 針對子樹導航進行了最佳化。
  • 改進的資料擷取: 在版面配置中擷取,同時避免瀑布流。
  • 使用 React 18 功能: 串流、轉場和 Suspense。
  • 用戶端和伺服器路由: 以伺服器為中心的路由,具有類似 SPA 的行為。
  • 100% 可逐步採用:沒有重大變更,因此您可以逐步採用。
  • 進階路由慣例:離螢幕存放、即時轉場等等。

如需更多資訊,請查看 RFC提供回饋

感謝貢獻者

Next.js 是 超過 2,000 位個別開發人員、Google Chrome 和 Meta 等產業合作夥伴以及我們 Vercel 核心團隊共同努力的成果。

此版本是由以下人員貢獻:@huozhi、@ijjk、@kwonoj、@ViolanteCodes、@akrabdev、@timneutkens、@jpveilleux、@stigkj、@jgoping、@oof2win2、@Brooooooklyn、@CGamesPlay、@lfades、@molebox、@steven-tey、@SukkaW、@Kikobeats、@balazsorban44、@erikbrinkman、@therealmarzouq、@remcohaszing、@perkinsjr、@shuding、@hanneslund、@housseindjirdeh、@RobertKeyser、@styfle、@htunnicliff、@lukeshumard、@sagnik3、@pixelass、@JoshuaKGoldberg、@rishabhpoddar、@nguyenyou、@kdy1、@sidwebworks、@gnoff、@gaspar09、@feugy、@mfix-stripe、@javivelasco、@Chastrlove、@goncharov-vlad、@NaveenDA、@Firfi、@idkwhojamesis、@FLCN-16、@icyJoseph、@ElijahPepe、@elskwid、@irvile、@Munawwar、@ykolbin、@hulufei、@baruchadi、@imadatyatalah、@await-ovo、@menosprezzi、@gazs、@Exortions、@rubens-lopes、@woochul2、@stefee、@stmtk1、@jlarmstrongiv、@MaedahBatool、@jameshfisher、@fabienheureux、@TxHawks、@mattbrandlysonos、@iggyzap、@src200、@AkifumiSato、@hermanskurichin、@kamilogorek、@ben-xD、@dawsonbooth、@Josehower、@crutchcorn、@ericmatthys、@CharlesStover、@charlypoly、@apmatthews、@naingaungphyo、@alexandrutasica、@stefanprobst、@dc7290、@DilwoarH、@tommarshall、@stanhong、@leerob、@appsbytom、@sshyam-gupta、@saulloalmeida、@indicozy、@ArianHamdi、@Clariity、@sebastianbenz、@7iomka、@gr-qft、@Schniz、@dgagn、@sokra、@okbel、@tbvjaos510、@dmvjs、@PepijnSenders、@JohnPhamous、@kyliau、@eric-burel、@alabhyajindal、@jsjoeio、@vorcigernix、@clearlyTHUYDOAN、@splatterxl、@manovotny、@maxproske、@nvh95、@frankievalentine、@nuta、@bagpyp、@dfelsie、@qqpann、@atcastle、@jsimonrichard、@mass2527、@ekamkohli、@Yuddomack、@tonyspiro、@saurabhmehta1601、@banner4422、@falsepopsky、@jantimon、@henriqueholtz、@ilfa、@matteobruni、@ryscheng、@hoonoh、@ForsakenHarmony、@william-keller、@AleksaC、@Miikis、@zakiego、@radunemerenco、@AliYusuf95 和 @dominiksipowicz。