Wyślij zapytanie Dołącz do Sii

Mikrofrontend prawdopodobnie dla większości front-end developerów nie jest pojęciem nowym. Na rynku funkcjonuje co najmniej od listopada 2016 roku, gdy firma Thougtworks przedstawiła go jako podobną do mikroserwisów architekturę frontendową. Rok później ta sama firma zarekomendowała Single-Spa do implementacji mikrofrontendu. Rewolucyjny plugin do Webpack 5 „Module Federation” wyszedł spod ręki Zacka Jacksona już w październiku 2020 roku. Od tamtej pory wiele firm przeszło z architektury monolitycznej na mikrofrontendową.

Ten proces, a przynajmniej analiza jego przydatności, czeka jeszcze wiele zespołów developerskich, dlatego warto zastanowić się nad zaletami, wadami, wyzwaniami i sposobami implementacji tego podejścia.

Zmiana koncepcji

Aplikacje o strukturze monolitycznej mają pewne zalety: jedno repozytorium, łatwość wdrażania i utrzymania. Problemy pojawiają się wraz poszerzaniem projektu i zespołu. Aktualizacja bibliotek czy oczekiwanie na efekty pracy innych zespołów mogą rozciągać się w czasie.

Takie zależności prowadzą też do poważniejszych konsekwencji, jak błędy, które zostają wykryte w trakcie korzystania z jednej funkcjonalności wewnątrz drugiej. To z kolei sprowadza się do konieczności utrzymywania wiedzy wśród zespołów na temat obszarów, za które nie odpowiadają. Niemniej problematyczna bywa konieczność przerabiania czy nawet testowania nowych core’owych rozwiązań. Dochodzą też problemy kadrowe – gdy technologia projektu nie jest nowa, developerzy mogą nie chcieć do niego dołączyć, nie widząc możliwości zmiany.

W opisanej sytuacji warto zastanowić się nad implementacją mikrofrontendu, czyli architektury polegającej na rozbiciu aplikacji o charakterze monolitu na fragmenty zdecentralizowane i niezależne. Każdy z nich, nazywany mikrofrontendem, odpowiada za inną część interfejsu tj. widok lub funkcjonalność. Kod odłączonego elementu najczęściej umieszczany jest w osobnym repozytorium.

Przykładowy podział pracy w architekturze mikrofrontendowej
Ryc. 1 Przykładowy podział pracy w architekturze mikrofrontendowej

Implementacja

Jak umieścić niezależny mikrofrontend wewnątrz aplikacji? Możliwości jest co najmniej kilka.

Single SPA

To narzędzie pozwala zintegrować mikroaplikacje – także wtedy, gdy są napisane w różnych technologiach – w ramach jednej hostowanej aplikacji, która nimi zarządza i renderuje. Single SPA umożliwia też współdzielenie zasobów.

Schemat architektury mikrofrontendowej opartej na Single SPA
Ryc. 2 Schemat architektury mikrofrontendowej opartej na Single SPA

Jak go użyć? Zaczynamy od konfiguracji – dodajemy Single SPA jako zależność, a w pliku config.js definiujemy, które mikrofrontendy mają być ładowane dla ścieżek URL lub eventów.

kod

kod

Następnie przechodzimy do tworzenia mikrofrontendów, których pliki startowe umieściliśmy powyżej. Pamiętamy, by każda aplikacja eksportowała funkcje bootstrap, umnount i shouldUnmount – pierwsza odpowiada za początkowe załadowanie, druga za odinstalowanie, a trzecia za sprawdzenie, czy można obsłużyć określoną ścieżkę URL.

Gdy mikrofrontendy są gotowe, a w głównej aplikacji umieszczona jest konfiguracja umożliwiająca ich załadowanie, możemy dodać współdzielone zasoby, np. skrypty i style, lub umożliwić korzystanie ze wspólnego stanu. Na koniec warto pamiętać, że dobrą praktyką jest wdrażanie stworzonych ten sposób mikrofrontendów niezależnie i przetestowanie ich we własnych środowiskach.

W razie potrzeby warto sięgnąć do dokumentacji Single SPA. Rozwiązanie to dostarcza sporo mechanizmów do komunikacji między aplikacjami i zarządzania stanem czy routingiem.

Iframe

To technicznie najprostszy sposób osadzania mikrofrontendów. Generuje jednak sporo problemów, o których wspomnę w dalszej części artykułu. Implementacja jest intuicyjna – tworzymy odrębne, samodzielne aplikacje zawierające pakiet plików HTML, CSS, JavaScript i innych, po czym osadzamy je w kontenerze, czyli głównej aplikacji, za pomocą elementu <iframe>:

kod

Przykład mikrofrontendu:

kod

Potencjalne problemy

