Introduction
Le concept de micro frontends est une architecture de développement de logiciels qui permet de découpler les différentes parties d'une application front-end en modules autonomes et indépendants les uns des autres. Cela permet de faciliter le développement, la maintenance et le déploiement d'applications web complexes.
Depuis 2019, les micro frontends ont gagné en popularité et sont devenus une option attrayante pour les entreprises qui cherchent à adopter une approche moderne pour leur architecture de développement front-end. En effet, cette approche permet aux équipes de développement de travailler sur des modules spécifiques sans affecter le reste de l'application. Ainsi, les entreprises peuvent évoluer plus rapidement et s'adapter aux changements du marché plus facilement.
De nombreuses grandes entreprises, telles que Spotify, Zalando et Airbnb, ont adopté cette architecture et ont vu des avantages significatifs en termes de flexibilité, de scalabilité et de maintenabilité de leurs applications. Les micro frontends sont donc devenus indispensables pour les entreprises modernes qui cherchent à rester compétitives dans un marché en constante évolution.
Mais c'est quoi ?
L'architecture micro frontend consiste à découpler les différentes parties d'une application web front-end en modules autonomes et indépendants, ce qui permet à ces modules de cohabiter et de communiquer sur un même site. Cette approche est similaire à celle des microservices qui vise à fragmenter la complexité pour avoir des codes isolés, spécifiques, maintenables et déployables en continu, chacun de manière indépendante des autres. L'objectif est de diviser pour mieux régner, en permettant aux équipes de développement de travailler sur des parties spécifiques de l'application sans avoir à affecter les autres parties.
Pour quoi faire ?
En adoptant cette architecture, les entreprises peuvent bénéficier d'une plus grande flexibilité, d'une évolutivité accrue et d'une meilleure maintenabilité de leur application web front-end. En effet, les modules autonomes peuvent être développés, testés, déployés et mis à jour de manière indépendante, ce qui permet d'accélérer le processus de développement et de réduire le temps de mise sur le marché. De plus, cette approche permet d'éviter les dépendances entre les différents modules, ce qui réduit les risques d'erreurs et de bugs.
Certaines entreprises ont du mal à maintenir la qualité et la sécurité de leur site web en raison de l'utilisation de technologies obsolètes, de frameworks de tests insuffisants ou de régressions sur les fonctionnalités existantes. Cela rend chaque évolution de l'application douloureuse, alors que les exigences commerciales et les attentes des utilisateurs continuent d'évoluer.
Dans les cas les plus extrêmes, il peut sembler que la solution la plus simple serait de repartir de zéro, mais cette option n'est pas toujours réaliste pour les entreprises. Les microfrontends offrent une alternative en permettant de faire évoluer l'application progressivement, en ajoutant ou en modifiant des briques de fonctionnalités tout en maintenant le trafic sur le site. Cela permet aux entreprises d'être plus agiles et de s'adapter plus rapidement aux changements du marché.
Qu'est ce que nous allons utilisé ?
L'iframe est souvent considérée comme une première étape vers l'architecture de microfrontends, mais elle présente des limites importantes en matière de responsive design, de sécurité applicative et de référencement naturel. Ainsi, il est recommandé d'utiliser des frontends ou des bibliothèques JS pour mettre en place des microfrontends.
Web Components
Ces bibliothèques partagent des socles communs, des APIs et utilisent le DOM. Il existe donc plusieurs approches pour créer des microfrontends. Les Web Components en sont une, qui sont des composants web nativement supportés par la plupart des navigateurs. Un Web Component est composé d'un template HTML encapsulé dans un Shadow DOM, qui est un document imbriqué et caché dans le reste de l'arbre.
Pour intégrer un Web Component dans une application, il suffit d'ajouter une balise personnalisée dans le code HTML et d'utiliser l'API Custom Elements pour définir et injecter le microfrontend dans cette balise.
En somme, l'utilisation de bibliothèques JS comme les Web Components peut offrir une alternative plus performante et plus souple à l'iframe pour la mise en place de microfrontends. Ces approches permettent une meilleure gestion des mises à jour, une sécurité accrue et une meilleure évolutivité de l'application web.
<!-- index.html -->
<html>
<head>
<script src="https://mes-micro frontends.fr/web-components.js" async></script>
</head>
<body>
...
<react-web-component></react-web-component>
<lit-element-web-component></lit-element-web-component>
<autre-web-component></autre-web-component>
...
</body>
</html>
Pour trouver les librairies web components :
- Vuejs : vue-web-component-wrapper
- Angular : @angular/elements
- React : direflow
Avantages | Incovénients |
---|---|
Réutilisables et adaptables à presque tous les cas d’usage | Les web components sont générés côté client par le script JS associé. De ce fait, pour les rendre côté serveur en cas de besoin en référencement naturel par exemple, c’est une autre paire de manches ! |
On peut les encapsuler dans un Shadow DOM qui protège notamment de tout conflits de style éventuel | L’encapsulation via Shadow DOM pose aujourd’hui des problèmes d’accessibilité web encore non résolus. |
On peut imbriquer des web components dans des web components |
Les Web Components sont très utiles pour l'encapsulation de services réutilisables sur plusieurs sites. Par exemple, ils peuvent être utilisés pour l'affichage de publicités personnalisées ou pour l'intégration de formulaires d'adhésion à des assurances sur des sites d'e-commerce.
En encapsulant des fonctionnalités spécifiques dans des Web Components, les développeurs peuvent les réutiliser facilement sur différents sites web, sans avoir à réécrire le code à chaque fois. Cela peut être particulièrement utile pour les entreprises qui souhaitent proposer des fonctionnalités personnalisées à leurs clients sur différents sites, tout en garantissant la cohérence et la sécurité de l'application.
En somme, les Web Components sont un outil puissant pour les entreprises qui cherchent à améliorer l'efficacité de leur développement web et à proposer des fonctionnalités personnalisées à leurs clients sur plusieurs sites web.
Node.js / Express / EJS
De nos jours, de nombreuses applications ont recours au Server-Side Rendering (SSR) pour combiner les avantages de l'affichage dynamique des applications rendues côté client et du référencement naturel offert par les applications universelles (MPA). Ces dernières sont des applications qui peuvent fonctionner sur différentes plates-formes, qu'il s'agisse de navigateurs web ou de serveurs.
Les frameworks les plus connus pour la création d'applications universelles sont Next.js pour React et Nuxt.js pour Vue. Grâce à ces frameworks, il est possible de concevoir des applications web hautement performantes qui sont également optimisées pour les moteurs de recherche.
Le fonctionnement du Server-Side Rendering consiste à requêter chaque application vivant à une adresse différente, à l'assigner à une variable EJS (Embedded JavaScript), puis à la rendre en fonction des templates. Cette technique permet d'afficher le contenu de chaque page en fonction des données de la base de données, ce qui améliore la vitesse de chargement et l'expérience utilisateur.
/* index.js */
server.get("/", (req, res) =>
Promise.all([
get("https://adresse-react.fr"),
get("https://adresse-vue.fr"),
get("https://adresse-angular.fr"),
get("https://adresse-ember.fr")
])
.then((réponses) => {
res.render("index", {
react: réponses[0],
vue: réponses[1],
angular: réponses[2],
ember: réponses[3],
});
})
.catch((erreur) => res.send(erreur.message))
)
<!-- index.ejs -->
<html>
<head>...</head>
<body>
<%- react %>
<%- vue %>
<%- angular %>
<%- ember %>
</body>
</html>
Avantages | Incovénients |
---|---|
Le référencement naturel est optimisé car le premier affichage du site et de ses micro frontends dans le navigateur ne nécessite pas l’exécution de JavaScript, plus long à charger que HTML et CSS, et non lu par la majorité des web crawlers. | On retrouve le problème classique des MPAs : le rafraîchissement automatique lors d’un changement de page est un frein à la fluidité de la navigation, et donc à l’expérience utilisateur. |
En utilisant le Server-Side Rendering, les entreprises peuvent offrir une expérience utilisateur fluide et rapide, tout en garantissant une visibilité optimale sur les moteurs de recherche. Cette approche est particulièrement intéressante pour les entreprises qui ont besoin d'offrir une expérience utilisateur de qualité tout en maximisant leur visibilité en ligne.
Le Server-Side Rendering est une technique avancée de développement web qui permet de combiner les avantages de l'affichage dynamique des applications rendues côté client et du référencement naturel offert par les applications universelles. Les frameworks les plus populaires pour la création d'applications universelles sont Next.js et Nuxt.js. Cette approche est particulièrement intéressante pour les entreprises qui cherchent à offrir une expérience utilisateur rapide et fluide tout en améliorant leur visibilité en ligne.
Framework Single-SPA
Single-SPA est un framework dédié à l'implémentation de micro frontends à partir de plusieurs applications web à page unique (Single Page Applications, SPA). Cette approche est considérée comme une technique à part entière dans le développement de micro frontends. Single-SPA est également connu sous le nom de "méta-framework", une catégorie émergente de frameworks conçue pour centraliser la gestion des cycles de vie et la communication entre les différentes applications.
Le principe de Single-SPA est simple : chaque micro frontend implémente trois méthodes distinctes, à savoir "bootstrap", "mount" et "unmount". Ces méthodes permettent respectivement de créer l'application, de l'attacher au DOM et de la retirer. En outre, une application "ROOT" (root-config) est utilisée pour orchestrer le positionnement et l'affichage dynamique des applications en fonction des routes.
Avantages | Incovénients |
---|---|
Permet de migrer une application SPA existante en micro frontend grâce aux librairies qu’il propose | La documentation ne permet pas encore une prise en main facile |
On observe encore des bugs d’affichage non résolus dans certains cas | |
Comme le framework est basé sur des SPA, le rendu côté serveur n’est a priori pas disponible. |
Single-SPA est un framework dédié à l'implémentation de micro frontends à partir de plusieurs SPA. Cette approche permet de centraliser la gestion des cycles de vie et la communication inter-applications, offrant ainsi une grande flexibilité et une évolutivité accrue. Single-SPA est une solution intéressante pour les entreprises qui cherchent à concevoir des applications web modulaires et maintenables tout en favorisant la collaboration entre les différentes équipes de développement.
Ce framework encore très récent n’est pas aujourd’hui 100% fiable, bien qu’il présente beaucoup de potentiel.
Comment les applications communiquent entre elles ?
Lorsque des services utilisent des technologies différentes, la communication entre eux peut être difficile. Cependant, il existe plusieurs façons de faire passer des informations d'une application à l'autre, notamment en utilisant les paramètres de l'URL.
Attributes et properties
Lors de l'utilisation des Web Components, il est possible de transmettre des données en utilisant les attributs ou les propriétés. Dans le cas des attributs, les données peuvent être transmises directement via le code HTML, comme par exemple dans l'exemple suivant :
<product-details product-id="1234567890"></product-details>
Dans cet exemple, l'attribut "product-id" est défini avec la valeur "1234567890", ce qui permet de transmettre cette information au composant Web.
Il est également possible de transmettre des données en utilisant les propriétés du composant Web, comme dans l'exemple suivant :
monWebComponent.produit = {
id: "1234567890",
nom: "Mon produit",
prix: 30.5
}
Dans cet exemple, les données sont transmises directement depuis le code JavaScript, en affectant les valeurs des propriétés du composant "monWebComponent".
Avantages | Incovénients |
---|---|
L’approche attributes est semblable au transfert de données de composant parent à composant enfant dans les frameworks SPA actuels. | Le format de données passé en attributes reste assez limité: chaine de caractère |
Certaines librairies permettent même de simplifier l’utilisation de ces dernières en passant les données: les props en React | Ces données sont directement visibles dans le code, attention donc aux données sensibles |
Il est important de noter que l'utilisation des propriétés est généralement préférable à celle des attributs, car les propriétés permettent une interaction plus dynamique et plus fluide entre les différentes parties du code. En effet, contrairement aux attributs, les propriétés peuvent être facilement modifiées en temps réel, ce qui permet une mise à jour plus rapide et plus efficace des données transmises entre les différents composants Web.
L'utilisation des attributs et des propriétés dans les Web Components peut suffire pour réaliser des micro frontends coordonnés avec le contexte de l'application parente. Ces approches sont simples à implémenter et permettent une communication efficace entre les différents composants Web.
DOM / Custom Events
Le Document Object Model (DOM) est une interface du navigateur web qui permet de manipuler les éléments HTML, CSS et JavaScript présents sur une page web. Une des fonctionnalités principales du DOM est la gestion des événements (events) qui se produisent au sein de la page web, qu'ils soient provoqués par l'utilisateur (par exemple, un clic de souris ou l'enfoncement d'une touche) ou par d'autres éléments (comme une vidéo ou une piste audio en pause).
Il est possible de créer et d'utiliser ces événements pour transmettre des données via l'objet "window". Par exemple, lorsqu'un événement est déclenché, on peut créer un objet de type "CustomEvent" et le transmettre à travers l'objet "window" afin que d'autres parties du code puissent y accéder.
Cette méthode peut être particulièrement utile pour faire passer des données entre différents micro frontends, qui peuvent être développés avec des technologies et des frameworks différents. En utilisant les événements du DOM pour transmettre des données, il est possible de réaliser une communication inter-applications efficace et transparente, tout en maintenant la modularité et la flexibilité des micro frontends.
/* émetteur.js */
const message = {
type: "important",
texte: "Ce message est important",
};
// DOM Event
window.postMessage(message, "https://url-destinataire.fr");
// Custom Event
const événement = new CustomEvent("message.important", {
detail: message
});
window.dispatchEvent(événement);
/* récepteur.js */
window.addEventListener("message.important", traitementDuMessage);
function traitementDuMessage(event) {
// la donnée est accessible dans event.data ou event.detail
}
Il sera préférable de privilégier les Custom Events à window.postMessage() dans tous les cas d’usage.
Avantages | Incovénients |
---|---|
Utilisation simple | Crée des couplages directs entre les applications émettrices et réceptrices, couplages que l’on cherche justement à éviter |
Permet d’assurer la réactivité des données entre les micro frontends d’une même page. | Gestion des différents events peut devenir rapidement complexe en fonction de leur nombre |
Les événements du DOM sont un élément central de la communication entre les micro frontends. Ils offrent une grande flexibilité en permettant la transmission de données riches et complexes, et peuvent être utilisés à n'importe quel niveau de l'application.
Cependant, l'utilisation d'événements peut également créer des couplages entre les micro frontends, ce qui peut poser des problèmes de maintenance à long terme. Il est donc important d'établir des contrats d'interface clairs entre les différentes applications, afin de minimiser les risques de conflits et de faciliter les évolutions futures.
En outre, il convient de noter que les micro frontends qui communiquent avec des événements doivent être présents simultanément dans le DOM. Autrement dit, si l'un des micro frontends n'est pas présent dans la page web, la communication entre les applications sera impossible, ce qui peut poser des problèmes de cohérence et d'interopérabilité.
Solution de state management (Redux / Vuex)
L'approche de composants proposée par les frameworks web modernes tels que React ou Vue implique souvent une hiérarchie parent-enfant pour le passage de données. Cela peut être complexe à gérer, mais des solutions comme Redux (pour React) et Vuex (pour Vue) offrent un système de gestion d'état global pour rendre les données indépendantes des composants.
Cette approche peut également être appliquée à plusieurs micro frontends. Pour cela, il est possible d'attacher des méthodes de lecture (selectors/getters) et de modification (actions) au window, afin que tous les micro frontends puissent y accéder de manière égale. Cela permet de simplifier la gestion des données partagées entre les différentes applications et d'améliorer leur interopérabilité.
Avantages | Incovénients |
---|---|
La donnée partagée est disponible à tout endroit de l’application, et indépendante de tout micro frontend | Cette solution (via window) reste néanmoins dangereuse : n’importe qui peut avoir accès à cet élément via la console du navigateur et donc dans ce cas avoir accès à toutes les données communes en lecture et en écriture, ce qui n’est pas toujours souhaitable. |
Persiste indépendamment des cycles de vie des micro frontends. | |
Permet de conserver la mise à jour des données de façon réactive. |
L'approche actuelle des solutions de state management telles que Redux et Vuex est souvent très liée aux frameworks web tels que React et Vue, ce qui limite leur portabilité et leur intégration avec d'autres micro frontends utilisant d'autres frameworks ou technologies. Cette dépendance peut également rendre la maintenance et l'évolution des applications plus complexe et coûteuse.
Cependant, il existe déjà des alternatives émergentes, telles que les librairies de state management indépendantes de framework, qui permettent de stocker et de partager des données entre différents micro frontends de manière sécurisée et indépendante. Certaines de ces librairies sont basées sur des concepts tels que l'immutabilité des données, qui garantissent que les données partagées ne peuvent pas être modifiées directement, mais seulement par des actions prédéfinies.
sessionStorage / localStorage / cookies
Le stockage de données côté client via le navigateur est un moyen pratique et efficace pour la communication entre différents micro frontends.
- Le sessionStorage est utile pour stocker des données temporaires qui ne doivent être accessibles que dans un seul onglet de navigateur.
- Le localStorage est idéal pour les données qui doivent être partagées entre plusieurs onglets de navigateur mais qui ne nécessitent pas une durée de vie permanente.
- Les cookies peuvent être utilisés pour stocker des informations importantes telles que des identifiants de session ou des préférences d'utilisateur, mais leur utilisation doit être gérée avec précaution en raison des risques de sécurité potentiels.
Avantages | Incovénients |
---|---|
Tout comme le state management, l’avantage principal de ces méthodes est de pouvoir avoir accès en lecture et en écriture à des données globales en tout point de l’application | On retrouve les mêmes inconvénients que précédemment. |
Indépendant des changements de pages | Les objets stockés ne sont qu’au format string |
données rigides: une modification n’entraînera pas de mise à jour dynamique dans les applications, mais seulement au rafraîchissement ou au changement de page | |
Le stockage du localStorage par application est limité par les navigateurs |
En somme, la communication entre les micro frontends est cruciale pour le fonctionnement de l'application globale. Cependant, cela peut être source de complexité et de couplage entre les différentes applications, ce qui peut réduire les avantages du découpage en micro frontends. Il est donc important de réfléchir à la conception de l'architecture pour minimiser les connexions entre les applications et éviter les anti-patterns. Les différents moyens de communication, tels que les events, le stockage de données, ou encore les librairies de state management, doivent être choisis en fonction des besoins spécifiques de chaque application et de leur compatibilité avec le découpage en micro frontends.
Ai-je vraiment besoin des micro frontends ?
Il est également important de se poser des questions sur la communication inter-applications : comment faire en sorte que les micro frontends communiquent efficacement ? Quel modèle de données utiliser ? Comment éviter les couplages trop forts entre les différentes parties de l'application ?
Enfin, il ne faut pas sous-estimer les conséquences de l'implémentation des micro frontends : il peut y avoir des baisses de performances liées à des duplications de code, une gestion supplémentaire de l'application globale avec la communication inter-applications, des problèmes de cohérence de l'expérience utilisateur et une utilisation de CDN pour contrebalancer le temps de réponse des différentes applications.
Malgré ces défis, les micro frontends sont une solution organisationnelle pour les projets à grande échelle, permettant à chaque équipe de se concentrer sur son périmètre et de le maîtriser. Des librairies telles que LitElement et des outils tels que Webpack 5 sont disponibles pour faciliter la configuration des micro frontends au sein d'une application. Cependant, il est important de se poser les bonnes questions et de choisir la solution technique la plus appropriée pour répondre à son besoin.
Concusion
Si vous êtes en train de commencer un nouveau projet et/ou que vous n'avez pas encore besoin d'une architecture complexe pour faire évoluer votre application, il est préférable de se concentrer sur la qualité de votre monolithe avant de le découper. En effet, découper votre application en micro frontends peut créer une complexité supplémentaire et introduire des problèmes de performance. De plus, il existe de nombreuses façons de transformer votre application en micro frontends lorsque cela sera nécessaire.
En revanche, si vous sentez que la complexité de votre application commence à devenir difficile à gérer, alors les micro frontends peuvent être une solution à envisager. Cependant, il est important de savoir comment découper votre site web de manière intelligente. Une approche possible consiste à segmenter votre application en fonction de la logique métier.