Comments 4
Привет! Спасибо за наглядный пример. Удалось применить где-то в продакшене?
По поводу зависимостей, я правильно понимаю, что Webpack рассматривает экспортируемый модуль (./src/ProductCarousel
) как отдельную вершину самостоятельного дерева зависимостей и помещает всё это дерево в отдельный чанк (export.js
), исключая из него модули, указанные в shared
?
Когда такой модуль выполняется на стороне приложения-приёмника он берёт эти недостающие внешние (shared) зависимости из бандла самого приложения-приёмника? А если в приложении-приёмнике какой-то зависимости нет? Он подгрузит её из собственного «родного» приложения?
А есть понимание как оно ведёт себя в случае, если версии зависимостей в двух приложениях отличаются? Например, в одном React 16, а в другом 17.
И будет ли оно корректно работать, если export.js
не добавляется в HTML-страницу изначально, а загружается и исполняется динамически (lazy-loading). Врядли кто-то захочет грузить все части микро-фронтенда заранее :)
Буду очень признателен, если кто-то поделится опытом, особенно касательно применения этой технологии в продакшене. Есть ли какие-то подводные камни и т. п.
К сожалению не могу отредактировать свой комментарий выше (Habr is weird oO) по этому постараюсь ответить на часть своих вопросов и возможно расширить их.
По поводу зависимостей, я правильно понимаю, что Webpack рассматривает экспортируемый модуль (./src/ProductCarousel) как отдельную вершину самостоятельного дерева зависимостей и помещает всё это дерево в отдельный чанк (export.js), исключая из него модули, указанные в shared?
Похоже, что на практике так и есть, только файл export.js
содержит не чанк с экспортируемым кодом, а только специальный небольшой Webpack runtime, который позволяет обратиться к экспортируемым модулям динамически.
Когда такой модуль выполняется на стороне приложения-приёмника он берёт эти недостающие внешние (shared) зависимости из бандла самого приложения-приёмника? А если в приложении-приёмнике какой-то зависимости нет? Он подгрузит её из собственного «родного» приложения?
Похоже, что так и есть.
И будет ли оно корректно работать, если export.js не добавляется в HTML-страницу изначально, а загружается и исполняется динамически (lazy-loading). Врядли кто-то захочет грузить все части микро-фронтенда заранее :)
Учитывая, что эти файлы очень маленькие, то не так страшно, что они добавляются в HTML напрямую. Хотя я предполагаю, что их также можно грузить динамически. Главное корректно сохранять порядок вызовов.
А есть понимание как оно ведёт себя в случае, если версии зависимостей в двух приложениях отличаются? Например, в одном React 16, а в другом 17.
Вот этот вопрос остаётся открытым, сейчас не очень понятно как это работает и есть ли какой-то механизм для согласования версий.
Что меня волнует в большей степени, это то как ведёт себя этот механизм в совокупности с tree-shaking'ом, что, если зависимость из родительского (host) приложения была минимизирована шейкером и растеряла часть своих символов. Не возникнет ли ситуация, когда импортируемый модуль попытается воспользоваться библиотекой из родителького (host) приложения и обратится к несуществующему символу? Если да, то это очень опасно использовать в продакшене, а если нет, то это ставит всю систему под сомнение, т. к. переиспользовать зависимости фактически будет невозможно и придётся грузить всё из своего родного (remote) приложения.
Module Federation в Webpack 5, плагин для обмена модулями между Javascript приложениями, описание и пример