Головна / Статті / Мікро-фронтенди React з Webpack Module Federation

Мікро-фронтенди React з Webpack Module Federation

Замініть обхідні шляхи з iframe на Webpack 5 Module Federation, щоб хостовані та віддалені React-додатки могли користуватися спільним середовищем виконання, розгортатися незалежно, але водночас зберігати вигляд єдиного продукту.

1148 слів

Великі поверхні продукту рідко є єдиним фронтендом. Процес оформлення замовлень, панелі керування, налаштування та елементи інтерфейсу навколо них часто належать до різних команд, кожна з яких має власні незавершені завдання, борги та календар випуску. Таку структуру зазвичай називають мікро-фронтендами: окремими частинами інтерфейсу, які контролюються окремо, але все одно представляють собою єдиний продукт — клієнтську аналогію мікросервісів.

Протягом тривалого часу інструменти React для реалізації такої моделі були незручними. Організації або використовували один величезний пакет SPA, або вбудовували окремі додатки у іфрейми, приймаючи пов’язані з цим витрати. Механізм Module Federation у Webpack 5 зробив можливим третій підхід: окремо створені та розгорнуті JavaScript-додатки, які на час виконання об’єднуються в один документ браузера. Розуміння того, що робить ця функція — та чому вона замінила старіші рішення — має велике значення для всіх, хто проектує React-системи з кількома командами.

Проблема до появи Module Federation

До того, як з’явилась Federation, у командах, які хотіли незалежно розгортати фронтенд, було обмежено вибір.

Стандартом був монолітичний SPA: один репозиторій, одна ланцюгова обробка та одне розгортання. Така модель підходить для невеликої групи. Коли відповідальність розподіляється, з’являються труднощі. Кожна функція використовує одну версію коду. Час компіляції зростає разом із обсягом коду. Регресія в одній частині проекту може зупинити розгортання іншої команди. Узгодження розгортань між багатьма групами стає окремою формою управління проектом.

Іншим поширеним рішенням були іфрами. Вбудовування повноцінного дочірнього додатку всередину сторінки-батька забезпечувало справжню незалежність у розгортанні, тому їх використовувало багато корпорацій. Однак швидко з’являлися недоліки:

  • Ізоляція є абсолютною. Контексти стилів, DOM та JavaScript не змішуються. Спільне використання стану, координація даних чи нав’язування єдиного мовлення проектування між батьківським та дочірнім елементами перетворюється на складну інженерну задачу замість звичайної передачі параметрів.
  • Залежності дублюються. Кожен фрейм часто завантажує власний React, спільні бібліотеки та CSS. Користувачі неодноразово завантажують однакові дані.
  • Якість користувацького інтерфейсу погіршується. Функції прокрутки, фокусування, зміни розміру, глибинні посилання та історія дій між фреймами вимагають спеціальних рішень, і все одно працюють некоректно.
  • SEO та доступність постраждають. Контент у фреймах важче індексувати, а також менш сумісний з технологіями допомоги користувачам.
  • Комунікація обмежується лише повідомленнями. Дані між фреймами передаються за допомогою postMessage та власних протоколів — без спільної пам’яті та спільного контексту React.

Iframes вирішили проблему незалежної розробки, але створили ще гіршу проблему чистої інтеграції. Бракувало незалежності під час будови та розгортання без відмови від користувацького досвіду, заснованого на одному документі.

Що таке Module Federation?

Module Federation, представлений у Webpack 5, дозволяє окремо розробленим та розгорнутим JavaScript-додаткам обмінюватися кодом під час виконання, а не під час компіляції.

На практиці можна запускати кілька додатків — від різних команд, процесів та версійних ліній — які все одно об’єднуються в браузері в єдиний продукт. Один додаток надає компонент, маршрут чи допоміжну функцію; інший використовує їх, ніби вони знаходяться в тому ж пакеті, без необхідності перекомпіляції при зміні постачальника.

Саме така композиція під час виконання є сьогодні основою для мікро-фронтендів у React.

Як це працює: хости, віддалені компоненти та спільні залежності

У федерації визначені дві ролі:

  • Хост завантажує код, опублікований в іншому місці. Це зазвичай шелл, який підключає інтерфейси інших команд.
  • Віддалений компонент опублікує модулі для інших: сторінки, компоненти, хуки чи утиліти.

