{"id":24791,"date":"2023-10-16T05:00:00","date_gmt":"2023-10-16T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=24791"},"modified":"2024-07-22T14:27:27","modified_gmt":"2024-07-22T12:27:27","slug":"wprowadzenie-do-mikrofrontendow-skalowanie-i-niezaleznosc-w-architekturze-front-end","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/wprowadzenie-do-mikrofrontendow-skalowanie-i-niezaleznosc-w-architekturze-front-end\/","title":{"rendered":"Wprowadzenie do mikrofrontend\u00f3w: skalowanie i niezale\u017cno\u015b\u0107 w architekturze front-end"},"content":{"rendered":"\n<p>Mikrofrontend prawdopodobnie dla wi\u0119kszo\u015bci front-end developer\u00f3w nie jest poj\u0119ciem nowym. Na rynku funkcjonuje co najmniej od listopada 2016 roku, gdy firma Thougtworks przedstawi\u0142a go jako podobn\u0105 do mikroserwis\u00f3w architektur\u0119 frontendow\u0105. Rok p\u00f3\u017aniej ta sama firma zarekomendowa\u0142a Single-Spa do implementacji mikrofrontendu. Rewolucyjny plugin do Webpack 5 \u201eModule Federation\u201d wyszed\u0142 spod r\u0119ki Zacka Jacksona ju\u017c w pa\u017adzierniku 2020 roku. Od tamtej pory wiele firm przesz\u0142o z architektury monolitycznej na mikrofrontendow\u0105.<\/p>\n\n\n\n<p>Ten proces, a przynajmniej analiza jego przydatno\u015bci, czeka jeszcze wiele zespo\u0142\u00f3w developerskich, <strong>dlatego warto zastanowi\u0107 si\u0119 nad zaletami, wadami, wyzwaniami i sposobami implementacji<\/strong> tego podej\u015bcia.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Zmiana koncepcji<\/strong><\/h2>\n\n\n\n<p>Aplikacje o strukturze monolitycznej maj\u0105 pewne zalety: jedno repozytorium, \u0142atwo\u015b\u0107 wdra\u017cania i utrzymania. Problemy pojawiaj\u0105 si\u0119 wraz poszerzaniem projektu i zespo\u0142u. Aktualizacja bibliotek czy oczekiwanie na efekty pracy innych zespo\u0142\u00f3w mog\u0105 rozci\u0105ga\u0107 si\u0119 w czasie.<\/p>\n\n\n\n<p>Takie zale\u017cno\u015bci prowadz\u0105 te\u017c do powa\u017cniejszych konsekwencji, jak b\u0142\u0119dy, kt\u00f3re zostaj\u0105 wykryte w trakcie korzystania z jednej funkcjonalno\u015bci wewn\u0105trz drugiej. To z kolei sprowadza si\u0119 do konieczno\u015bci utrzymywania wiedzy w\u015br\u00f3d zespo\u0142\u00f3w na temat obszar\u00f3w, za kt\u00f3re nie odpowiadaj\u0105. Niemniej problematyczna bywa konieczno\u015b\u0107 przerabiania czy nawet testowania nowych core\u2019owych rozwi\u0105za\u0144. Dochodz\u0105 te\u017c problemy kadrowe \u2013 gdy technologia projektu nie jest nowa, developerzy mog\u0105 nie chcie\u0107 do niego do\u0142\u0105czy\u0107, nie widz\u0105c mo\u017cliwo\u015bci zmiany.<\/p>\n\n\n\n<p>W opisanej sytuacji <strong>warto zastanowi\u0107 si\u0119 nad implementacj\u0105 mikrofrontendu<\/strong>, czyli architektury polegaj\u0105cej na rozbiciu aplikacji o charakterze monolitu na fragmenty zdecentralizowane i niezale\u017cne. Ka\u017cdy z nich, nazywany mikrofrontendem, odpowiada za inn\u0105 cz\u0119\u015b\u0107 interfejsu tj. widok lub funkcjonalno\u015b\u0107. Kod od\u0142\u0105czonego elementu najcz\u0119\u015bciej umieszczany jest w osobnym repozytorium.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz1-1.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz1-1.png\" alt=\"Przyk\u0142adowy podzia\u0142 pracy w architekturze mikrofrontendowej\" class=\"wp-image-24792\" width=\"608\" height=\"371\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz1-1.png 922w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz1-1-300x184.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz1-1-768x470.png 768w\" sizes=\"(max-width: 608px) 100vw, 608px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 Przyk\u0142adowy podzia\u0142 pracy w architekturze mikrofrontendowej<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Implementacja<\/strong><\/h2>\n\n\n\n<p>Jak umie\u015bci\u0107 niezale\u017cny mikrofrontend wewn\u0105trz aplikacji? Mo\u017cliwo\u015bci jest co najmniej kilka.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Single SPA<\/strong><\/h3>\n\n\n\n<p>To narz\u0119dzie pozwala zintegrowa\u0107 mikroaplikacje \u2013 tak\u017ce wtedy, gdy s\u0105 napisane w r\u00f3\u017cnych technologiach \u2013 w ramach jednej hostowanej aplikacji, kt\u00f3ra nimi zarz\u0105dza i renderuje. Single SPA umo\u017cliwia te\u017c wsp\u00f3\u0142dzielenie zasob\u00f3w.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz2.jpg\"><img decoding=\"async\" width=\"789\" height=\"612\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz2.jpg\" alt=\"Schemat architektury mikrofrontendowej opartej na Single SPA\" class=\"wp-image-24794\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz2.jpg 789w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz2-300x233.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz2-768x596.jpg 768w\" sizes=\"(max-width: 789px) 100vw, 789px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2 <a href=\"https:\/\/www.north-47.com\/micro-frontend-overview-single-spa\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Schemat architektury mikrofrontendowej opartej na Single SPA<\/a><\/figcaption><\/figure>\n\n\n\n<p>Jak go u\u017cy\u0107? Zaczynamy od konfiguracji \u2013 dodajemy Single SPA jako zale\u017cno\u015b\u0107, a w pliku config.js definiujemy, kt\u00f3re mikrofrontendy maj\u0105 by\u0107 \u0142adowane dla \u015bcie\u017cek URL lub event\u00f3w.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/1.png\"><img decoding=\"async\" width=\"241\" height=\"24\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/1.png\" alt=\"kod\" class=\"wp-image-24796\"\/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/2.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/2.png\" alt=\"kod\" class=\"wp-image-24798\" width=\"454\" height=\"273\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/2.png 454w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/2-300x180.png 300w\" sizes=\"(max-width: 454px) 100vw, 454px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Nast\u0119pnie przechodzimy do tworzenia mikrofrontend\u00f3w, kt\u00f3rych pliki startowe umie\u015bcili\u015bmy powy\u017cej. Pami\u0119tamy, by ka\u017cda aplikacja eksportowa\u0142a funkcje bootstrap, umnount i shouldUnmount \u2013 pierwsza odpowiada za pocz\u0105tkowe za\u0142adowanie, druga za odinstalowanie, a trzecia za sprawdzenie, czy mo\u017cna obs\u0142u\u017cy\u0107 okre\u015blon\u0105 \u015bcie\u017ck\u0119 URL.<\/p>\n\n\n\n<p>Gdy mikrofrontendy s\u0105 gotowe, a w g\u0142\u00f3wnej aplikacji umieszczona jest konfiguracja umo\u017cliwiaj\u0105ca ich za\u0142adowanie, mo\u017cemy doda\u0107 wsp\u00f3\u0142dzielone zasoby, np. skrypty i style, lub umo\u017cliwi\u0107 korzystanie ze wsp\u00f3lnego stanu. Na koniec warto pami\u0119ta\u0107, \u017ce dobr\u0105 praktyk\u0105 jest wdra\u017canie stworzonych ten spos\u00f3b mikrofrontend\u00f3w niezale\u017cnie i przetestowanie ich we w\u0142asnych \u015brodowiskach.<\/p>\n\n\n\n<p>W razie potrzeby warto si\u0119gn\u0105\u0107 do dokumentacji Single SPA. Rozwi\u0105zanie to dostarcza sporo mechanizm\u00f3w do komunikacji mi\u0119dzy aplikacjami i zarz\u0105dzania stanem czy routingiem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Iframe<\/strong><\/h3>\n\n\n\n<p>To <strong>technicznie najprostszy<\/strong> spos\u00f3b osadzania mikrofrontend\u00f3w. Generuje jednak sporo problem\u00f3w, o kt\u00f3rych wspomn\u0119 w dalszej cz\u0119\u015bci artyku\u0142u. Implementacja jest intuicyjna \u2013 tworzymy odr\u0119bne, samodzielne aplikacje zawieraj\u0105ce pakiet plik\u00f3w HTML, CSS, JavaScript i innych, po czym osadzamy je w kontenerze, czyli g\u0142\u00f3wnej aplikacji, za pomoc\u0105 elementu &lt;iframe&gt;:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/3.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/3.png\" alt=\"kod\" class=\"wp-image-24801\" width=\"605\" height=\"115\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/3.png 605w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/3-300x57.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Przyk\u0142ad mikrofrontendu:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/4.png\"><img decoding=\"async\" width=\"197\" height=\"123\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/4.png\" alt=\"kod\" class=\"wp-image-24803\"\/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Potencjalne problemy<\/strong><\/p>\n\n\n\n<p>Problem\u00f3w, kt\u00f3re mo\u017cemy napotka\u0107, stosuj\u0105c to rozwi\u0105zanie, jest niestety sporo:<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li>Po pierwsze komunikacja mi\u0119dzy aplikacjami \u2013 konieczne s\u0105 rozwi\u0105zania typu postMessage, cz\u0119sto skomplikowane i powoduj\u0105ce b\u0142\u0119dy.<\/li>\n\n\n\n<li>Wyzwanie stanowi te\u017c zabezpieczenie takiej aplikacji, kt\u00f3ra staje si\u0119 podatna m.in.: na ataki typu XSS (Cross-Site Scripting).<\/li>\n\n\n\n<li>Trudno\u015bci mo\u017ce dostarczy\u0107 przegl\u0105darka \u2013 niekt\u00f3re spo\u015br\u00f3d starszych przegl\u0105darek nie wspieraj\u0105 iframe, z kolei w nowszych dost\u0119p do cz\u0119\u015bci funkcjonalno\u015bci z tego elementu mo\u017ce by\u0107 ograniczony.<\/li>\n\n\n\n<li>To rozwi\u0105zanie jest ponadto ma\u0142o wydajne \u2013 w ramach ka\u017cdego mikrofrontendu oddzielnie b\u0119d\u0105 si\u0119 \u0142adowa\u0107 osobne pliki graficzne, CSS, JavaScript, co prze\u0142o\u017cy si\u0119 na czas \u0142adowania strony i zu\u017cycie pami\u0119ci.<\/li>\n\n\n\n<li>Kolejny problem stanowi wyizolowanie klas i zale\u017cno\u015bci, kt\u00f3re dzia\u0142aj\u0105 w ramach r\u00f3\u017cnych kontekst\u00f3w odr\u0119bnych element\u00f3w iframe. Mo\u017ce to spowodowa\u0107 kolizje, nierzadko trudne w rozwi\u0105zaniu.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Web Components<\/strong><\/h3>\n\n\n\n<p>Komponenty webowe, jako hermetyczne i samodzielne elementy interfejsu u\u017cytkownika, bardzo dobrze nadaj\u0105 si\u0119 do tworzenia projektu w architekturze mikrofrontendowej. Ich zastosowanie jest przy tym niemal r\u00f3wnie proste jak iframe\u2019\u00f3w.<\/p>\n\n\n\n<p>Podobnie jak w ich przypadku, tworzymy komponenty odpowiedzialne za wy\u015bwietlanie interfejsu oraz obs\u0142ug\u0119 logiki funkcjonalno\u015bci.<\/p>\n\n\n\n<p>HTML:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/5.png\"><img decoding=\"async\" width=\"338\" height=\"142\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/5.png\" alt=\"kod\" class=\"wp-image-24805\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/5.png 338w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/5-300x126.png 300w\" sizes=\"(max-width: 338px) 100vw, 338px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>JS:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/6.png\"><img decoding=\"async\" width=\"378\" height=\"142\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/6.png\" alt=\"kod\" class=\"wp-image-24807\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/6.png 378w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/6-300x113.png 300w\" sizes=\"(max-width: 378px) 100vw, 378px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Gotowy komponent integrujemy na stronie g\u0142\u00f3wnej, korzystaj\u0105c z jego tagu:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/7.png\"><img decoding=\"async\" width=\"237\" height=\"121\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/7.png\" alt=\"kod\" class=\"wp-image-24810\"\/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Procesy budowania komponent\u00f3w powinny zosta\u0107 skonfigurowane tak, by by\u0142y niezale\u017cne od innych komponent\u00f3w. Do obs\u0142ugi stan\u00f3w mo\u017cemy u\u017cy\u0107 lokalnego stanu komponent\u00f3w webowych lub rozwi\u0105za\u0144 takich jak Redux lub MobX, pozwalaj\u0105cych na wsp\u00f3\u0142dzielenie stanu mi\u0119dzy komponentami. Z kolei do komunikacji mog\u0105 pos\u0142u\u017cy\u0107 zdarzenia (Event Bus), wsp\u00f3lne magazyny stanu czy interfejsy API.<\/p>\n\n\n\n<p>Najcz\u0119\u015bciej komponenty b\u0119dziemy umieszcza\u0107 w r\u00f3\u017cnych repozytoriach. Do implementacji w g\u0142\u00f3wnej aplikacji mo\u017cemy w\u00f3wczas u\u017cy\u0107:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pakiet\u00f3w npm lub yarn,<\/li>\n\n\n\n<li>Git SubModules,<\/li>\n\n\n\n<li>zewn\u0119trznych skrypt\u00f3w,<\/li>\n\n\n\n<li>wspomnianego ju\u017c pluginu Module Federation.<\/li>\n<\/ul>\n\n\n\n<p>Warto przy tym zauwa\u017cy\u0107, \u017ce Module Federation to nie tylko plugin, ale i ca\u0142o\u015bciowe podej\u015bcie, kt\u00f3re mo\u017ce by\u0107 stosowane do komunikacji i integracji mi\u0119dzy poszczeg\u00f3lnymi mikrofrontendami. Pomaga wywo\u0142a\u0107 funkcje, korzysta\u0107 z komponent\u00f3w i wsp\u00f3\u0142dzieli\u0107 dane mi\u0119dzy r\u00f3\u017cnymi modu\u0142ami, dzi\u0119ki czemu b\u0119d\u0105 p\u0142ynnie wsp\u00f3\u0142dzia\u0142a\u0107. Warto zg\u0142\u0119bi\u0107 ten temat, gdy zdecydujemy si\u0119 na implementacj\u0119 architektury mikrofrontendowej.<\/p>\n\n\n\n<p>Cho\u0107 komponenty webowe <strong>s\u0105 rozwi\u0105zaniem du\u017co lepszym<\/strong> ni\u017c np. korzystanie z iframe-\u00f3w, r\u00f3wnie\u017c w ich przypadku mog\u0105 wyst\u0105pi\u0107 problemy z wydajno\u015bci\u0105, komunikacj\u0105, zale\u017cno\u015bciami czy kompatybilno\u015bci\u0105 z przegl\u0105darkami. Decyduj\u0105c si\u0119 jednak na architektur\u0119 mikrofrontendow\u0105, musimy by\u0107 na to gotowi.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Frint<\/strong><\/h3>\n\n\n\n<p>Du\u017co mniej popularnym podej\u015bciem jest skorzystanie z javascriptowej biblioteki Frint. Zaczynamy od instalacji biblioteki (na przyk\u0142adzie mikrofrontend\u00f3w napisanych w React):<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/8.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/8.png\" alt=\"kod\" class=\"wp-image-24813\" width=\"302\" height=\"25\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/8.png 302w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/8-300x25.png 300w\" sizes=\"(max-width: 302px) 100vw, 302px\" \/><\/a><\/figure>\n\n\n\n<p>Nast\u0119pnie, w obu aplikacjach tworzymy pliki index.js:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/9.png\"><img decoding=\"async\" width=\"324\" height=\"304\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/9.png\" alt=\"kod\" class=\"wp-image-24816\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/9.png 324w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/9-300x281.png 300w\" sizes=\"(max-width: 324px) 100vw, 324px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Druga aplikacja:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/10.png\"><img decoding=\"async\" width=\"322\" height=\"306\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/10.png\" alt=\"kod\" class=\"wp-image-24818\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/10.png 322w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/10-300x285.png 300w\" sizes=\"(max-width: 322px) 100vw, 322px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Teraz konfigurujemy routing, do czego mo\u017cemy u\u017cy\u0107 react-router:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/11.png\"><img decoding=\"async\" width=\"580\" height=\"392\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/11.png\" alt=\"kod\" class=\"wp-image-24821\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/11.png 580w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/11-300x203.png 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>W kolejnym kroku zapewniamy komunikacj\u0119 mi\u0119dzy mikrofrontendami \u2013 na potrzeby przyk\u0142adu u\u017cyjemy dostarczonego przez bibliotek\u0119 Frint Event Bus. Nas\u0142uchujemy na zdarzenie &#8222;titleChanged&#8221; i dodajemy funkcj\u0119, kt\u00f3rej zadaniem b\u0119dzie wywo\u0142anie tego zdarzenia po za\u0142adowaniu mikrofrontu:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/12.png\"><img decoding=\"async\" width=\"366\" height=\"326\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/12.png\" alt=\"kod\" class=\"wp-image-24823\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/12.png 366w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/12-300x267.png 300w\" sizes=\"(max-width: 366px) 100vw, 366px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Na koniec w pliku index.js integrujemy mikrofrontendy:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/13.png\"><img decoding=\"async\" width=\"473\" height=\"331\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/13.png\" alt=\"kod\" class=\"wp-image-24826\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/13.png 473w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/13-300x210.png 300w\" sizes=\"(max-width: 473px) 100vw, 473px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Aby efektywnie zaimplementowa\u0107 zarz\u0105dzanie stanem czy komunikacj\u0119 mi\u0119dzy mikrofrontendami, warto si\u0119gn\u0105\u0107 do dokumentacji Frint, biblioteka zapewnia sporo ciekawych rozwi\u0105za\u0144.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Tailor<\/strong><\/h3>\n\n\n\n<p><strong>Najmniej typowy<\/strong> spos\u00f3b implementacji mikrofrontendu to skorzystanie z frameworka Tailor. Rozwi\u0105zanie to r\u00f3\u017cni si\u0119 od poprzednich \u2013 napisany w NodeJs przez Walmart Labs Tailor umo\u017cliwia <strong>server-side rendering<\/strong> (SSR) i <strong>page fragment stitching<\/strong> (PFS).<\/p>\n\n\n\n<p><strong>SSR<\/strong> to, kr\u00f3tko m\u00f3wi\u0105c, technika generowania stron internetowych po stronie serwera, gdzie zawarto\u015b\u0107 HTML jest tworzona i dostarczana do przegl\u0105darki klienta przez serwer, co pozwala na lepsz\u0105 wydajno\u015b\u0107 i indeksowalno\u015b\u0107 tre\u015bci przez wyszukiwarki.<\/p>\n\n\n\n<p><strong>PFS<\/strong> to z kolei to proces \u0142\u0105czenia r\u00f3\u017cnych fragment\u00f3w stron internetowych lub komponent\u00f3w na serwerze przed ich dostarczeniem do przegl\u0105darki klienta. Umo\u017cliwia to modularyzacj\u0119, ponowne wykorzystywanie oraz optymalizacj\u0119 zarz\u0105dzania tre\u015bci\u0105 na stronie internetowej.<\/p>\n\n\n\n<p>Zaczynamy wi\u0119c od instalacji:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/14.png\"><img decoding=\"async\" width=\"327\" height=\"23\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/14.png\" alt=\"kod\" class=\"wp-image-24829\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/14.png 327w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/14-300x21.png 300w\" sizes=\"(max-width: 327px) 100vw, 327px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Nast\u0119pnie implementujemy serwer w NodeJs:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/15.png\"><img decoding=\"async\" width=\"605\" height=\"338\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/15.png\" alt=\"kod\" class=\"wp-image-24833\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/15.png 605w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/15-300x168.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Kolejno tworzymy HTML g\u0142\u00f3wnej aplikacji:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/16.png\"><img decoding=\"async\" width=\"372\" height=\"144\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/16.png\" alt=\"kod\" class=\"wp-image-24835\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/16.png 372w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/16-300x116.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/16-370x144.png 370w\" sizes=\"(max-width: 372px) 100vw, 372px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Po uruchomieniu serwera mo\u017cemy cieszy\u0107 si\u0119 z dzia\u0142aj\u0105cego mikrofrontendu.<\/p>\n\n\n\n<p>To nietypowe rozwi\u0105zanie sprawia oczywi\u015bcie, \u017ce <strong>stajemy si\u0119 zale\u017cni od serwera<\/strong>. Poza tym niezb\u0119dna jest wiedza z zakresu server-side renderingu i umiej\u0119tno\u015b\u0107 skonfigurowania serwera. Zyskujemy za to \u0142atwe zarz\u0105dzanie integracj\u0105 mikrofrontend\u00f3w oraz <strong>potencjalnie lepsz\u0105 wydajno\u015b\u0107<\/strong> ni\u017c w poprzednich rozwi\u0105zaniach.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Mikrofrontend \u2013 na co zwr\u00f3ci\u0107 uwag\u0119?<\/strong><\/h2>\n\n\n\n<p>Mo\u017ce si\u0119 wydawa\u0107, \u017ce architektura mikrofrontendowa od razu u\u0142atwi prac\u0119 ka\u017cdego zespo\u0142u developerskiego, znacz\u0105co poprawiaj\u0105c przy tym jako\u015b\u0107 wytwarzanego kodu.<\/p>\n\n\n\n<p>Wdra\u017caj\u0105c j\u0105, musimy by\u0107 jednak gotowi na <strong>szereg wyzwa\u0144,<\/strong> kt\u00f3rym trzeba b\u0119dzie po\u015bwi\u0119ci\u0107 troch\u0119 czasu. W\u015br\u00f3d nich znajduj\u0105 si\u0119:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>zarz\u0105dzanie zale\u017cno\u015bciami, konflikty zwi\u0105zane z wersjami bibliotek i wszystko inne, co wynika z separacji kodu,<\/li>\n\n\n\n<li>zarz\u0105dzanie stanem, szczeg\u00f3lnie gdy mamy do czynienia z korzystaniem z tych samych danych przez dwa komponenty,<\/li>\n\n\n\n<li>routing, zw\u0142aszcza w przypadku z\u0142o\u017conych aplikacji,<\/li>\n\n\n\n<li>problemy ze wsparciem dla przegl\u0105darek, spo\u015br\u00f3d kt\u00f3rych te starsze nie wspieraj\u0105 wielu koniecznych dla mikrofrontendu funkcji,<\/li>\n\n\n\n<li>komunikacja \u2013 tym trudniejsza, im wi\u0119cej r\u00f3\u017cnych technologii w mikrofrontendach u\u017cywamy,<\/li>\n\n\n\n<li>utrudnione dbanie o bezpiecze\u0144stwo \u2013 m.in.: autoryzacja i uwierzytelnianie w przypadku du\u017cej liczby mikrofrontend\u00f3w mog\u0105 sta\u0107 si\u0119 skomplikowane,<\/li>\n\n\n\n<li>wydajno\u015b\u0107 \u2013 mo\u017ce (cho\u0107 nie musi) spa\u015b\u0107 na skutek wdro\u017cenia dodatkowej warstwy komunikacyjnej pomi\u0119dzy komponentami,<\/li>\n\n\n\n<li>testowanie oraz debugowanie \u2013 du\u017co trudniejsze ni\u017c w aplikacji o charakterze monolitycznym,<\/li>\n\n\n\n<li>praca zespo\u0142\u00f3w developerskich \u2013 <strong>najwi\u0119kszym wyzwaniem<\/strong> mo\u017ce okaza\u0107 si\u0119 zorganizowanie &nbsp;pracy developer\u00f3w tak, aby unikn\u0105\u0107 konflikt\u00f3w i zapewni\u0107 ci\u0105g\u0142o\u015b\u0107 developmentu.<\/li>\n<\/ul>\n\n\n\n<p>Cz\u0119\u015b\u0107 z tych problem\u00f3w na og\u00f3\u0142 udaje si\u0119 rozwi\u0105za\u0107 dzi\u0119ki rozs\u0105dnemu zaplanowaniu pracy. Niekt\u00f3re jednak pozostaj\u0105 wadami mikrofrontendu, z kt\u00f3rymi trzeba si\u0119 b\u0119dzie mierzy\u0107 przez ca\u0142y okres realizacji projektu postawionego zgodnie z t\u0105 architektur\u0105.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Mikrofrontend \u2013 czy warto?<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"866\" height=\"427\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz3.jpg\" alt=\"Zalety architektury mikrofrontendowej\" class=\"wp-image-24837\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz3.jpg 866w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz3-300x148.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz3-768x379.jpg 768w\" sizes=\"(max-width: 866px) 100vw, 866px\" \/><figcaption class=\"wp-element-caption\">Ryc. 3 <a href=\"https:\/\/code-care.com\/blog\/should-your-2022-projects-have-micro-frontends\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Zalety architektury mikrofrontendowej<\/a><\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz4.jpg\"><img decoding=\"async\" width=\"678\" height=\"411\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz4.jpg\" alt=\"Wady architektury mikrofrontendowej \" class=\"wp-image-24839\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz4.jpg 678w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Obraz4-300x182.jpg 300w\" sizes=\"(max-width: 678px) 100vw, 678px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 4 <a href=\"https:\/\/code-care.com\/blog\/should-your-2022-projects-have-micro-frontends\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Wady architektury mikrofrontendowej<\/a><\/figcaption><\/figure>\n\n\n\n<p>Odpowied\u017a zale\u017cy oczywi\u015bcie od specyfiki projektu i zespo\u0142u, kt\u00f3ry nad nim pracuje. Niew\u0105tpliwie, wraz z tym podej\u015bciem <strong>zyskujemy<\/strong> podzia\u0142 na skalowalne, niezale\u017cne w trakcie wdra\u017cania i niezale\u017cne technologicznie komponenty. Dzi\u0119ki rozdzieleniu odpowiedzialno\u015bci i odseparowaniu b\u0142\u0119d\u00f3w takie aplikacje s\u0105 <strong>du\u017co prostsze w utrzymaniu<\/strong>. Zespo\u0142y pracuj\u0105 samodzielnie, a nowym developerom du\u017co \u0142atwiej zrozumie\u0107 kod, kt\u00f3ry b\u0119d\u0105 wsp\u00f3\u0142tworzy\u0107. Co wa\u017cne, dziel\u0105c aplikacj\u0119, ograniczamy te\u017c powierzchnie potencjalnego ataku, dbaj\u0105c tym samym o <strong>popraw\u0119 bezpiecze\u0144stwa<\/strong>.<\/p>\n\n\n\n<p>Z drugiej strony, implementuj\u0105c mikrofrontend, sprawiamy, \u017ce aplikacja jest bardziej z\u0142o\u017cona, a przez dodatkow\u0105 warstw\u0119 komunikacyjn\u0105 \u2013 cz\u0119sto <strong>mniej wydajna<\/strong>. Konieczna jest odpowiednia infrastruktura i umiej\u0119tno\u015bci developerskie, co jest jedn\u0105 z przyczyn, dla kt\u00f3rych <strong>koszty wdro\u017cenia takiej architektury bywaj\u0105 wy\u017csze<\/strong>. Problemem s\u0105 te\u017c wspominane wielokrotnie zale\u017cno\u015bci i brak wsparcia dla starszych przegl\u0105darek.<\/p>\n\n\n\n<p>Przyk\u0142ady marek takie jak Amazon, Zalando, Spotify, Lego, SoundCloud czy Ikea, dowodz\u0105 jednak, \u017ce <strong>du\u017ce firmy coraz ch\u0119tniej si\u0119gaj\u0105 po architektur\u0119 mikrofrontendow\u0105<\/strong>. Rosn\u0105ca liczba rozwi\u0105za\u0144 problem\u00f3w, kt\u00f3r\u0105 generuje, oraz du\u017ca liczba zalet, mog\u0105 sprawi\u0107, \u017ce ju\u017c nied\u0142ugo podej\u015bcie to stanie si\u0119 w \u015bwiecie front-endu <strong>absolutnym standardem.<\/strong><\/p>\n\n\n\n<p>***<\/p>\n\n\n\n<p>Je\u015bli interesuje Ci\u0119 tematyka front-endu, zajrzyj r\u00f3wnie\u017c<a aria-label=\" do innych artyku\u0142\u00f3w naszych ekspert\u00f3w. (opens in a new tab)\" href=\"https:\/\/sii.pl\/blog\/wyszukiwarka\/front\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\"> do innych artyku\u0142\u00f3w naszych ekspert\u00f3w.<\/a> <\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;24791&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;7&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.9&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;4.9\\\/5 ( votes: 7)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Wprowadzenie do mikrofrontend\u00f3w: skalowanie i niezale\u017cno\u015b\u0107 w architekturze front-end&quot;,&quot;width&quot;:&quot;136.6&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 136.6px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            4.9\/5 ( votes: 7)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Mikrofrontend prawdopodobnie dla wi\u0119kszo\u015bci front-end developer\u00f3w nie jest poj\u0119ciem nowym. Na rynku funkcjonuje co najmniej od listopada 2016 roku, gdy &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/wprowadzenie-do-mikrofrontendow-skalowanie-i-niezaleznosc-w-architekturze-front-end\/\">Continued<\/a><\/p>\n","protected":false},"author":572,"featured_media":24844,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[2427,1814,1554,1546,113],"class_list":["post-24791","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-digital","tag-mikrofrontend","tag-zalety-i-wady","tag-przeglad-narzedzi","tag-frontend"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/10\/Wprowadzenie-do-mikrofrontendow-Skalowanie-i-niezaleznosc-w-architekturze-front-end.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/24791"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/572"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=24791"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/24791\/revisions"}],"predecessor-version":[{"id":24843,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/24791\/revisions\/24843"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/24844"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=24791"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=24791"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=24791"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}