Skip to main content

多区域

Examples

多区域是一种微前端方法,它将域上的大型应用分成较小的 Next.js 应用,每个应用都服务于一组路径。当应用中存在与其它页面无关的页面集合时,这很有用。通过将这些页面移动到单独的区域(即单独的应用),你可以减小每个应用的大小,从而缩短构建时间并删除仅对其中一个区域必要的代码。

¥Multi-Zones are an approach to micro-frontends that separate a large application on a domain into smaller Next.js applications that each serve a set of paths. This is useful when there are collections of pages unrelated to the other pages in the application. By moving those pages to a separate zone (i.e., a separate application), you can reduce the size of each application which improves build times and removes code that is only necessary for one of the zones.

例如,假设你有以下一组想要拆分的页面:

¥For example, let's say you have the following set of pages that you would like to split up:

  • /blog/* 用于所有博客文章

    ¥/blog/* for all blog posts

  • /dashboard/* 用于用户登录到仪表板时的所有页面

    ¥/dashboard/* for all pages when the user is logged-in to the dashboard

  • /* 用于其他区域未覆盖的其余网站

    ¥/* for the rest of your website not covered by other zones

借助多区域支持,你可以创建三个应用,它们都在同一域上提供服务,并且对用户来说看起来相同,但你可以独立开发和部署每个应用。

¥With Multi-Zones support, you can create three applications that all are served on the same domain and look the same to the user, but you can develop and deploy each of the applications independently.

在同一区域中的页面之间导航将执行软导航,即不需要重新加载页面的导航。例如,在此图中,从 / 导航到 /products 将是一种软导航。

¥Navigating between pages in the same zone will perform soft navigations, a navigation that does not require reloading the page. For example, in this diagram, navigating from / to /products will be a soft navigation.

从一个区域中的页面导航到另一个区域中的页面,例如从 //dashboard,将执行硬导航,卸载当前页面的资源并加载新页面的资源。经常一起访问的页面应位于同一区域中,以避免硬导航。

¥Navigating from a page in one zone to a page in another zone, such as from / to /dashboard, will perform a hard navigation, unloading the resources of the current page and loading the resources of the new page. Pages that are frequently visited together should live in the same zone to avoid hard navigations.

如何定义区域

¥How to define a zone

没有特殊的 API 来定义新区域。区域是一个普通的 Next.js 应用,你还可以在其中配置 basePath 以避免与其他区域中的页面和静态文件发生冲突。

¥There are no special APIs to define a new zone. A zone is a normal Next.js application where you also configure a basePath to avoid conflicts with pages and static files in other zones.

/** @type {import('next').NextConfig} */
const nextConfig = {
basePath: '/blog',
}

处理未发送到更​​特定区域的所有路径的默认应用不需要 basePath

¥The default application that will handle all paths not sent to a more specific zone does not need a basePath.

Next.js 资源(例如 JavaScript 和 CSS)也将以 basePath 为前缀,以确保它们不会与其他区域的资源冲突。这些资源将在每个区域的 /basePath/_next/... 下提供。

¥Next.js assets, such as JavaScript and CSS, will also be prefixed with basePath to make sure that they don't conflict with assets from other zones. These assets will be served under /basePath/_next/... for each of the zones.

如果区域提供的页面不共享公共路径前缀,例如 /home/blog,那么你还可以设置 assetPrefix 以确保所有 Next.js 资源都在区域的唯一路径前缀下提供,而无需在应用中的其余路由中添加路径前缀。

¥If the zone serves pages that don't share a common path prefix, such as /home and /blog, then you can also set assetPrefix to ensure that all Next.js assets are served under a unique path prefix for the zone without adding a path prefix to the rest of the routes in your application.

如何将请求路由到正确的区域

¥How to route requests to the right zone

使用多区域设置后,你需要将路径路由到正确的区域,因为它们由不同的应用提供服务。你可以使用任何 HTTP 代理来执行此操作,但 Next.js 应用之一也可用于路由整个域的请求。

¥With the Multi Zones set-up, you need to route the paths to the correct zone since they are served by different applications. You can use any HTTP proxy to do this, but one of the Next.js applications can also be used to route requests for the entire domain.

要使用 Next.js 应用路由到正确的区域,你可以使用 rewrites。对于不同区域提供的每条路径,你都可以添加重写规则以将该路径发送到另一个区域的域。例如:

¥To route to the correct zone using a Next.js application, you can use rewrites. For each path served by a different zone, you would add a rewrite rule to send that path to the domain of the other zone. For example:

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

destination 应该是区域提供的 URL,包括方案和域。这应该指向区域的生产域,但它也可以用于在本地开发中将请求路由到 localhost

¥destination should be a URL that is served by the zone, including scheme and domain. This should point to the zone's production domain, but it can also be used to route requests to localhost in local development.

很高兴知道:URL 路径对于区域应该是唯一的。例如,两个区域尝试为 /blog 提供服务将产生路由冲突。

¥Good to know: URL paths should be unique to a zone. For example, two zones trying to serve /blog would create a routing conflict.

区域之间的链接

¥Linking between zones

指向不同区域中的路径的链接应使用 a 标记,而不是 Next.js <Link> 组件。这是因为 Next.js 将尝试预取并软导航到 <Link> 组件中的任何相对路径,这在跨区域时不起作用。

¥Links to paths in a different zone should use an a tag instead of the Next.js <Link> component. This is because Next.js will try to prefetch and soft navigate to any relative path in <Link> component, which will not work across zones.

共享代码

¥Sharing code

组成不同区域的 Next.js 应用可以存在于任何存储库中。但是,将这些区域放在 monorepo 中通常很方便,以便更轻松地共享代码。对于位于不同存储库中的区域,还可以使用公共或私有 NPM 包共享代码。

¥The Next.js applications that make up the different zones can live in any repository. However, it is often convenient to put these zones in a monorepo to more easily share code. For zones that live in different repositories, code can also be shared using public or private NPM packages.

由于不同区域中的页面可能在不同时间发布,因此功能标志可用于在不同区域中一致启用或禁用功能。

¥Since the pages in different zones may be released at different times, feature flags can be useful for enabling or disabling features in unison across the different zones.

对于 Vercel 上的 Next.js 应用,你可以使用 monorepo 和单个 git push 部署所有受影响的区域。

¥For Next.js on Vercel applications, you can use a monorepo to deploy all affected zones with a single git push.