Один додаток може виконувати обидві ролі: надавати деякі модулі та водночас використовувати інші.

Віддалені компоненти вказують експорти у конфігурації Webpack; хости визначають, які віддалені компоненти завантажувати та які символи імпортувати. Завантаження відбувається у браузері за адресою входу до віддаленого компонента. Для складання хоста не потрібен вихідний код віддаленого компонента — достатньо стабільної точки входу, яку можна отримати під час запуску додатка.

Спільні залежності допомагають завершити картину. Коли як хост, так і віддалений компонент потребують React, Federation дозволяє використовувати одну інстанцію React замість двох. Це усуває дублювання у стилі iframe, водночас залишаючи можливість для команд різнитися у версіях, коли це необхідно.

Module Federation проти Iframes

Саме це порівняння пояснює, чому багато команд відмовилися від iframes, коли Federation досяг зрілості. Ви зберігаєте незалежність розгортання, яка робила iframes привабливими, не жертвуючи якістю інтеграції. Віддалені компоненти додають контент до DOM хоста, ділять один світ JavaScript та можуть повторно використовувати пакети з постачальниками, станом та системою дизайну — роботу, яка була складною або неможливою через межі iframe.

Чому це використовують великі команди

Маленькі продукти рідко потребують такої складності. Організації з багатьма командами фронтенду використовують Federation для усунення структурних обмежень:

  • Незалежне розгортання. Фахівець, що працює віддалено, може впровадити виправлення без необхідності перебудови продуктів інших команд.
  • Автономія команди. Кожна група самостійно визначає темпи роботи, процеси інтеграції та, у певних межах, вибір інструментів.
  • Швидше створення продуктів. Окремі віддалені робочі місця означають, що невеликі зміни не вимагають перебудови всього продукту.
  • Поступова модернізація. Старі системи можуть поступово додавати нові віддалені елементи замість одноразової заміни всього.
  • Гнучкість стеку технологій. Найпростіше — використовувати спільну фреймворк-систему, але команди іноді поєднують різні версії або навіть різні фреймворки через механізми федерації.

Практичні приклади використання

Веб-сайти для електронної комерції часто дозволяють командам, які керують каталогом, процесом оформлення замовлень та обліковими записами, використовувати окремі інструменти керування. Продукти типу SaaS надсилають віджети панелей керування чи панелі налаштувань від команд, що розробляють функції, не вимагаючи щоразу змінювати основну структуру програми. Під час міграції частини старої SPA виймаються у окремі компоненти, при цьому стара версія продовжує працювати.

Короткий огляд ключових переваг

Переваги федерації можна перелічити у кількох пунктах: справжня можливість незалежної розгортки, спільний середовище виконання, яке усуває дублювання бібліотек та проблеми з обміном даними між додатками, а також користувацький інтерфейс, який все ще здається єдиним додатком. Це забезпечує обіцяну автономність без додаткових складнощів із інтеграцією та проблем з продуктивністю.

Висновок

Перехід від iframes до Module Federation є частиною більш зрілої архітектури фронтенду: незалежність розгортання та послідовний користувацький досвід більше не мають бути протилежностями. Webpack 5 зробив цю комбінацію придатною для організацій, які активно використовують React та вийшли за межі одного бандлу. У міру зростання популярності та розширення ідей спільного використання runtime інструментами на кшталт Rspack та Module Federation 2.0, розуміння причин цього переходу допомагає тим, хто розробляє великі React-системи, свідомо визначати межі власності, замість того щоб використовувати iframes чи постійно зростаючий моноліт.

Спробуйте самі

Мінімальний зразок хоста/віддаленого сервера доступний за адресою react_module_federation.

Клонуйте його локально:

git clone https://github.com/ModithaM/react_module_federation.git
cd react_module_federation

Спочатку запустіть віддалений сервер, щоб його ентрі-пошук почав працювати ще до того, як хост запитає про модулі:

cd remote
npm install
npm start

У іншому терміналі запустіть хост:

cd host
npm install
npm start

Відкрийте хост у браузері; він має завантажувати віддалені компоненти під час роботи та демонструвати описані вище зв’язки. Порядок має значення: хост, який запускається окремо, не має чого завантажувати, поки віддалений компонент не буде доступний, що є корисним нагадуванням про те, що незалежність Federation все ще залежить від доступності віддалених компонентів під час запуску шелу.