跳至內容

多區域

範例

多區域是一種微前端架構方法,它將一個大型應用程式依網域劃分為較小的 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 之前的版本中,您可能還需要額外的重寫設定來處理靜態資源。在 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。對於每個由不同區域提供的路徑,您都需要新增一個重寫規則,以將該路徑傳送到其他區域的網域。例如:

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' && myFeaturFlag.isEnabled()) {
    return NextResponse.rewrite(`${rewriteDomain}${pathname}${search});
  }
}

區域間的連結

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

程式碼共用 單體儲存庫 (monorepo)中通常更方便,以便更輕鬆地共享程式碼。對於位於不同儲存庫中的區域,也可以使用公開或私有的 NPM 套件來共享程式碼。

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

對於在 Vercel 上運行的Next.js應用程式,您可以使用單體儲存庫 (monorepo),透過單一指令 `git push` 來部署所有受影響的區域。

伺服器動作

當您將伺服器動作與多區域搭配使用時,您必須明確允許使用者端來源,因為您的使用者端網域可能會提供多個應用程式。在您的 `next.config.js` 檔案中,新增以下幾行:

next.config.js
const nextConfig = {
  experimental: {
    serverActions: {
      allowedOrigins: ['your-production-domain.com'],
    },
  },
}

請參閱`serverActions.allowedOrigins`以取得更多資訊。