跳到內容

多區域

範例

多區域是一種微前端的方法,可將網域上大型應用程式分割成較小的 Next.js 應用程式,每個應用程式服務一組路徑。當頁面集合與應用程式中的其他頁面無關時,這非常有用。透過將這些頁面移至不同的區域(即不同的應用程式),您可以縮減每個應用程式的大小,從而縮短建置時間並移除僅在其中一個區域中才需要的程式碼。由於應用程式是解耦的,多區域也允許網域上的其他應用程式使用它們自己選擇的框架。

例如,假設您有以下一組頁面想要分割

  • /blog/* 用於所有部落格文章
  • /dashboard/* 用於使用者登入儀表板後的所有頁面
  • /* 用於網站其餘未被其他區域涵蓋的部分

透過多區域支援,您可以建立三個應用程式,它們都在同一個網域上提供服務,並且對使用者看起來相同,但您可以獨立開發和部署每個應用程式。

Three zones: A, B, C. Showing a hard navigation between routes from different zones, and soft navigations between routes within the same zone.

在同一個區域中瀏覽頁面將執行軟導航,這是一種不需要重新載入頁面的導航。例如,在此圖表中,從 / 導航到 /products 將會是軟導航。

從一個區域中的頁面導航到另一個區域中的頁面,例如從 //dashboard,將執行硬導航,卸載目前頁面的資源並載入新頁面的資源。經常一起訪問的頁面應位於同一個區域中,以避免硬導航。

如何定義區域

區域是一個正常的 Next.js 應用程式,您還可以在其中設定 assetPrefix,以避免與其他區域中的頁面和靜態檔案衝突。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  assetPrefix: '/blog-static',
}

Next.js 資源,例如 JavaScript 和 CSS,將以 assetPrefix 為前綴,以確保它們不會與來自其他區域的資源衝突。這些資源將在每個區域的 /assetPrefix/_next/... 下提供服務。

預設應用程式處理未路由到另一個更特定區域的所有路徑,不需要 assetPrefix

在舊於 Next.js 15 的版本中,您可能還需要額外的 rewrite 來處理靜態資源。這在 Next.js 15 中不再必要。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  assetPrefix: '/blog-static',
  async rewrites() {
    return {
      beforeFiles: [
        {
          source: '/blog-static/_next/:path+',
          destination: '/_next/:path+',
        },
      ],
    }
  },
}

如何將請求路由到正確的區域

使用多區域設定,您需要將路徑路由到正確的區域,因為它們由不同的應用程式提供服務。您可以使用任何 HTTP 代理來執行此操作,但其中一個 Next.js 應用程式也可以用於路由整個網域的請求。

若要使用 Next.js 應用程式路由到正確的區域,您可以使用 rewrites。對於由不同區域服務的每個路徑,您將新增一個 rewrite 規則,將該路徑傳送到另一個區域的網域。例如

next.config.js
async rewrites() {
    return [
        {
            source: '/blog',
            destination: `${process.env.BLOG_DOMAIN}/blog`,
        },
        {
            source: '/blog/:path+',
            destination: `${process.env.BLOG_DOMAIN}/blog/:path+`,
        }
    ];
}

destination 應該是由區域服務的 URL,包括協定和網域。這應該指向區域的生產網域,但也可以用於在本地開發中路由請求到 localhost

須知:URL 路徑對於一個區域應該是唯一的。例如,兩個區域嘗試服務 /blog 將會產生路由衝突。

使用中介軟體路由請求

建議透過 rewrites 路由請求,以盡量減少請求的延遲開銷,但是當需要動態決策來路由時,也可以使用中介軟體。例如,如果您正在使用功能標誌來決定路徑應該路由到哪裡,例如在遷移期間,您可以使用中介軟體。

middleware.js
export async function middleware(request) {
  const { pathname, search } = req.nextUrl;
  if (pathname === '/your-path' && myFeatureFlag.isEnabled()) {
    return NextResponse.rewrite(`${rewriteDomain}${pathname}${search});
  }
}

區域之間的連結

連結到不同區域中的路徑應使用 a 標籤,而不是 Next.js <Link> 元件。這是因為 Next.js 將嘗試預先提取並軟導航到 <Link> 元件中的任何相對路徑,這將無法跨區域運作。

程式碼共用

組成不同區域的 Next.js 應用程式可以位於任何儲存庫中。但是,通常將這些區域放在 monorepo 中更方便,以便更輕鬆地共用程式碼。對於位於不同儲存庫中的區域,也可以使用公開或私有的 NPM 套件共用程式碼。

由於不同區域中的頁面可能會在不同的時間發布,因此功能標誌對於在不同區域中統一啟用或停用功能很有用。

對於 Vercel 上的 Next.js 應用程式,您可以使用 monorepo 來使用單個 git push 部署所有受影響的區域。