Multi-Zones
示例
Multi-Zones 是一种微前端方案,它将同一域名下的大型应用拆分成多个较小的 Next.js 应用,每个应用负责处理一组特定的路径。当应用中存在一些与其他页面无关的页面集合时,这种方案特别有用。通过将这些页面移至单独的 zone (即单独的应用),你可以减小每个应用的体积,从而改善构建时间,并删除仅对某个 zone 必要的代码。由于应用之间是解耦的,Multi-Zones 还允许域名下的其他应用使用它们各自选择的框架。
例如,假设你有以下一组需要拆分的页面:
/blog/*
用于所有博客文章/dashboard/*
用于用户登录后的所有仪表盘页面/*
用于网站其他未被其他 zone 覆盖的部分
借助 Multi-Zones 支持,你可以创建三个应用,它们都在同一个域名下提供服务,对用户来说看起来是一样的,但你可以独立开发和部署每个应用。
在同一个 zone 内的页面之间导航将执行软导航,即不需要重新加载页面的导航。例如,在这个示意图中,从 /
导航到 /products
将是一个软导航。
从一个 zone 的页面导航到另一个 zone 的页面时,例如从 /
导航到 /dashboard
,将执行硬导航,卸载当前页面的资源并加载新页面的资源。经常一起访问的页面应该放在同一个 zone 中,以避免硬导航。
如何定义 zone
zone 是一个普通的 Next.js 应用,你还需要配置 assetPrefix 以避免与其他 zone 中的页面和静态文件发生冲突。
Next.js 的资源,如 JavaScript 和 CSS,将以 assetPrefix
为前缀,以确保它们不会与其他 zone 的资源发生冲突。这些资源将在每个 zone 的 /assetPrefix/_next/...
下提供服务。
处理所有未路由到其他更具体 zone 的路径的默认应用不需要 assetPrefix
。
在早于 Next.js 15 的版本中,你可能还需要一个额外的 rewrite 来处理静态资源。在 Next.js 15 中这不再必要。
如何将请求路由到正确的 zone
使用 Multi Zones 设置后,你需要将路径路由到正确的 zone,因为它们是由不同的应用提供服务的。你可以使用任何 HTTP 代理来实现这一点,但其中一个 Next.js 应用也可以用来路由整个域名的请求。
要使用 Next.js 应用路由到正确的 zone,你可以使用 rewrites
。对于每个由不同 zone 提供服务的路径,你需要添加一个 rewrite 规则,将该路径发送到其他 zone 的域名。例如:
destination
应该是由该 zone 提供服务的 URL,包括协议和域名。这应该指向该 zone 的生产域名,但也可以用于在本地开发中将请求路由到 localhost
。
值得注意的是:URL 路径对于每个 zone 应该是唯一的。例如,两个 zone 试图提供
/blog
会造成路由冲突。
使用中间件路由请求
通过 rewrites
路由请求是推荐的方式,可以最小化请求的延迟开销,但当需要在路由时进行动态决策时,也可以使用中间件。例如,如果你在迁移过程中使用功能标志来决定路径应该路由到哪里,你可以使用中间件。
zone 之间的链接
链接到其他 zone 的路径时应该使用 a
标签,而不是 Next.js 的 <Link>
组件。这是因为 Next.js 会尝试预取并软导航到 <Link>
组件中的任何相对路径,这在跨 zone 时不会生效。
共享代码
构成不同 zone 的 Next.js 应用可以存在于任何仓库中。但是,将这些 zone 放在 monorepo 中通常更方便,可以更轻松地共享代码。对于存在于不同仓库中的 zone,代码也可以通过公共或私有的 NPM 包来共享。
由于不同 zone 中的页面可能在不同时间发布,功能标志对于在不同 zone 之间统一启用或禁用功能很有用。
对于 Next.js on Vercel 应用,你可以使用 monorepo 通过单个 git push
部署所有受影响的 zone。
Server Actions
在 Multi-Zones 中使用 Server Actions 时,由于你的面向用户的域名可能会提供多个应用,你必须明确允许面向用户的源。在你的 next.config.js
文件中,添加以下行:
查看 serverActions.allowedOrigins
了解更多信息。