Problemów, które możemy napotkać, stosując to rozwiązanie, jest niestety sporo:

  1. Po pierwsze komunikacja między aplikacjami – konieczne są rozwiązania typu postMessage, często skomplikowane i powodujące błędy.
  2. Wyzwanie stanowi też zabezpieczenie takiej aplikacji, która staje się podatna m.in.: na ataki typu XSS (Cross-Site Scripting).
  3. Trudności może dostarczyć przeglądarka – niektóre spośród starszych przeglądarek nie wspierają iframe, z kolei w nowszych dostęp do części funkcjonalności z tego elementu może być ograniczony.
  4. To rozwiązanie jest ponadto mało wydajne – w ramach każdego mikrofrontendu oddzielnie będą się ładować osobne pliki graficzne, CSS, JavaScript, co przełoży się na czas ładowania strony i zużycie pamięci.
  5. Kolejny problem stanowi wyizolowanie klas i zależności, które działają w ramach różnych kontekstów odrębnych elementów iframe. Może to spowodować kolizje, nierzadko trudne w rozwiązaniu.

Web Components

Komponenty webowe, jako hermetyczne i samodzielne elementy interfejsu użytkownika, bardzo dobrze nadają się do tworzenia projektu w architekturze mikrofrontendowej. Ich zastosowanie jest przy tym niemal równie proste jak iframe’ów.

Podobnie jak w ich przypadku, tworzymy komponenty odpowiedzialne za wyświetlanie interfejsu oraz obsługę logiki funkcjonalności.

HTML:

kod

JS:

kod

Gotowy komponent integrujemy na stronie głównej, korzystając z jego tagu:

kod

Procesy budowania komponentów powinny zostać skonfigurowane tak, by były niezależne od innych komponentów. Do obsługi stanów możemy użyć lokalnego stanu komponentów webowych lub rozwiązań takich jak Redux lub MobX, pozwalających na współdzielenie stanu między komponentami. Z kolei do komunikacji mogą posłużyć zdarzenia (Event Bus), wspólne magazyny stanu czy interfejsy API.

Najczęściej komponenty będziemy umieszczać w różnych repozytoriach. Do implementacji w głównej aplikacji możemy wówczas użyć:

  • pakietów npm lub yarn,
  • Git SubModules,
  • zewnętrznych skryptów,
  • wspomnianego już pluginu Module Federation.

Warto przy tym zauważyć, że Module Federation to nie tylko plugin, ale i całościowe podejście, które może być stosowane do komunikacji i integracji między poszczególnymi mikrofrontendami. Pomaga wywołać funkcje, korzystać z komponentów i współdzielić dane między różnymi modułami, dzięki czemu będą płynnie współdziałać. Warto zgłębić ten temat, gdy zdecydujemy się na implementację architektury mikrofrontendowej.

Choć komponenty webowe są rozwiązaniem dużo lepszym niż np. korzystanie z iframe-ów, również w ich przypadku mogą wystąpić problemy z wydajnością, komunikacją, zależnościami czy kompatybilnością z przeglądarkami. Decydując się jednak na architekturę mikrofrontendową, musimy być na to gotowi.

Frint

Dużo mniej popularnym podejściem jest skorzystanie z javascriptowej biblioteki Frint. Zaczynamy od instalacji biblioteki (na przykładzie mikrofrontendów napisanych w React):

kod

Następnie, w obu aplikacjach tworzymy pliki index.js:

kod

Druga aplikacja:

kod

Teraz konfigurujemy routing, do czego możemy użyć react-router:

kod

W kolejnym kroku zapewniamy komunikację między mikrofrontendami – na potrzeby przykładu użyjemy dostarczonego przez bibliotekę Frint Event Bus. Nasłuchujemy na zdarzenie „titleChanged” i dodajemy funkcję, której zadaniem będzie wywołanie tego zdarzenia po załadowaniu mikrofrontu:

kod

Na koniec w pliku index.js integrujemy mikrofrontendy:

kod

Aby efektywnie zaimplementować zarządzanie stanem czy komunikację między mikrofrontendami, warto sięgnąć do dokumentacji Frint, biblioteka zapewnia sporo ciekawych rozwiązań.

Tailor

Najmniej typowy sposób implementacji mikrofrontendu to skorzystanie z frameworka Tailor. Rozwiązanie to różni się od poprzednich – napisany w NodeJs przez Walmart Labs Tailor umożliwia server-side rendering (SSR) i page fragment stitching (PFS).

SSR to, krótko mówiąc, technika generowania stron internetowych po stronie serwera, gdzie zawartość HTML jest tworzona i dostarczana do przeglądarki klienta przez serwer, co pozwala na lepszą wydajność i indeksowalność treści przez wyszukiwarki.

PFS to z kolei to proces łączenia różnych fragmentów stron internetowych lub komponentów na serwerze przed ich dostarczeniem do przeglądarki klienta. Umożliwia to modularyzację, ponowne wykorzystywanie oraz optymalizację zarządzania treścią na stronie internetowej.

Zaczynamy więc od instalacji:

kod

Następnie implementujemy serwer w NodeJs:

kod

Kolejno tworzymy HTML głównej aplikacji:

kod

Po uruchomieniu serwera możemy cieszyć się z działającego mikrofrontendu.

