Как стать автором
Обновить

Разворачиваем микрофронты на Next.js

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров4.2K

Привет, Хабр! Меня зовут Дэниз, я фронтенд-разработчик в крупнейшем телеком-операторе Казахстана. Сегодня расскажу о микрофронтах — что это такое, какие у них плюсы и минусы, и как их можно реализовать. 

Зачем нам понадобились микрофронты 

По бизнес-требованиям нам нужно было реализовать админ-панель. У нас в компании много проектов с частым обновлением контента. А ещё много команд, которые хотят не только пользоваться фича-тоглами, справочниками и другим общедоступным функционалом, но и встраивать что-то своё.  

Такую админ-панель можно было бы развернуть через NPM-модули и раздать всем разработчикам доступы к пакетам. Но мы решили пойти другим путём — создать единую админ-панель, куда команды могли бы встраивать свои части функционала. Так и появилась идея с микрофронтами. У нас получился один проект, с которым могут работать все разработчики — это позволило  масштабировать разработку и разделить зоны ответственности, но об этом дальше. 

Как это устроено 

Разберём на примере стандартной админ-панели с sidebar-меню и контентом. Когда команда заходит в панель, ей отображаются только её элементы меню, а доступ к ним регулируется через права доступа.  

Получается, что: 

  • общие элементы доступны всем командам; 

  • специфичные элементы видны только той команде, которая их разрабатывает; 

  • каждая команда получает свой микрофронт, который интегрируется в основную админку. 

Технологии современной фронтенд-разработки, которые используются для работы с микрофронтами: 

  • Single-spa — тулза для подгрузки микрофронтов; 

  • Webpack со встроенным плагином Module Federation; 

  • System.js — новый подход, основанный на Rsbuild, используется реже. 

Плюсы микрофронтов

Такой подход даёт ряд преимуществ. 

1. Изоляция кодовой базы 
Каждая команда работает со своим кодом и не затрагивает чужой. 

2. Масштабируемость 
В систему можно добавлять любое количество микрофронтов без необходимости править общий код. 

3. Разделение ответственности 
Команды сами управляют своими микрофронтами: разрабатывают, обновляют, тестируют. 

4. Минимизация рисков 
Ошибка в одном микрофронте не влияет на другие проекты. 

5. Гибкость в разработке и тестировании 
Каждая команда использует свои технологии и библиотеки. Например, одна может работать с Redux, другая с MobX, и они никак не конфликтуют. 

Вот как это работает:

Минусы тоже есть

Микрофронты не всегда идеальны, у них есть ощутимые недостатки. 

1. Сложность в настройке инфраструктуры 
Нужны сложные пайплайны, система хранения артефактов, релиз-менеджмент с чендж-логами. А ещё строгое версионирование на случай, если придётся откатываться назад. В первое время всё это сложно настроить. 

2. Увеличение времени загрузки 
Если три микрофронта используют одну и ту же библиотеку, её чанки загружаются трижды. В монолитном SPA это решается одной загрузкой. 

3. Интеграционные сложности 
Часто командам нужно обмениваться данными, например, передавать токены авторизации. Нужно понимать, как передавать их между микрофронтами — через куки, LocalStorage или как-то ещё. Должны быть строгие договорённости, а в крупных компаниях это бывает сложно. 

Про эксперименты 

До микрофронтов мы экспериментировали с Git submodule.  

У нас есть главный репозиторий, в котором может быть несколько сабмодулей Внутри сабмодуля может быть ещё сабмодуль. Выстраивается такая лесенка зависимостей: 

Отказались от этого подхода по двум причинам: 

1. Сложно настраивать пайплайны 
Версионирование в сабмодулях зависит от хэша коммита. Если в момент билда разработчик пушнет, версия изменится — соберётся версия, которую не тестировали и не обкатывали.  Это усложняет откаты. 

2. Кодовая база не изолирована  
Разработчики видят код друг друга, могут копировать его и изменять. 

Какая архитектура у нас сейчас  

Текущая архитектура у нас про NPM-модули. Вот как она выглядит. 

