- I microfrontend applicano i principi dei microservizi all'interfaccia utente del browser, suddividendo i frontend di grandi dimensioni in sezioni autonome e orientate al dominio, di proprietà di team interfunzionali.
- L'integrazione si basa su DOM, elementi personalizzati, federazione di moduli e una shell applicativa che orchestra il routing, la sicurezza, la composizione e le librerie condivise.
- Framework come React, Angular e Next.js, insieme a pattern come BFF, bus di eventi e caricamento differito, consentono sistemi microfrontend scalabili, resilienti e osservabili.
- I microfrontend aggiungono complessità architettonica, ma danno i loro frutti in prodotti di grandi dimensioni, gestiti da più team, in cui l'implementazione indipendente, la migrazione graduale e il ridimensionamento differenziato sono fondamentali.

I microfrontend sono diventati uno dei modelli di architettura frontend più discussi per team che hanno superato il classico monolite a pagina singola. Quando decine di sviluppatori lavorano sulla stessa base di codice, i cicli di rilascio rallentano, le regressioni si insinuano ovunque e piccole modifiche all'interfaccia utente richiedono improvvisamente un coordinamento massiccio. I microfrontend affrontano esattamente questo problema suddividendo l'interfaccia utente in parti sviluppate e distribuite in modo indipendente.
In questa guida spiegheremo cosa sono i microfrontend, perché sono comparsi e come si relazionano ai microservizi., quali idee fondamentali dovresti rispettare durante la progettazione e come funzionano in pratica con tecnologie come React, Angular, Next.js, Web Components, Webpack Module Federation e Single-SPA. Approfondiremo anche modelli architetturali reali, buone pratiche, insidie comuni ed esempi concreti come un catalogo prodotti e un carrello implementati come microfrontend separati.
Cosa sono i microfrontend e perché sono comparsi?
Il termine "micro frontend" è stato reso popolare intorno al 2016 nel ThoughtWorks Technology Radar In risposta a una tendenza molto concreta: le architetture backend si stavano spostando verso i microservizi, ma il lato browser rimaneva un grande e fragile monolite gestito da un singolo team. Col tempo, quella SPA basata su "fat client" diventa difficile da evolvere, anche se il backend è suddiviso in piccoli servizi.
Un microfrontend è essenzialmente l'idea del microservizio applicata all'interfaccia utente del browser: invece di un unico grande repository frontend, l'interfaccia utente si compone a partire da più applicazioni più piccole e autonome. Ognuna di esse possiede un dominio aziendale chiaro (ad esempio, "checkout", "ricerca prodotti", "profili studenti") e può essere sviluppata, testata e distribuita con cadenza autonoma.
Proprio come i microservizi dividono la logica del backend in unità distribuibili separate, i microfrontend dividono il frontend in sezioni verticali che spaziano dal database o dalle API, passando per il backend, fino all'interfaccia utente. Un team interfunzionale gestisce questa fetta verticale end-to-end, dallo schema dei dati ai componenti dell'interfaccia utente.
Questa “organizzazione verticale” contrasta con una divisione orizzontale per strati (un team per l'interfaccia utente, un altro per le API, un altro per il database). I team verticali tendono a essere più rapidi nelle consegne perché non devono coordinare ogni piccola modifica in metà dell'azienda.
Dal punto di vista applicativo, un microfrontend è un'applicazione web autonoma che può essere composta in un'esperienza più ampia: può avere il proprio routing, gestione dello stato, sistema di progettazione e pipeline di distribuzione, purché rispetti una serie di contratti con il resto del sistema (URL, eventi, API, librerie condivise, ecc.).
Idee e principi fondamentali alla base dei microfrontend
Diversi principi ricorrenti si manifestano nelle architetture microfrontend di successo; non sono regole rigide, ma ti risparmieranno un sacco di problemi se le usi come protezioni.
Agnosticismo tecnologico è uno dei principi più noti: ogni team dovrebbe essere in grado di scegliere e aggiornare il proprio stack tecnologico senza doversi sincronizzare con tutti gli altri. Magari un microfrontend è basato su React, un altro su Angular e uno legacy su Vue. Le astrazioni native del browser come gli elementi personalizzati (componenti web) aiutano a nascondere queste differenze dietro un'API DOM standard.
Un altro obiettivo chiave è un forte isolamento tra le basi di codice dei teamIdealmente, i microfrontend non condividono un runtime JavaScript o variabili globali. Ogni bundle è autonomo, carica le proprie dipendenze e non si basa sullo stato nascosto degli altri. Ciò riduce l'accoppiamento accidentale e rende i deployment indipendenti molto più realistici.
Per evitare conflitti di denominazione, i team spesso concordano su namespace espliciti per classi CSS, eventi DOM, chiavi localStorage, cookie o persino nomi di tag di elementi personalizzati. Ad esempio, un team di checkout potrebbe aggiungere un prefisso con chk- oppure usa un tag come <blue-buy>, mentre un team di raccomandazioni utilizza rec- or <green-recos>A colpo d'occhio, il DOM ti dice chi possiede quale pezzo.
Un altro principio è quello di preferire le capacità native del browser rispetto alle API globali personalizzateInvece di inventare un sistema PubSub multiuso, puoi fare affidamento sugli eventi DOM standard, CustomEvent, API cronologica per il routing o il DOM stesso come livello di integrazione. Ogni volta che hai davvero bisogno di un'API condivisa, mantienila il più piccola e stabile possibile.
Infine, la resilienza dovrebbe essere parte della progettazione fin dal primo giornoOgni microfrontend dovrebbe comunque fornire un valore aggiunto quando JavaScript è lento, non funziona o è bloccato. Tecniche come il rendering lato server, il miglioramento progressivo e gli skeleton screen aiutano a mantenere elevate le prestazioni percepite anche in condizioni di rete scadenti.
Cosa si intende in questo contesto per “applicazione web moderna”?
Non tutti i siti web necessitano di microfrontend o di una strategia di integrazione del browser complessaUn buon modello mentale deriva dal "continuum documenti-applicazioni": a sinistra si trovano per lo più documenti statici collegati tra loro; a destra si trovano app completamente interattive come un editor di foto online.
Se il tuo progetto è più vicino ai documenti statici, spesso è sufficiente una semplice composizione renderizzata dal serverIl server raccoglie frammenti HTML da diverse fonti, li unisce e li invia al browser. Gli aggiornamenti avvengono tramite caricamenti completi della pagina o piccole iniezioni Ajax, e questo è perfettamente normale.
Quando ti muovi verso esperienze più dinamiche, simili a quelle delle app—feedback immediato, lavoro offline, aggiornamenti ottimistici dell'interfaccia utente—la pura integrazione lato server non è più sufficiente. Sono necessari composizione, gestione dello stato e routing lato client. È qui che i microfrontend diventano interessanti: offrono un modo per scalare tale complessità tra più team.
Organizzazione verticale e sezioni guidate dal dominio
Una raccomandazione comune è quella di allineare i microfrontend con i domini aziendali anziché con i livelli tecniciPensa in termini di percorsi utente: "carrello", "dettagli prodotto", "utenti amministratori", "calendari dei corsi", "registri degli studenti", "fatture", ecc.
Ciascuno di questi domini può diventare un proprio microfrontend con una responsabilità ben definitaIn un sistema universitario, un'app potrebbe gestire i profili degli studenti, un'altra i profili del personale, una terza gli orari dei corsi e un'altra l'interfaccia utente dei risultati degli esami. Condividono una shell e forse anche un po' di stile, ma ciascuna è un'applicazione indipendente dal punto di vista dell'implementazione.
Un buon slicing considera anche i contesti delimitati dei microservizi backendIdealmente, il microfrontend per la "fatturazione" dialoga principalmente con i microservizi di fatturazione, il frontend per il "catalogo" con i servizi di catalogo e così via. In questo modo, ogni sezione verticale rimane coesa e si riducono le dipendenze tra team.
Integrazione tecnica: DOM come API e Web Components
Nelle architetture microfrontend lato browser, il DOM stesso spesso funge da API di integrazione primariaInvece di chiamare direttamente il codice JavaScript dell'altro, i team espongono le funzionalità tramite elementi HTML, attributi ed eventi.
Gli elementi personalizzati (parte dei componenti Web) sono un potente strumento primitivo per questoUn team può creare una funzionalità utilizzando qualsiasi framework desideri e poi racchiuderla come tag personalizzato, ad esempio <order-minicart></order-minicart>Il contratto pubblico di quel componente è definito dal nome del tag, dagli attributi e dagli eventi emessi, non dalla sua implementazione interna.
Il supporto del browser per Custom Elements v1 è ora solido su tutti i principali browser, il che significa che raramente avrai bisogno di polyfill. La maggior parte dei framework più diffusi – React, Vue, Angular, Svelte, Preact – possono visualizzare o incorporare elementi personalizzati come se fossero normali tag HTML, e molti di essi possono anche essere compilati in un elemento personalizzato.
Il modello di integrazione è simile a questo: un microfrontend "pagina prodotto" decide quali funzionalità appaiono sulla pagina (selettori, pulsanti di acquisto, mini-carrello, raccomandazioni). Inietta elementi personalizzati come <blue-buy sku="t_porsche"></blue-buy> or <green-recos sku="t_porsche"></green-recos>I team che possiedono tali funzionalità registrano i loro elementi con customElements.define e implementare callback del ciclo di vita come connectedCallback or attributeChangedCallback.
Quando una variante di prodotto cambia, la pagina può ricreare l'elemento o semplicemente aggiornarne gli attributiSe il componente rileva attributi rilevanti, può rieseguire il rendering di se stesso. Internamente, il componente potrebbe utilizzare stringhe modello, React, Vue o qualsiasi motore di rendering; l'integratore non deve preoccuparsene.
Comunicazione lato client: eventi e relazioni DOM
Il passaggio di attributi funziona bene per scenari di "ingresso dati" unidirezionali, ma molte interazioni reali richiedono che i componenti comunichino con l'ambiente circostante o con i componenti simili. Un esempio tipico è un pulsante "acquista" che deve notificare al mini-carrello quando viene aggiunto un articolo.
Invece di creare un bus di eventi globale personalizzato, puoi affidarti agli eventi del browser. Spedizione dei componenti CustomEvent istanze che si propagano attraverso l'albero DOM. Un elemento padre o anche window può ascoltare quegli eventi e orchestrare le risposte.
Ad esempio, il pulsante di acquisto potrebbe emettere un evento come blue:basket:changed con l'attuale carico utile del carrelloIl mini-carrello si iscrive a quell'evento su window o su un elemento contenitore condiviso e aggiorna il suo stato interno ogni volta che viene attivato.
Questo approccio mantiene i componenti indipendenti: il pulsante "Acquista" non ha idea di chi, se c'è qualcuno, stia ascoltando i suoi eventi. Si limita a rispettare il suo contratto. E il mini-carrello dipende solo dalla semantica degli eventi, non dai dettagli di implementazione di altri frammenti.
Rendering lato server e componenti universali
Se tieni alle prestazioni di prima verniciatura, alla SEO o alla resilienza quando JavaScript fallisce, il rendering lato server (SSR) è essenzialeI componenti Web lato client puri vengono visualizzati solo dopo il download e l'esecuzione del bundle JS, il che potrebbe comportare una schermata bianca su reti lente.
Una soluzione pragmatica è quella di combinare elementi personalizzati con include lato server (SSI/ESI)Ogni microfrontend espone un endpoint HTTP che restituisce l'HTML per il suo frammento, ad esempio /blue-buy?sku=t_porscheLa pagina principale, renderizzata da una shell o da un'applicazione host, include segnaposto come <!--#include virtual="/blue-buy?sku=t_porsche" --> che il server web (spesso nginx) espande prima di inviare la risposta al browser.
In fase di esecuzione nel browser, lo stesso elemento personalizzato viene idratato o reinizializzato una volta caricato il suo pacchetto JS. Questo fornisce un componente "universale": può essere renderizzato sul server per velocità e SEO, per poi comportarsi come un elemento personalizzato completamente interattivo sul client.
Uno svantaggio dell'SSR con include è che il frammento più lento determina il tempo di risposta totaleLa memorizzazione nella cache a livello di frammento è quasi obbligatoria. Per elementi costosi e altamente personalizzati (come le raccomandazioni) è possibile saltare il rendering lato server e caricarli in modo asincrono sul client.
Gli schermi scheletrici sono un buon compromesso per evitare bruschi cambiamenti di layoutUn frammento può eseguire il rendering sul server di un segnaposto grigio con dimensioni approssimativamente uguali a quelle del contenuto finale. Quando i dati reali arrivano sul lato client, lo scheletro viene sostituito senza grandi riflussi.
Caricamento dei dati e prestazioni percepite
In un mondo microfrontend devi pensare attentamente a dove e quando i dati vengono recuperatiÈ possibile recuperare tutto lato server, tutto lato client o utilizzare una soluzione ibrida. Ogni scelta influisce sulle strategie di caching, sul tempo di interazione e sulla velocità percepita.
Le inclusioni lato server incoraggiano naturalmente i recuperi lato server per frammentoOgni microfrontend dialoga con i "suoi" servizi di backend, esegue il rendering dell'HTML e lo restituisce alla shell. Tale HTML può essere memorizzato nella cache indipendentemente dagli altri frammenti, il che aiuta a scalare parti ad alto traffico come il login o le liste di prodotti.
Quando si caricano i dati sul client, è necessario prevedere un budget per gli stati progressivi: scheletro iniziale, aggiornamenti rapidi quando gli attributi cambiano e comportamento di fallback quando le API sono lente. A volte mantenere i vecchi dati invariati fino all'arrivo di nuovi dati è meno fastidioso visivamente che mostrare uno scheletro per ogni piccola modifica.
Microfrontend con React
React è una scelta molto popolare per l'implementazione di microfrontend grazie al suo ecosistema e alle ottimizzazioni di renderingIl DOM virtuale e il diffing semplificano l'aggiornamento di piccole parti dell'interfaccia utente in base alle modifiche delle proprietà o allo stato globale, ed è possibile raggruppare le app React come SPA autonome o come elementi personalizzati.
La migrazione tra le versioni di React tende ad essere incrementale e relativamente indolore Rispetto ad altri framework, questo è utile quando molti team indipendenti gestiscono microfrontend separati. Non è necessario che tutti i frammenti passino da una versione principale all'altra contemporaneamente.
Il rovescio della medaglia è che i microfrontend React decentralizzati possono creare una proliferazione di risorse: più team, più pipeline di CI/CD, molti bundle, molti piccoli repository. Senza un'automazione sufficiente per build, provisioning e osservabilità, questo sovraccarico diventa difficile da gestire.
Un altro problema pratico è la dimensione del pacchettoSe ogni microfrontend distribuisce la propria copia di React e le librerie condivise, le dimensioni totali del download possono esplodere, soprattutto quando sono necessari diversi frammenti per il rendering di una pagina. Soluzioni come la Federazione dei Moduli (per condividere le dipendenze in fase di esecuzione) o uno stack fortemente allineato tra i team possono mitigare questo problema.
Microfrontend con Angular
Angular si presta bene a configurazioni microfrontend più opinabili, in particolare quando si utilizzano i monorepo e gli strumenti che li circondano (come Nx). Gli spazi di lavoro di Angular sono organizzati in progetti e librerie, il che rende naturale suddividere una soluzione di grandi dimensioni in più app e librerie condivise.
A partire da Angular 12 e Webpack 5, Module Federation è diventato un cittadino di prima classeUn progetto Angular può essere configurato come host o remoto utilizzando comandi schematici, cablando il necessario webpack.config.js e la logica bootstrap per te.
In questo modello, l'app Angular "host" funge da shell che orchestra la navigazione, lo stato condiviso e la condivisione delle dipendenze. I singoli microfrontend Angular (remoti) espongono moduli Angular che l'host può caricare dinamicamente tramite la federazione dei moduli.
Si applicano ancora le solite primitive di routing AngularAll'interno di un microfrontend, si utilizza RouterModule.forChild per le definizioni di percorsi figlio in modo che l'host sia l'unico a utilizzare forRootIn questo modo, più app Angular possono coesistere in uno spazio URL unificato senza conflitti di router.
Federazione dei moduli in pratica (esempio angolare)
Webpack Module Federation è una funzionalità di Webpack 5 che consente a più build di condividere il codice in fase di esecuzioneUna build (l'host) carica dinamicamente i moduli esposti da altre build (remoti) tramite un piccolo file manifest, in genere denominato remoteEntry.js.
In Angular puoi creare questo scaffold abbastanza rapidamenteAd esempio, potresti creare un'app host (host-app) e quindi eseguire uno schema come ng add @angular-architects/module-federation --project host-app --port 4200In questo modo viene impostata una configurazione ModuleFederationPlugin, i file di bootstrap e la logica di runtime.
Quindi crei due app Angular remote: una per un catalogo prodotti e una per un carrello della spesaOgni app ha la sua porta (ad esempio 4201 per products-app, 4202 per cart-app) e la sua configurazione di Federazione dei Moduli. In webpack.config.js di ogni telecomando che usi exposes per pubblicare un modulo (tipicamente il modulo dell'app principale) sotto una chiave come ./ProductsModule or ./CartModule.
La shell host definisce quindi percorsi che caricano in modo pigro quei moduli remoti via loadRemoteModule da @angular-architects/module-federationAd esempio, navigando verso /products innesca un'importazione dinamica da http://localhost:4201/remoteEntry.js e carichi ProductsModule; /cart fa lo stesso con il telecomando del carrello.
All'interno del microfrontend del catalogo potresti avere un ProductsComponent che visualizza una tabella di elementi, leggendo i dati da un PRODUCTS_CATALOG costante e offre un pulsante "Aggiungi al carrello". Al clic, l'articolo persiste in localStorage sotto un tasto “carrello”, incrementando le quantità quando il prodotto esiste già.
Il microfrontend del carrello legge quindi dallo stesso localStorage chiave, visualizza una tabella con nome del prodotto, prezzo, quantità e totale, e offre un pulsante "Svuota carrello" che svuota lo spazio di archiviazione e ne ripristina lo stato interno. Questo è un modo semplice ma esemplificativo di condividere lo stato tra due app indipendenti senza accoppiamento stretto.
Creazione della shell host: layout, home e navigazione
Una shell host solida è fondamentale per una buona esperienza utente sui microfrontendSolitamente possiede il layout globale (intestazione, piè di pagina, barre laterali), il routing di primo livello e talvolta lo stato globale come l'autenticazione o i flag delle funzionalità.
Nell'esempio Angular, l'host definisce un LayoutComponent che esegue il rendering di un'intestazione e di un elemento annidato router-outletL'intestazione vive per conto suo HeaderModule e espone i link di navigazione alla home page, all'elenco dei prodotti e al carrello tramite Angular routerLinkI percorsi di rotta possono essere centralizzati in un enum come RoutesPath per evitare stringhe magiche.
Il modulo di routing del layout imposta un percorso padre con LayoutComponent come suo componente e definisce percorsi figlio per /home, /products e al /cart. /home il percorso carica un locale HomeModule; gli altri usano loadRemoteModule per estrarre i microfrontend Angular in fase di esecuzione.
All'interno dell'host, un SharedModule può raccogliere blocchi di costruzione riutilizzabili come intestazione, layout, direttive comuni e costanti. Questo modulo può essere importato nella radice AppModule con AppRoutingModule, che indirizza il percorso vuoto alla configurazione del routing del layout.
Next.js e microfrontend
Next.js, in quanto framework React di livello produttivo, si adatta bene anche a un approccio microfrontend, soprattutto da quando ha adottato Webpack 5 e quindi il supporto per la Federazione dei Moduli. La sua attenzione a SSR, rigenerazione statica incrementale e routing lo rende un buon candidato per la shell, singoli microfrontend o entrambi.
Per implementare i microfrontend in Next.js in genere si configura la federazione dei moduli a livello di Webpack, esponendo determinate pagine o componenti come remoti e consumandoli da un host. Sebbene la Federazione dei Moduli sia "solo" una funzionalità di bundler JavaScript, è possibile considerarla come un modello architetturale: consente di caricare dinamicamente il codice di proprietà di team diversi senza dover raggruppare tutto in anticipo.
Per le versioni legacy di Next.js senza Webpack 5 avresti bisogno di adattatori esterni per abilitare il supporto alla federazione. Da Next 10.2 in poi, il supporto a Webpack 5 è integrato, semplificando notevolmente la configurazione.
Single-SPA e altri framework microfrontend
Single-SPA è un'altra soluzione ben nota per i microfrontend, in particolare negli ecosistemi ReactSi concentra sull'orchestrazione di più app indipendenti sulla stessa pagina, ciascuna montata nel proprio nodo DOM in base al percorso corrente.
Con Single-SPA puoi avere diverse applicazioni React (o anche combinare React, Vue, Angular) che coesistonoIl framework gestisce quando avviare, montare o smontare ciascun microfrontend durante la navigazione dell'utente e lo si collega alla strategia di routing (ad esempio con React Router in ogni frammento).
Quando si sceglie tra Single-SPA e Module Federation, i team spesso considerano le loro preferenze in termini di bundler/strumenti. Module Federation si integra profondamente con Webpack (e, sempre più, con alternative come Rspack o Rollup man mano che ne aggiungono il supporto). Single-SPA, d'altra parte, riguarda più l'orchestrazione a runtime che la condivisione di bundle, quindi è possibile utilizzarlo con diversi strumenti di build gestendo al contempo la condivisione del codice in altri modi.
Obiettivi, caratteristiche e vantaggi dei microfrontend
L'obiettivo principale dei microfrontend è quello di scalare lo sviluppo frontend tra più team senza crollare sotto il sovraccarico di coordinamentoInvece di un'unica gigantesca base di codice con rilasci sincronizzati, si ottengono unità più piccole distribuibili in modo indipendente.
Gli obiettivi chiave di solito includono consentendo a più team di lavorare in parallelo, supportando la distribuzione indipendente per diverse parti dell'interfaccia utente, mantenendo la flessibilità per utilizzare diverse tecnologie dove ha senso e migliorando la manutenibilità riducendo le dimensioni e la complessità di ogni base di codice.
Le caratteristiche tipiche di tale architettura sono il riutilizzo dei componenti tramite librerie condivise, integrazione modulare tramite una shell applicativa, pipeline indipendenti per microfrontend, ottimizzazione delle prestazioni tramite CDN e caching, gestione centralizzata della sicurezza e forte osservabilità.
Dal punto di vista aziendale, i vantaggi sono sostanziali: lo sviluppo è più scalabile con più team, gli errori vengono isolati meglio, le funzionalità possono essere implementate o ripristinate per dominio e gli stack frontend legacy possono essere migrati gradualmente sostituendo una porzione alla volta anziché riscrivere l'intera app.
Componenti chiave in un'architettura microfrontend
Sebbene le implementazioni varino, la maggior parte delle architetture microfrontend condividono alcuni componenti strutturali che mantengono tutto coerente.
La shell dell'applicazione (o contenitore) è la spina dorsale. È responsabile del layout esterno, della navigazione globale, dell'autenticazione, a volte dello stato globale e della logica per il caricamento o lo scaricamento dei microfrontend. Nelle configurazioni basate su browser, è la pagina che richiama tutti gli altri bundle.
Ogni microfrontend è un modulo autonomo che implementa una capacità specifica, come catalogo prodotti, carrello, profilo utente o pannello di amministrazione. Espone una superficie di integrazione (percorsi, elementi personalizzati, moduli remoti di federazione) e nasconde i dettagli interni al resto del sistema.
Un bus di eventi o un sistema di messaggi è spesso presente per la comunicazione tra microfrontendPuò trattarsi di una semplice astrazione sugli eventi DOM, di un archivio Redux centralizzato o di un broker di messaggi personalizzato. L'obiettivo è una semantica di pubblicazione/sottoscrizione disaccoppiata: un microfrontend emette eventi senza sapere chi li gestisce.
Le librerie condivise ospitano componenti UI riutilizzabili, utilità, token di progettazione e client comuniNelle configurazioni monorepo, strumenti come Nx sono particolarmente utili, consentendo di definire pacchetti condivisi utilizzati da più app con limiti imposti e versioni coerenti.
Collettori e strumenti di osservabilità (ad esempio utilizzando OpenTelemetry) aggregare log, metriche e tracce da tutti i microfrontend, rendendo possibile diagnosticare problemi che interessano più frammenti o servizi.
I CDN completano il quadro sul lato della consegna, memorizzando nella cache risorse statiche come bundle JS, CSS e immagini vicino agli utenti, riducendo la latenza e alleggerendo il carico sui server di origine. Nelle configurazioni microfrontend, spesso si ospitano le risorse di ciascun frammento sul proprio percorso CDN per la memorizzazione nella cache e i rollout indipendenti.
Architettura e modelli di progettazione per microfrontend
Esiste un ricco catalogo di modelli che si applicano specificamente ai microfrontend, solitamente definiti dal modo in cui vengono composti, distribuiti e collegati.
La composizione basata sui componenti significa costruire l'interfaccia utente a partire da componenti web o primitive similiOgni componente ha una singola responsabilità, input e output chiari e può essere testato separatamente. Un livello di composizione di livello superiore (come una shell o un framework di orchestrazione) organizza tali componenti in pagine complete.
Il modello di federazione enfatizza la completa autonomia delle applicazioniOgni microfrontend è un'app autonoma con il proprio ciclo di vita e il proprio team; la shell o un gateway API instrada semplicemente le richieste/i dati al frammento corretto. La comunicazione avviene tramite API REST o eventi ben definiti.
Il modello shell dell'applicazione è effettivamente l'approccio "host"La shell carica i microfrontend, gestisce aspetti trasversali come la navigazione e la sicurezza e garantisce un aspetto coerente. Questo è molto comune nelle configurazioni basate su federazione di moduli o Single-SPA.
I modelli API Gateway e Backend-for-Frontend (BFF) si concentrano sul lato serverUn gateway API si trova di fronte a molti servizi backend, instradando le richieste e applicando misure di sicurezza. Un BFF va oltre: ogni frontend (web, mobile, IoT) può avere un proprio backend dedicato, personalizzato in base alle proprie esigenze.
I modelli di archiviazione dati distribuiti riconoscono che diversi microfrontend potrebbero gestire le proprie fonti di dati o cache. Nel browser questo spesso significa utilizzare chiavi localStorage separate, database IndexedDB o archivi in memoria, mentre nel backend significa database separati per ogni microservizio.
Osservabilità, distribuzione indipendente, scalabilità orizzontale e modelli di sicurezza affrontare le problematiche operative: come monitorare ogni frammento, come distribuirli senza interruzioni globali, come ridimensionarli sotto carico e come applicare l'autenticazione/autorizzazione in modo coerente.
La composizione del routing e i modelli di caricamento differito sono fondamentali per l'esperienza utente e le prestazioniUn router master decide quale microfrontend gestisce quale percorso, e ogni microfrontend ha il proprio router interno. Il caricamento differito garantisce che venga scaricato solo il codice per i frammenti effettivamente necessari per il percorso corrente.
Infine, i modelli di comunicazione basati sugli eventi garantiscono che i microfrontend debolmente accoppiati possano comunque coordinarsi attraverso eventi di dominio, senza introdurre dipendenze dirette che vanificherebbero lo scopo della modularità.
Quando utilizzare i microfrontend (e quando no)
I microfrontend brillano in applicazioni grandi e complesse con domini funzionali ben definitiSi pensi alle piattaforme di e-commerce, ai sistemi di gestione aziendale, ai portali comunali, alle piattaforme educative, ai grandi portali sanitari o a qualsiasi prodotto con molti team che lavorano su aree funzionali separate.
Sono particolarmente utili quando più team lavorano in parallelo che richiedono autonomia nelle scelte tecnologiche, nei cicli di rilascio e nelle priorità, o quando si sta lentamente modernizzando un'interfaccia legacy e non ci si può permettere una riscrittura completa. È possibile ritagliare un'area alla volta in un nuovo microfrontend e integrarla con la vecchia shell.
Sono utili anche quando diverse parti dell'app devono essere ridimensionate in modo diversoUna pagina di accesso o di pagamento potrebbe ricevere molto più traffico di una schermata di configurazione amministrativa; ridimensionare queste sezioni in modo indipendente può far risparmiare molto sui costi infrastrutturali.
Tuttavia, i microfrontend non sono un pranzo gratisAggiungono complessità architettonica, richiedono un forte coordinamento su UX e contratti condivisi e introducono nuove modalità di errore (ad esempio, un frammento non caricato). Per app di piccole o medie dimensioni gestite da un singolo team, un monolite ben strutturato è spesso più semplice ed economico.
I team dovrebbero anche diffidare dell'”anarchia del framework”Sebbene sia tecnicamente possibile che ogni microfrontend utilizzi uno stack completamente diverso, un mix incontrollato di framework rende più difficile l'assunzione di personale, la creazione di strumenti e la condivisione del codice. Un ragionevole livello di allineamento (ad esempio "siamo un'azienda che usa React-first, ma consentiamo l'uso di Angular per domini specifici") di solito funziona meglio nel lungo periodo.
I microfrontend estendono la mentalità dei microservizi al browser, offrendo ai team un modo per suddividere i grandi frontend in parti autonome e orientate al dominio che possono evolversi, distribuire e scalare in modo indipendente, pur continuando a formare un'esperienza utente coesa quando combinata tramite una shell applicativa, librerie condivise, federazione di moduli, componenti Web o framework di orchestrazione come Single-SPA.