Микрофронтенды: ажиотаж или революционные изменения? Как одна команда сократила расходы, ускорила релизы и создала масштабируемые приложения без хаоса.
Привет всем! Меня зовут Никита, я фронтенд-лидер в Exante, и сегодня я хочу поделиться нашим опытом внедрения микрофронтенд-архитектуры. Я расскажу, как мы к ней пришли, какие проблемы она решила, какие преимущества и недостатки мы обнаружили, и, наконец, когда микрофронтенды действительно стоит использовать и что приносит больше пользы разработчикам или бизнесу.
Каждое из этих приложений разрабатывается независимо и имеет свой собственный цикл выпуска. Они могут находиться в одном репозитории, но чаще всего размещаются отдельно.
Главная цель микрофронтендов — разделить ответственность, ускорить вывод продукта на рынок и позволить различным командам работать и выпускать релизы параллельно.
RUN объединяет множество функциональных областей — бэк-офис, CRM, мониторинг, управление ролями и правами доступа, отчетность, брендинг и многое другое.
Мы также предоставляем RUN нашим внешним клиентам в качестве решения под собственной торговой маркой, позволяя им управлять своими брокерскими операциями и настраивать интерфейс в соответствии со своими потребностями.
Да, и RUN — это действительно большая коллекция микроприложений для фронтенда.
Это разнообразие вызвало ряд серьезных проблем:
Компании требовалось новое решение: единая точка входа с унифицированной авторизацией. Кроме того, приложение должно было быть модульным, поскольку Exante также предоставляет готовые решения под собственной торговой маркой.
Так появилось новое приложение на основе React с единым входом, для разработки основного функционала которого мы начали с нуля.
Наша команда фронтенд-разработчиков состояла всего из трех или четырех человек.
Прежде чем приступить к программированию, мы создали систему дизайна и выделили её в отдельный набор элементов пользовательского интерфейса. Но переписывать всё с нуля заняло бы годы.
Поэтому руководство компании задало вопрос: можем ли мы интегрировать старые веб-приложения в новую систему в их текущем виде, не дожидаясь разработки новых? Единственное требование заключалось в том, что старые и новые приложения должны оставаться независимыми с точки зрения релизов.
Это привело нас к созданию системы, в которой несколько микрофронтендов — даже построенных с использованием разных технологий — могли сосуществовать в рамках одного хост-приложения.
У старых приложений были свои собственные системы дизайна, но в качестве временного решения это подходило для бизнеса. Со временем все приложения перешли на React с единым дизайном и поддержкой тем оформления.
Сегодня наша команда фронтенд-разработчиков выросла до десяти человек. Мы переписали почти всё, и поддержка устаревших приложений больше не требуется.
Основное приложение включает в себя макет (меню, заголовок, маршрутизацию, аутентификацию и пользовательские настройки). Каждый маршрут отображает соответствующий микроинтерфейс, загружаемый динамически из конфигурации нашей системы брендинга. Доступные пункты меню определяются ролями и правами пользователей.
Каждое MFE-приложение отображается очень просто: мы прикрепляем его функцию рендеринга к глобальному объекту Window. Каждый микрофронтенд публикуется независимо и может даже работать автономно на собственном хосте.
В основном приложении все тоже довольно просто. Мы отрисовываем компонент для определенного маршрута и вызываем хук useModuleInit с ключом соответствующего проекта.
Внутри основного приложения мы используем функцию React 19 — ModuleInit из react-dom, которая позволяет загружать внешние модули нативно. Раньше мы добавляли скрипты вручную через плагин Helmet, но это было неудобно. Теперь это элегантно и просто.
Каждый микрофронтенд-скрипт загружается один раз, кэшируется после первого запроса и не перезагружается при переходе между маршрутами.
Мы намеренно избегали сложных конфигураций, таких как модульная федерация или Single-SPA. ModuleInit идеально нам подходит, не добавляя ненужных зависимостей или настроек. Мы не используем общее хранилище между микрофронтендами — и это сделано намеренно. Общее доступное для записи состояние приводит к зависимости и снижает гибкость.
Если существует общее хранилище данных, поток информации должен быть только односторонним: от хоста к микроинтерфейсу.
Для межмодульного взаимодействия мы используем CustomEvent, в то время как другие состояния хранятся либо в бэкэнде, либо в локальном хранилище. Флаги функций также хранятся в бэкэнде.
Для внешних клиентов мы можем собрать любую комбинацию приложений и функций «из коробки» — без необходимости написания кода.
Нет смысла переписывать всё на микрофронтенды только потому, что это модно. Необходимо оценить контекст и выбрать то, что лучше всего подходит для вашего продукта.
Наша архитектура была полностью продиктована потребностями бизнеса:
Привет всем! Меня зовут Никита, я фронтенд-лидер в Exante, и сегодня я хочу поделиться нашим опытом внедрения микрофронтенд-архитектуры. Я расскажу, как мы к ней пришли, какие проблемы она решила, какие преимущества и недостатки мы обнаружили, и, наконец, когда микрофронтенды действительно стоит использовать и что приносит больше пользы разработчикам или бизнесу.
Что такое микрофронтенды и почему они важны?
Микрофронтенды — это архитектурный подход, при котором фронтенд большого приложения разделяется на независимые модули — отдельные микрофронтенд-приложения.Каждое из этих приложений разрабатывается независимо и имеет свой собственный цикл выпуска. Они могут находиться в одном репозитории, но чаще всего размещаются отдельно.
Главная цель микрофронтендов — разделить ответственность, ускорить вывод продукта на рынок и позволить различным командам работать и выпускать релизы параллельно.
Наш опыт внедрения микрофронтендов
Проект RUN
Позвольте мне рассказать вам о нашем проекте. У нас есть внутреннее приложение под названием RUN, которое используется различными отделами нашей брокерской компании.RUN объединяет множество функциональных областей — бэк-офис, CRM, мониторинг, управление ролями и правами доступа, отчетность, брендинг и многое другое.
Мы также предоставляем RUN нашим внешним клиентам в качестве решения под собственной торговой маркой, позволяя им управлять своими брокерскими операциями и настраивать интерфейс в соответствии со своими потребностями.
Да, и RUN — это действительно большая коллекция микроприложений для фронтенда.
Почему нам понадобилась микрофронтенд-архитектура
Изначально у нас был целый "зоопарк" внутренних проектов для разных отделов. Они были созданы с использованием различных технологий — Angular, jQuery, Vue.js, настольных приложений и административных панелей Django.Это разнообразие вызвало ряд серьезных проблем:
- Технологическая фрагментация. Каждый проект требовал собственной инфраструктуры и разработчиков со специфическими навыками, что делало его обслуживание дорогостоящим.
- Отсутствие разделения ответственности. Каждая команда сосредоточилась на своем продукте, без единого видения или общих решений. Синхронизация между командами была затруднена, что приводило к дублированию работы.
- Логика скопирована и вставлена. Без единой системы проектирования интерфейсы выглядели непоследовательными и нескоординированными.
- Множество точек входа. Для каждого приложения требовалась отдельная аутентификация.
Компании требовалось новое решение: единая точка входа с унифицированной авторизацией. Кроме того, приложение должно было быть модульным, поскольку Exante также предоставляет готовые решения под собственной торговой маркой.
Так появилось новое приложение на основе React с единым входом, для разработки основного функционала которого мы начали с нуля.
Наша команда фронтенд-разработчиков состояла всего из трех или четырех человек.
Прежде чем приступить к программированию, мы создали систему дизайна и выделили её в отдельный набор элементов пользовательского интерфейса. Но переписывать всё с нуля заняло бы годы.
Поэтому руководство компании задало вопрос: можем ли мы интегрировать старые веб-приложения в новую систему в их текущем виде, не дожидаясь разработки новых? Единственное требование заключалось в том, что старые и новые приложения должны оставаться независимыми с точки зрения релизов.
Это привело нас к созданию системы, в которой несколько микрофронтендов — даже построенных с использованием разных технологий — могли сосуществовать в рамках одного хост-приложения.
У старых приложений были свои собственные системы дизайна, но в качестве временного решения это подходило для бизнеса. Со временем все приложения перешли на React с единым дизайном и поддержкой тем оформления.
Сегодня наша команда фронтенд-разработчиков выросла до десяти человек. Мы переписали почти всё, и поддержка устаревших приложений больше не требуется.
Как это работает сейчас
Вот как выглядит наша текущая конфигурация:- Приложение-хост (контейнер), объединяющее все микроприложения во фронтенде.
- Набор элементов пользовательского интерфейса, опубликованный в виде частного npm-пакета в нашем собственном реестре Nexus.
- Единые конфигурационные пакеты для ESLint, Prettier и TypeScript позволяют поддерживать единообразный стиль кода во всех проектах и обеспечивают плавное переключение между ними.
- Vite используется для сборки всего — как производственные, так и тестовые сборки выполняются молниеносно. Устранение зависимостей (tree-shaking) уменьшает размер пакета, а независимые зависимости для нас не проблема.
- Единый шаблон конфигурации CI/CD, который легко поддерживать.
Основное приложение включает в себя макет (меню, заголовок, маршрутизацию, аутентификацию и пользовательские настройки). Каждый маршрут отображает соответствующий микроинтерфейс, загружаемый динамически из конфигурации нашей системы брендинга. Доступные пункты меню определяются ролями и правами пользователей.
Каждое MFE-приложение отображается очень просто: мы прикрепляем его функцию рендеринга к глобальному объекту Window. Каждый микрофронтенд публикуется независимо и может даже работать автономно на собственном хосте.
В основном приложении все тоже довольно просто. Мы отрисовываем компонент для определенного маршрута и вызываем хук useModuleInit с ключом соответствующего проекта.
Внутри основного приложения мы используем функцию React 19 — ModuleInit из react-dom, которая позволяет загружать внешние модули нативно. Раньше мы добавляли скрипты вручную через плагин Helmet, но это было неудобно. Теперь это элегантно и просто.
Каждый микрофронтенд-скрипт загружается один раз, кэшируется после первого запроса и не перезагружается при переходе между маршрутами.
Мы намеренно избегали сложных конфигураций, таких как модульная федерация или Single-SPA. ModuleInit идеально нам подходит, не добавляя ненужных зависимостей или настроек. Мы не используем общее хранилище между микрофронтендами — и это сделано намеренно. Общее доступное для записи состояние приводит к зависимости и снижает гибкость.
Если существует общее хранилище данных, поток информации должен быть только односторонним: от хоста к микроинтерфейсу.
Для межмодульного взаимодействия мы используем CustomEvent, в то время как другие состояния хранятся либо в бэкэнде, либо в локальном хранилище. Флаги функций также хранятся в бэкэнде.
Для внешних клиентов мы можем собрать любую комбинацию приложений и функций «из коробки» — без необходимости написания кода.
Что нам дали микрофронтенды
Внедрение такого подхода принесло нам ряд преимуществ:- Ускоренная разработка. Интегрировав устаревшие приложения в качестве микроинтерфейсов, мы создали единую систему за несколько месяцев, а не за годы.
- Современный технологический стек. Мы стандартизировали React, унифицировали стиль кодирования и создали единый набор инструментов для пользовательского интерфейса. Теперь разработчики могут легко переключаться между проектами, и бизнес больше не зависит от разнообразных технических навыков.
- Общий контекст. Теперь команда владеет продуктом как единым целым, что уменьшает фрагментацию и дублирование усилий.
- Независимые релизы. Каждое небольшое приложение легко понять, новые разработчики могут быстрее освоиться, а исправления могут быть выпущены немедленно, без ожидания других.
- Упрощенная CI/CD. Теперь у нас есть единый шаблон для всех проектов.
- Гибкость и масштабируемость. Мы можем собирать или удалять приложения, как кубики LEGO. Настройка нового приложения занимает всего один день.
- Устойчивость. Если одно приложение выходит из строя, остальные продолжают работать. Откат выполняется просто и изолированно.
Что следует учитывать
Если ваша компания решит внедрить микрофронтенд-архитектуру, подготовьтесь к следующему:- Документация. Создание подробных руководств по настройке для разработчиков, специалистов по контролю качества и служб поддержки: как настраивать, интегрировать и развертывать новые приложения.
- Набор инструментов для пользовательского интерфейса. Создайте согласованную систему дизайна, чтобы избежать повторяющейся работы над пользовательским интерфейсом.
- Общая конфигурация и инструменты. Единые правила проверки синтаксиса и TypeScript экономят время и упрощают ротацию разработчиков.
- Обмен знаниями . Поощряйте общение в командах; технические руководители и менеджеры по продуктам могут выступать в качестве связующего звена.
- Увеличение нагрузки на DevOps. Поскольку микрофронтенды зависят от сетевых запросов, обеспечьте правильные настройки CORS и кэширования.
- Участие руководства. Для поддержания порядка необходим сильный технический лидер; без него хаос и дорогостоящие расхождения в коде неизбежны.
- Учет зависимостей. Каждое приложение загружает свои собственные зависимости, увеличивая размер пакета — оптимизация зависимостей (tree-shaking) помогает смягчить этот эффект.
- Общий бэкэнд-сервис. Централизованное хранилище конфигураций для управления приложениями без дополнительных релизов.
Как понять, действительно ли вам нужны микрофронтенды
Они вам, вероятно, понадобятся, если :- Для реализации вашего проекта требуется минимальное время выхода на рынок.
- Независимые релизы имеют решающее значение.
- У вас большая команда, которая испытывает трудности с рефакторингом и разрешением конфликтов в монолитном приложении.
- У вас много изолированных функций, не имеющих общего состояния.
- Вы имеете дело с устаревшими системами и нуждаетесь в единой точке входа — микрофронтенды позволяют осуществлять постепенную миграцию.
- Вы разрабатываете небольшой продукт, стартап или минимально жизнеспособный продукт (MVP).
- Ваши функции тесно взаимосвязаны и требуют постоянного взаимодействия.
- Производительность и размер пакета имеют решающее значение (хотя это и решаемо, но усложняет задачу).
- Ваша DevOps-инфраструктура недостаточно развита, или вашей команде не хватает достаточных знаний и опыта.
Заключение
Я не считаю себя ни евангелистом микрофронтенда, ни приверженцем монолитных систем.Нет смысла переписывать всё на микрофронтенды только потому, что это модно. Необходимо оценить контекст и выбрать то, что лучше всего подходит для вашего продукта.
Наша архитектура была полностью продиктована потребностями бизнеса:
- Переход к приложению с единой точкой входа.
- Временная интеграция устаревших приложений.
- Независимость и изоляция модулей позволяют создавать любые конфигурации.