1. Файл index.ts — входная точка в модуль, через которую мы экспортируем компоненты, выдаём всё в общий проект и работаем с главным репозиторием. 

export { DictionariesPage, DictionaryBySlugPage } from "@/components"

2. GitLab — инструмент для версионирования кодовой базы с сильной девопс-практикой. Пайплайны собирают, тестируют и выкладывают модули в Nexus reposity, который выступает сохраняющим артефактом. 

3. Дальше мы всё это качаем через NPM — он нужен, чтобы подключаться к Nexus reposity. 

4. И используем Next.js. 

Почему мы отказались от Single-spa и Module Federation

Оказалось, что фреймворк, который мы уже везде используем, умеет транспилировать пакеты и разворачивать микрофронты — они называются мультизонами. 

Мы скачиваем наш NPM-пакет обычным образом. Но чтобы он смотрел на локальный Nexus reposity, его нужно настроить через токен. 

npm install @digital/dictionaries-module

И просто в виде страницы выдаём наши компоненты. 

"use client"

import { DictionariesPage } from "@digital/dictionaries-module"

const Page = () => {
    return <DictionariesPage />
}

export default Page

Далее указываем, какие пакеты должны быть транспилированы в конфиге Next.js, и он сам с этим справляется. 

const nextConfig = {
    //...,    
    transpilePackages: [
        "@digital/authorization-module",
        "@digital/feature-toggle-module",
        "@digital/banners-module",
        "@digital/dictionaries-module",
    ],
}

Next.js Multizone — другой подход к микрофронтам

Концептуально это другой подход по оформлению микросервисов. В этом подходе каждый микрофронт — это отдельный Backend for Frontend. 

В обычной схеме есть один общий backend, куда интегрируются микрофронты. В Multizone у каждого микрофронта есть свой backend. Это удобно, если нужно логировать разные модули отдельно или требуются кардинально разные подходы Backend for Frontend. 

Настраивать это тоже легко. В Next-конфиге указываем sub-url, который смотрит на удалённый сервис и подгружает из него JS-код. 

const nextConfig = {
  async rewrites() {
    return [
      {
        source: "/blog",
        destination: `${BLOG_URL}/blog`,
      },
      {
        source: "/blog/:path+",
        destination: `${BLOG_URL}/blog/:path+`,
      },
      {
        source: "/blog-static/_next/:path+",
        destination: `${BLOG_URL}/blog-static/_next/:path+`,
      },
    ];
  },
};

В мультизонах должны совпадать префиксы с root-проектом. 

const nextConfig = {
  assetPrefix: "/blog-static",
};

В данном случае приложение — это обычный фронт, у которого есть несколько url. Каждая ссылка — это отдельная мультизона или микрофронт, у которого есть свой бэкенд. 

При переходе по ссылке идёт перенаправление, при этом url не меняется. 

Таким способом можно гибко редизайнить старые легаси-коды без поломки всего проекта. 

Подведём итоги 

Микрофронты — это мощный инструмент, но не панацея. Они подходят не всем проектам и требуют серьёзных ресурсов для реализации. 

Микрофронты оправданы, если: 

  • у вас много команд и нужно разграничить ответственность; 

  • разработка должна быть параллельной; 

  • важна изоляция кода. 

Лучше обойтись без микрофронтов, если: 

  • проект небольшой. Команде из 3-4 разработчиков будет удобнее работать в одном монорепозитории над одной кодовой базой; 

  • инфраструктура не позволяет удобно версионировать модули; 

  • важнее перформанс, чем масштабируемость. 

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

На этом у меня всё. Спасибо за внимание! 

Как тебе статья? 

Если у тебя есть опыт работы с микрофронтами, напиши в комментариях, какие технологии используешь и какие подводные камни встречались. Будет интересно обсудить. 

Подготовка текста и редактура: Лидия Виринская 

Еще я об этом рассказывал на конференции

Можете послушать, там есть детали.

Теги:
Хабы:
+11
Комментарии6

Публикации

Истории

Работа

Ближайшие события

25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань
20 – 22 июня
Летняя айти-тусовка Summer Merge
Ульяновская область