跳至內容
返回部落格

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 建置 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 現在支援使用 邊緣運行環境 進行伺服器渲染。

如上所述,Edge Runtime 比 Node.js 更輕量,可提供更快的啟動速度以降低延遲。與 React 18 搭配使用時,它可以為 Pages 啟用串流伺服器渲染。

Next.js 使用 Node.js 作為伺服器端渲染頁面的預設運行環境。從 12.2 版本開始,如果您使用的是 React 18,您可以選擇使用 Edge Runtime。

您可以在 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 水合作用和客戶端 JavaScript。

更多資訊,請參閱文件

遠端模式(實驗性)

next/image 現在支援實驗性的設定選項 remotePatterns,讓您在使用內建圖片最佳化 API 時,能以萬用字元指定遠端圖片。這允許比現有的 images.domains 設定更強大的匹配功能,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',
        },
      ],
    },
  },
};

更多資訊,請參閱文件

停用圖片最佳化

零設定圖片最佳化 API 會阻止使用 next export,因為它需要伺服器在圖片被請求時即時進行最佳化。到目前為止,以 next export 為目標的使用者需要設定 loader 來使用第三方圖片最佳化供應商,但如果沒有可用的供應商,就沒有明確的解決方案。從今天開始,next export 的使用者可以使用新的設定屬性停用所有 next/image 執行個體的圖片最佳化功能。

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

SWC 外掛程式(實驗性)

Next.js 編譯器使用 SWC 來轉換和壓縮您的 JavaScript 程式碼以用於生產環境。SWC 在 Next.js 12.0 中被引入,以提升本地開發和建置效能。

您現在可以新增外掛程式(以 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,否則可以將其移除。欲了解更多資訊,請參閱文件
  • Next.js 編譯器更好地支援 styled-components 轉換,允許自訂預設選項,包括 cssProp 選項。欲了解更多資訊,請參閱文件
  • 更好地支援 JavaScript ES 模組,以便可以正確地 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 – 這是 Next.js 自 2016 年推出以來最大的更新,包含:

  • 巢狀佈局:使用巢狀路由建置複雜的應用程式。
  • 專為伺服器元件設計:針對子樹導覽進行最佳化。
  • 改進的資料提取:在佈局中提取資料,同時避免瀑布流式載入。
  • 使用 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。