Module Federation 2.0 est “stable”. Cool. Sauf que la stabilité d’un outil ne garantit pas la stabilité de ton produit. Les micro-frontends, ça peut te débloquer une org entière… ou te fabriquer une usine à incidents où chaque release ressemble à un tirage de Jenga.
Je te propose un tri simple et sans romance : quand MF2 vaut vraiment le coût, où ça casse en prod, ce que les nouveautés changent concrètement, et les garde-fous minimum si tu décides d’y aller.
Module Federation 2.0 “stable” : ce que ça change vraiment (et ce que ça ne change pas)
Le gros mouvement de MF2, c’est la promesse d’être moins “collé” à webpack. En pratique, ça veut dire un runtime et une approche plus portables, avec du support annoncé/évoqué pour plusieurs toolchains et environnements (Rspack, Rollup/Rolldown, Vite, Rsbuild, Metro…) et même des scénarios côté Node.js. Si tu as déjà vécu le « oui mais nous on n’est plus sur webpack », tu vois l’intérêt.
Mais attention au piège mental : “agnostique bundler” ne veut pas dire “agnostique réalité”. Les problèmes qui font mal avec les micro-frontends restent les mêmes : contrats de versions, partage de dépendances, CSS qui fuit, runtime errors, perf, cache, observabilité, et surtout responsabilités floues entre équipes. MF2 rend certaines intégrations plus accessibles. Il ne supprime pas le coût d’exploitation.
Sponsorisé par Le Scribouillard
Besoin de contenu optimisé SEO ?
Utilisez la meilleure plateforme française de création de contenu assistée par IA ! Et générez des articles pour moins de 1€ !
Les vrais cas où les micro-frontends valent le coût (sinon tu te punis)
Le cas qui justifie MF, ce n’est pas « on veut faire moderne ». C’est quand tu as une application qui devient une plateforme : plusieurs équipes, plusieurs cycles de release, et une vraie nécessité de livrer indépendamment sans se marcher dessus tous les jours. Quand une équipe doit pouvoir shipper une feature sans attendre une release “mère”, la fédération peut être un accélérateur net.
Ça marche aussi quand ton produit est naturellement modulaire, avec des domaines qui s’isolent bien. Typiquement : un backoffice énorme avec des zones qui n’ont quasiment pas d’UI partagée, ou un portail où chaque “verticale” est un mini-produit. Dans ces cas-là, l’architecture te donne déjà des frontières. MF vient juste les rendre déployables.
Enfin, il y a un cas plus “terrain” que j’ai vu réussir : quand tu dois intégrer des morceaux hétérogènes (legacy + nouveau, ou plusieurs stacks) mais que tu veux une expérience utilisateur unifiée. MF peut jouer le rôle de pont, à condition d’assumer que c’est une étape de migration, pas une religion.
Les coûts cachés : là où ça casse pour de vrai (souvent 6 mois après)
Le premier coût, c’est la cohérence UI/UX. Au début, tout le monde promet de respecter le design system. Puis tu as un micro-frontend qui embarque une version légèrement différente du DS, un autre qui surcharge des styles « temporairement », et tu te retrouves avec une app où deux boutons “primaires” ne se ressemblent plus. Ce n’est pas juste moche : ça crée des bugs, des régressions et une perte de confiance côté produit.
Le second, c’est la duplication de dépendances et les effets de bord. Le monde idéal, c’est un partage propre de React, des libs d’état, des utilitaires, et une compat totale. Le monde réel, c’est « on a mis à jour une lib dans un remote, et ça explose ailleurs ». Tu peux aussi te retrouver avec deux React chargés, ou des copies de bibliothèques lourdes qui rendent ton bundle “split” très théorique.
Le troisième, c’est le cache et le versioning. En micro-frontends, tu déploies indépendamment. Donc tu acceptes un état où le shell A parle à remote B, et parfois A a été mis à jour mais pas B (ou inversement), avec des utilisateurs qui gardent des assets en cache. Si ton système de cache busting et de compat de versions n’est pas solide, tu fabriques des bugs « impossibles à reproduire » qui arrivent seulement à 3% des users.
Et le dernier coût, celui qui fait vraiment mal en prod : le runtime. Les erreurs de chargement de remote, les timeouts, les 404 d’assets, les CORS mal réglés, la CDN qui sert un vieux fichier, un remote down… tout ça n’est pas un cas edge. C’est ton quotidien si tu ne mets pas de garde-fous d’exploitation.
Les nouveautés MF2 qui comptent : support hors webpack, types TS, side effects scanner
Le support au-delà de webpack est probablement la nouveauté la plus “politique” et la plus utile. Elle baisse la barrière d’entrée pour des équipes sur Vite/Rollup-like, Rspack, Metro, ou des environnements hybrides. Si ton organisation bouge vite côté tooling, MF2 peut éviter de te retrouver coincé dans un coin avec « l’archi dépend de webpack ».
Les type hints TypeScript dynamiques pour les remotes sont intéressants pour une raison simple : dans une fédération, l’API entre le host et le remote est un contrat. Et les contrats, sans typage, finissent en runtime errors ou en docs qui mentent. Avoir quelque chose de plus fluide côté TS, c’est une vraie amélioration de DX, mais ça ne remplace pas une discipline de versioning. Ça rend juste le mensonge plus dur à écrire.
Le Side Effect Scanner est, à mon avis, un signal très sain. Les micro-frontends souffrent énormément de pollution globale : styles qui “leak”, variables globales, monkey patch, initialisations cachées. Pouvoir détecter ce genre de comportement, c’est exactement le genre de feature qui te sauve d’un incident idiot. Par contre, ne le lis pas comme une garantie. C’est un radar, pas un bouclier.
Mes garde-fous minimum si tu veux que “ça marche” (pas juste une démo)
Le premier garde-fou, c’est un contrat de versions explicite. Tu dois décider ce qui est shared, ce qui est embarqué, et comment tu gères les incompatibilités. Et tu dois le décider avant de fédérer 15 remotes. Sinon, tu vas improviser au fil des incidents, ce qui est le meilleur moyen de finir avec une architecture incohérente.
Je veux aussi un budget perf écrit noir sur blanc, et mesuré. Pas “on fera attention”. Un budget. Les micro-frontends peuvent améliorer le time-to-market, mais ils peuvent aussi te donner une app qui télécharge plus, parse plus, initialise plus, et devient lente pour des raisons difficiles à attribuer à une équipe précise. Si personne n’a la responsabilité du poids global, tout le monde le dégrade.
Sur la CSS, je ne négocie plus : isolation ou discipline très stricte. Les fuites de styles sont un tueur silencieux parce qu’elles ne “cassent” pas toujours. Elles dégradent, elles rendent l’UI imprévisible, elles créent une dette de debug atroce. CSS Modules, CSS-in-JS avec scoping propre, shadow DOM sur certains widgets… peu importe la méthode, mais il faut une stratégie assumée.
Dernier point, le plus “prod” : observabilité et rollback. Tu dois pouvoir savoir quel remote a été chargé, en quelle version, et corréler ça à des erreurs runtime. Et tu dois avoir un plan de repli quand un remote est cassé. Ça peut être un fallback UI, un mode dégradé, un flag de désactivation, ou le fait de servir une version précédente. Mais “on verra” est un plan qui finit à 2h du matin.
Un exemple concret : verrouiller React en singleton (sinon tu joues avec le feu)
Le détail varie selon l’outil, mais l’intention reste la même : partager React en singleton et éviter les écarts de versions non contrôlés. Sinon, tu t’exposes à des comportements bizarres (hooks, context, hydration) et à des bugs qui ressemblent à de la magie noire.
// Intention : 1 React, 1 ReactDOM, versions compatibles, pas d'instances multiples.
// La syntaxe exacte dépend de l'intégration MF2 / bundler, mais c'est CE contrat-là qu'il faut.
const shared = {
react: { singleton: true, requiredVersion: "^18.2.0" },
"react-dom": { singleton: true, requiredVersion: "^18.2.0" }
};Si tu hésites : alternatives plus simples (et souvent meilleures)
Si ton vrai besoin, c’est « plusieurs devs travaillent sur des zones différentes sans se gêner », un monorepo avec des packages internes fait souvent le job, avec beaucoup moins de risques runtime. Tu gardes une release unifiée (donc une cohérence de versions), tu factorises proprement, et tu peux quand même faire du découpage en libs, en features, en domaines.
Si ton problème, c’est le poids initial, commence par regarder du côté de lazy loading et du découpage route-level. C’est moins sexy que “micro-frontends”, mais ça règle énormément de cas d’usage. Et surtout, ça ne te force pas à gérer la compat entre plusieurs déploiements indépendants.
Et si tu veux de l’indépendance d’équipe, parfois la réponse est organisationnelle : des boundaries claires, un design system versionné, un ownership de modules, et des règles de contribution. Les micro-frontends peuvent aider, mais ils ne remplacent pas une org qui sait gérer des interfaces et des contrats.
Conclusion : MF2 n’est pas une feature, c’est un modèle d’exploitation
Module Federation 2.0 qui devient stable et plus agnostique, c’est une bonne nouvelle. Ça élargit le terrain de jeu, ça enlève un peu de friction tooling, et certaines features (comme la détection d’effets de bord) vont dans le bon sens.
Mais si ton objectif numéro un, c’est « mon produit doit juste marcher », la question n’est pas “est-ce que MF2 est prêt ?”. La question est : est-ce que ton équipe est prête à exploiter une app distribuée côté front avec ses contrats, ses versions, son observabilité, ses modes dégradés. Si la réponse est “pas vraiment”, une solution plus simple te fera souvent gagner… du temps et de la sérénité.