Мультизоны (Multi-Zones)

Примеры

Мультизоны (Multi-Zones) — это подход к микрофронтендам, который разделяет большое приложение на домене на несколько меньших приложений Next.js, каждое из которых обслуживает определённый набор путей. Это полезно, когда есть коллекции страниц, не связанных с другими страницами приложения. Переместив эти страницы в отдельную зону (т.е. отдельное приложение), вы можете уменьшить размер каждого приложения, что улучшит время сборки и удалит код, необходимый только для одной из зон.

Например, предположим, у вас есть следующий набор страниц, которые вы хотите разделить:

  • /blog/* — для всех постов блога
  • /dashboard/* — для всех страниц, когда пользователь вошёл в панель управления
  • /* — для остальной части вашего сайта, не охваченной другими зонами

С поддержкой Multi-Zones вы можете создать три приложения, которые все обслуживаются на одном домене и выглядят одинаково для пользователя, но каждое из приложений можно разрабатывать и развертывать независимо.

Три зоны: A, B, C. Показана жёсткая навигация между маршрутами из разных зон и мягкая навигация между маршрутами в одной зоне.

Навигация между страницами в одной зоне будет выполнять мягкие переходы (soft navigation) — навигацию без перезагрузки страницы. Например, на этой диаграмме переход с / на /products будет мягким.

Навигация со страницы в одной зоне на страницу в другой зоне, например с / на /dashboard, выполнит жёсткий переход (hard navigation), выгружая ресурсы текущей страницы и загружая ресурсы новой страницы. Страницы, которые часто посещаются вместе, должны находиться в одной зоне, чтобы избежать жёстких переходов.

Как определить зону

Для определения новой зоны не требуется специальных API. Зона — это обычное приложение Next.js, в котором также настроен basePath, чтобы избежать конфликтов со страницами и статическими файлами в других зонах.

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

Главное приложение, которое будет обрабатывать все пути, не отправленные в более конкретную зону, не требует basePath.

Ресурсы Next.js, такие как JavaScript и CSS, также будут иметь префикс basePath, чтобы гарантировать отсутствие конфликтов с ресурсами из других зон. Эти ресурсы будут обслуживаться по пути /basePath/_next/... для каждой из зон.

Если зона обслуживает страницы без общего префикса пути, например /home и /blog, вы также можете установить assetPrefix, чтобы все ресурсы Next.js обслуживались с уникальным префиксом пути для зоны без добавления префикса к остальным маршрутам вашего приложения.

Как направлять запросы в нужную зону

При настройке Multi-Zones необходимо направлять пути в правильную зону, так как они обслуживаются разными приложениями. Для этого можно использовать любой 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, создадут конфликт маршрутизации.

Ссылки между зонами

Ссылки на пути в другой зоне должны использовать тег a вместо компонента Next.js <Link>. Это связано с тем, что Next.js попытается предварительно загрузить и выполнить мягкий переход для любого относительного пути в компоненте <Link>, что не будет работать между зонами.

Совместное использование кода

Приложения Next.js, составляющие разные зоны, могут находиться в любом репозитории. Однако часто удобно размещать эти зоны в монорепозитории (monorepo), чтобы упростить совместное использование кода. Для зон, находящихся в разных репозиториях, код также можно совместно использовать через публичные или приватные NPM-пакеты.

Поскольку страницы в разных зонах могут выпускаться в разное время, функциональные флаги могут быть полезны для одновременного включения или отключения функций в разных зонах.

Для Next.js на Vercel можно использовать монорепозиторий (monorepo) для развертывания всех затронутых зон с помощью одной команды git push.