Aplicațiile folosite în zilele noastre sunt din ce în ce mai complexe. De aceea o arhitectură bine pusă la punct de la început poate ajuta la o dezvoltare a acestora într-un mod mai ușor. Deși în trecut majoritatea logicii era în backend, acum avem multă logică și în zona de frontend, fapt care a generat și conceptul de micro-frontend.
Microfrontend reprezintă o abordare arhitecturală în dezvoltarea aplicațiilor web, care împarte interfața utilizatorului în componente independente, denumite "microfrontends". Această metodă extinde conceptul de microservices, aplicându-l la frontend. În loc de a dezvolta o aplicație monolitică, dezvoltatorii creează și gestionează mai multe aplicații mici, fiecare cu propriul domeniu de responsabilitate, dar care funcționează împreună pentru a forma o aplicație unitară.
Fig. 1 - Schiță generală a unei arhitecturi cu microfrontends (imagine reinterpretată de autor)
Fiecare microfrontend este autonom și poate fi dezvoltat, testat și implementat independent de celelalte. Aceste componente pot fi create folosind tehnologii diferite, pot avea propriul ciclu de viață și pot fi gestionate de echipe separate. Această abordare aduce o serie de avantaje, în special în proiectele mari, unde complexitatea și dimensiunea codului pot deveni o provocare.
Fig. 2 - Folosirea a mai multor tehnologii. Sursa
Scalabilitate. Fiecare microfrontend poate fi scalat independent în funcție de nevoi, permițând o gestionare mai eficientă a resurselor.
Actualizări și întreținere. Actualizările și corecțiile pot fi aplicate doar pe microfrontendul relevant, fără a afecta întreaga aplicație. Acest fapt duce la o reducere a riscului și a timpului necesar pentru implementarea schimbărilor.
Flexibilitate tehnologică. Fiecare microfrontend este autonom, astfel încât poate fi dezvoltat folosind tehnologia care se potrivește cel mai bine nevoilor echipei respective. Astfel, echipele nu sunt constrânse de o singură tehnologie.
Implementarea microfrontendurilor poate fi realizată prin mai multe tehnici, în funcție de arhitectura și nevoile specifice ale aplicației. Iată câteva metode comune:
În această abordare, serverul combină mai multe microfrontenduri într-o singură pagină web înainte de a trimite rezultatul către client. Aceasta permite o încărcare rapidă a paginii și oferă o experiență unitară pentru utilizator.
Fig. 3 - Combinarea componentelor pe backend (imagine reinterpretată de autor)
În acest caz, microfrontendurile sunt încărcate și asamblate în browserul utilizatorului, de obicei folosind tehnici precum lazy loading. Această abordare poate reduce sarcina pe server și permite o mai mare flexibilitate în ceea ce privește actualizările.
Fig. 4 - Combinarea componentelor pe frontend. Sursa
Utilizarea de iframes permite izolarea completă a fiecărui microfrontend, ceea ce poate fi util pentru a evita conflictele de stil sau script. Totuși, această abordare poate avea un impact negativ asupra performanței și a experienței utilizatorului.
Web Components sunt o tehnologie nativă a browserelor care permite crearea de elemente personalizate, reutilizabile și izolate, care pot fi utilizate ca microfrontenduri. Aceasta oferă o metodă standardizată de a dezvolta componente care pot fi integrate ușor în orice aplicație.
Implementarea microfrontendurilor în Angular implică împărțirea unei aplicații monolitice mari în module mai mici și independente, care pot fi dezvoltate și gestionate de echipe diferite.
Aplicația principală (shell) gestionează routingul și integrează microfrontendurile. Aceasta este responsabilă de încărcarea microfrontendurilor și de coordonarea interacțiunii dintre ele.
Pașii pentru a începe să construiți o aplicație cu microfrontend sunt următorii:
Se creează o aplicație Angular care va servi drept "shell".
Exemplu de configurare a rutei pentru aplicația shell:
const routes: Routes = [
{
path: ‘microfrontend’,
loadChildren: ()
=> import(‘remote/microfrontend’).then(
m => m.MicrofrontendModule)
}
];
Fiecare microfrontend este o aplicație Angular independentă, care poate fi dezvoltată, testată și rulată separat.
Se creează fiecare aplicație microfrontend ca un proiect Angular separat.
Comunicarea dintre microfrontenduri poate fi realizată prin:
Evenimente globale. Utilizarea unui mecanism de tip EventEmitter sau un serviciu global pentru a transmite date între microfrontenduri.
Local Storage sau Session Storage. Pentru partajarea stării între aplicații independente.
Webpack 5 oferă suport pentru Module Federation, o soluție populară pentru microfrontends în care aplicațiile pot partaja module la runtime. Acest lucru permite încărcarea dinamică a microfrontendurilor fără ca toate să fie încărcate într-un singur pachet atunci când se execută buildul.
Primul pas pentru a folosi Module Federation este să adăugați Webpack 5 în proiect.
Exemplu de configurare webpack.config.js pentru aplicația shell:
const ModuleFederationPlugin = require(‘webpack/lib/container/ModuleFederationPlugin’);
module.exports = {
output: {
publicPath: ‘http://localhost:4200/’,
},
plugins: [
new ModuleFederationPlugin({
name: ‘shell’,
remotes: {
microfrontend:
‘microfrontend@http://localhost:4201/remoteEntry.js’,
},
shared: [‘@angular/core’, ‘@angular/common’,
‘@angular/router’],
}),
],
};
Exemplu de configurare pentru un microfrontend:
const ModuleFederationPlugin = require(
‘webpack/lib/container/ModuleFederationPlugin’);
module.exports = {
output: {
publicPath: ‘http://localhost:4201/’,
},
plugins: [
new ModuleFederationPlugin({
name: ‘microfrontend’,
filename: ‘remoteEntry.js’,
exposes: {
‘./Module’: ‘./src/app/microfrontend.module.ts’,
},
shared: [‘@angular/core’, ‘@angular/common’,
‘@angular/router’],
}),
],
};
Fiecare microfrontend poate fi instalat separat și pe servere diferite. Aplicația shell este responsabilă cu orchestrarea și integrarea fiecărui microfrontend la runtime. În funcție de rută sau de interacțiuni, shellul poate încărca microfrontendurile necesare.
Deși microfrontendurile aduc numeroase avantaje, există și provocări asociate cu această abordare. Una dintre principalele provocări este gestionarea consistenței și a comunicării între microfrontenduri. Deoarece fiecare componentă este autonomă, poate fi dificil să se asigure o experiență coerentă pentru utilizatori. De asemenea, gestionarea dependențelor comune, cum ar fi stilurile sau librăriile de utilități, poate fi complexă și poate duce la creșterea dimensiunii aplicației.
Pentru a aborda aceste provocări, este esențială o bună planificare arhitecturală și utilizarea unor practici solide de gestionare a codului. De asemenea, folosirea unor instrumente și platforme de orchestrare și containerizare poate facilita gestionarea microfrontendurile într-un mod eficient.
Microfrontendurile reprezintă o evoluție importantă în dezvoltarea aplicațiilor web, permițând o mai mare flexibilitate, scalabilitate și independență în dezvoltare. Deși implementarea lor poate aduce provocări, beneficiile pe termen lung, în special pentru proiectele mari și complexe, sunt semnificative. Cu o abordare corectă, microfrontendurile pot transforma modul în care echipele de dezvoltare construiesc și întrețin aplicații moderne.
de Ovidiu Mățan
de Cornel Spînu
de Bianca Moga