Как фронтенды обмениваются контрактами в микрофронтендной архитектуре?
Что проверяют
Понимаете ли вы, где проходят границы между независимыми командами и как договорённость между ними зафиксирована так, чтобы деплой одной не ломал другую. Следом обычно спрашивают про версии: что будет, если хост обновился, а remote ещё нет.
Как отвечать
Контракт в микрофронтендах состоит из нескольких частей, назовите их:
- точка монтирования: что экспортирует микрофронтенд. Часто это функции
mount(el, props)иunmount()или Custom Element. Хост знает только этот интерфейс, а не фреймворк внутри; - входные данные: props или атрибуты, например идентификатор пользователя и локаль. Передавайте минимум и простыми значениями;
- события наружу:
CustomEventс описанной схемойdetail, шина наwindow,BroadcastChannelмежду вкладками. Имена событий с префиксом команды; - URL как контракт: каждый микрофронтенд владеет своим префиксом маршрутов, а состояние, нужное другим, живёт в адресе;
- типы: отдельный пакет с TypeScript-типами контракта в приватном npm-реестре по semver. В Module Federation 2.0 типы remote можно подтягивать автоматически;
- общие зависимости: в Module Federation блок
sharedсsingleton: trueиrequiredVersionдля React, иначе на странице окажутся две копии; - визуальный контракт: дизайн-токены и общая библиотека компонентов, стили изолированы через CSS Modules, префиксы или Shadow DOM.
Изменения делайте обратно совместимыми: новое поле добавляется, старое помечается устаревшим и удаляется, когда все потребители обновились. Совместимость проверяют контрактными тестами в CI.
Где спотыкаются
Предлагают общий глобальный Redux-стор на все микрофронтенды. Команды снова связаны одной схемой состояния, и независимый деплой теряет смысл.
Импортируют внутренние модули соседа напрямую, мимо публичного интерфейса. Любой рефакторинг у соседа ломает чужой код прямо в рантайме.
Не думают о рассинхроне версий. Remote деплоится независимо, поэтому хост должен переживать и старую, и новую версию контракта, а не только ту, с которой его собирали.