To nietypowe rozwiązanie sprawia oczywiście, że stajemy się zależni od serwera. Poza tym niezbędna jest wiedza z zakresu server-side renderingu i umiejętność skonfigurowania serwera. Zyskujemy za to łatwe zarządzanie integracją mikrofrontendów oraz potencjalnie lepszą wydajność niż w poprzednich rozwiązaniach.

Mikrofrontend – na co zwrócić uwagę?

Może się wydawać, że architektura mikrofrontendowa od razu ułatwi pracę każdego zespołu developerskiego, znacząco poprawiając przy tym jakość wytwarzanego kodu.

Wdrażając ją, musimy być jednak gotowi na szereg wyzwań, którym trzeba będzie poświęcić trochę czasu. Wśród nich znajdują się:

  • zarządzanie zależnościami, konflikty związane z wersjami bibliotek i wszystko inne, co wynika z separacji kodu,
  • zarządzanie stanem, szczególnie gdy mamy do czynienia z korzystaniem z tych samych danych przez dwa komponenty,
  • routing, zwłaszcza w przypadku złożonych aplikacji,
  • problemy ze wsparciem dla przeglądarek, spośród których te starsze nie wspierają wielu koniecznych dla mikrofrontendu funkcji,
  • komunikacja – tym trudniejsza, im więcej różnych technologii w mikrofrontendach używamy,
  • utrudnione dbanie o bezpieczeństwo – m.in.: autoryzacja i uwierzytelnianie w przypadku dużej liczby mikrofrontendów mogą stać się skomplikowane,
  • wydajność – może (choć nie musi) spaść na skutek wdrożenia dodatkowej warstwy komunikacyjnej pomiędzy komponentami,
  • testowanie oraz debugowanie – dużo trudniejsze niż w aplikacji o charakterze monolitycznym,
  • praca zespołów developerskich – największym wyzwaniem może okazać się zorganizowanie  pracy developerów tak, aby uniknąć konfliktów i zapewnić ciągłość developmentu.

Część z tych problemów na ogół udaje się rozwiązać dzięki rozsądnemu zaplanowaniu pracy. Niektóre jednak pozostają wadami mikrofrontendu, z którymi trzeba się będzie mierzyć przez cały okres realizacji projektu postawionego zgodnie z tą architekturą.

Mikrofrontend – czy warto?

Zalety architektury mikrofrontendowej
Ryc. 3 Zalety architektury mikrofrontendowej

Wady architektury mikrofrontendowej
Ryc. 4 Wady architektury mikrofrontendowej

Odpowiedź zależy oczywiście od specyfiki projektu i zespołu, który nad nim pracuje. Niewątpliwie, wraz z tym podejściem zyskujemy podział na skalowalne, niezależne w trakcie wdrażania i niezależne technologicznie komponenty. Dzięki rozdzieleniu odpowiedzialności i odseparowaniu błędów takie aplikacje są dużo prostsze w utrzymaniu. Zespoły pracują samodzielnie, a nowym developerom dużo łatwiej zrozumieć kod, który będą współtworzyć. Co ważne, dzieląc aplikację, ograniczamy też powierzchnie potencjalnego ataku, dbając tym samym o poprawę bezpieczeństwa.

Z drugiej strony, implementując mikrofrontend, sprawiamy, że aplikacja jest bardziej złożona, a przez dodatkową warstwę komunikacyjną – często mniej wydajna. Konieczna jest odpowiednia infrastruktura i umiejętności developerskie, co jest jedną z przyczyn, dla których koszty wdrożenia takiej architektury bywają wyższe. Problemem są też wspominane wielokrotnie zależności i brak wsparcia dla starszych przeglądarek.

Przykłady marek takie jak Amazon, Zalando, Spotify, Lego, SoundCloud czy Ikea, dowodzą jednak, że duże firmy coraz chętniej sięgają po architekturę mikrofrontendową. Rosnąca liczba rozwiązań problemów, którą generuje, oraz duża liczba zalet, mogą sprawić, że już niedługo podejście to stanie się w świecie front-endu absolutnym standardem.

***

Jeśli interesuje Cię tematyka front-endu, zajrzyj również do innych artykułów naszych ekspertów.

4.9/5 ( głosy: 7)
Ocena:
4.9/5 ( głosy: 7)
Autor
Avatar
Rafał Bedlewicz

Front-end Developer w Sii Polska. Aktualnie związany z Angularem. Wolny czas lubi spędzać aktywnie – entuzjasta podróży i każdej formy sportu

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Może Cię również zainteresować

Pokaż więcej artykułów

Bądź na bieżąco

Zasubskrybuj naszego bloga i otrzymuj informacje o najnowszych wpisach.

Otrzymaj ofertę

Jeśli chcesz dowiedzieć się więcej na temat oferty Sii, skontaktuj się z nami.

Wyślij zapytanie Wyślij zapytanie

Natalia Competency Center Director

Get an offer

Dołącz do Sii

Znajdź idealną pracę – zapoznaj się z naszą ofertą rekrutacyjną i aplikuj.

Aplikuj Aplikuj

Paweł Process Owner

Join Sii

ZATWIERDŹ

This content is available only in one language version.
You will be redirected to home page.

Are you sure you want to leave this page?