多区域(Multi-Zones)是一种微前端方法,它将一个域上的大型应用拆分成更小的 Next.js 应用,每个应用负责一组路径。当页面集合与应用中的其他页面无关时,这种方法非常有用。通过将这些页面移到一个单独的区域(即一个独立的应用),您可以减小每个应用的大小,从而缩短构建时间并移除只在一个区域内才需要的代码。由于应用是解耦的,多区域架构还允许同一域上的其他应用使用它们自己选择的框架。
例如,假设您有以下页面集需要拆分:
/blog/* 用于所有博客文章/dashboard/* 用于用户登录到仪表盘后的所有页面/* 用于网站中未被其他区域覆盖的其余部分借助多区域支持,您可以创建三个应用,它们都服务于同一域,并且对用户而言外观一致,但您可以独立地开发和部署每个应用。

在同一区域内的页面之间导航将执行软导航,这种导航无需重新加载页面。例如,在此图中,从 / 导航到 /products 将是一个软导航。
从一个区域的页面导航到另一个区域的页面,例如从 / 到 /dashboard,将执行硬导航,即卸载当前页面的资源并加载新页面的资源。经常一起访问的页面应位于同一区域,以避免硬导航。
一个区域是一个普通的 Next.js 应用,您还需要配置一个 assetPrefix 以避免与其他区域中的页面和静态文件冲突。
/** @type {import('next').NextConfig} */
const nextConfig = {
assetPrefix: "/blog-static",
};Next.js 资源,例如 JavaScript 和 CSS,将以 assetPrefix 为前缀,以确保它们不会与其他区域的资源冲突。这些资源将以 /assetPrefix/_next/... 的形式为每个区域提供服务。
处理所有未被路由到其他更具体区域的路径的默认应用不需要 assetPrefix。
在 Next.js 15 之前的版本中,您可能还需要额外的重写来处理静态资源。在 Next.js 15 中已不再需要。
/** @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。对于由不同区域提供服务的每个路径,您需要添加一个重写规则,将该路径发送到其他区域的域,并且您还需要重写静态资源的请求。例如:
async rewrites() {
return [
{
source: '/blog',
destination: `${process.env.BLOG_DOMAIN}/blog`,
},
{
source: '/blog/:path+',
destination: `${process.env.BLOG_DOMAIN}/blog/:path+`,
},
{
source: '/blog-static/:path+',
destination: `${process.env.BLOG_DOMAIN}/blog-static/:path+`,
}
];
}destination 应该是一个由区域提供服务的 URL,包括方案(scheme)和域名。这应该指向区域的生产域名,但它也可以在本地开发中用于将请求路由到 localhost。
须知:URL 路径应在区域内唯一。例如,两个区域尝试服务
/blog将会产生路由冲突。
推荐通过 rewrites 路由请求,以最大程度地减少请求的延迟开销,但在路由时需要动态决策的情况下,也可以使用代理。例如,如果您正在使用功能标志来决定路径的路由位置,例如在迁移期间,则可以使用代理。
export async function proxy(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 包来共享代码。
由于不同区域的页面可能在不同时间发布,功能标志(feature flags)可以用于在不同区域之间同步启用或禁用功能。
当在多区域中使用 Server Actions 时,您必须明确允许面向用户的源,因为您的面向用户域名可能服务多个应用。在您的 next.config.js 文件中,添加以下行:
const nextConfig = {
experimental: {
serverActions: {
allowedOrigins: ["your-production-domain.com"],
},
},
};有关更多信息,请参阅 serverActions.allowedOrigins。