Concepto clave
En arquitecturas de micro-frontends, la comunicacion entre aplicaciones federadas y el manejo de estado compartido son desafios criticos. Un sistema de notificaciones federado permite que diferentes micro-frontends se comuniquen de forma desacoplada, similar a como un sistema de mensajeria corporativa conecta departamentos independientes sin que cada uno conozca los detalles internos de los otros.
Module Federation de Webpack habilita este patron mediante la exposicion y consumo de modulos entre aplicaciones. El estado compartido se gestiona tipicamente a traves de un event bus o un store global accesible por todos los micro-frontends, manteniendo la autonomia de cada aplicacion mientras permiten interacciones coordinadas.
Como funciona en la practica
Imagina tres micro-frontends: una aplicacion principal (shell), un panel de usuario y un sistema de alertas. El shell expone un modulo de notificaciones que otros consumen. Paso a paso:
- El shell configura Module Federation para exponer un modulo
notifications. - El panel de usuario consume este modulo y registra eventos (ej: "usuario-actualizado").
- El sistema de alertas tambien consume el modulo y escucha esos eventos para mostrar notificaciones.
- Cuando el panel de usuario dispara un evento, el sistema de alertas reacciona sin acoplamiento directo.
Esto se implementa usando Webpack 5 con configuraciones especificas en cada aplicacion, compartiendo codigo en tiempo de ejecucion.
Codigo en accion
Configuracion del shell (aplicacion principal) que expone el modulo de notificaciones:
// webpack.config.js del shell
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
// ... otras configuraciones
plugins: [
new ModuleFederationPlugin({
name: "shell",
filename: "remoteEntry.js",
exposes: {
"./notifications": "./src/notifications/eventBus.js",
},
shared: ["react", "react-dom"],
}),
],
};
// src/notifications/eventBus.js
export class EventBus {
constructor() {
this.listeners = {};
}
emit(event, data) {
if (this.listeners[event]) {
this.listeners[event].forEach(callback => callback(data));
}
}
on(event, callback) {
if (!this.listeners[event]) this.listeners[event] = [];
this.listeners[event].push(callback);
}
}
export const eventBus = new EventBus();Consumo desde un micro-frontend (panel de usuario):
// webpack.config.js del panel de usuario
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: "userPanel",
remotes: {
shell: "shell@http://localhost:3000/remoteEntry.js",
},
shared: ["react", "react-dom"],
}),
],
};
// Componente que usa el modulo federado
import React, { useEffect } from "react";
const UserPanel = () => {
useEffect(() => {
import("shell/notifications").then(module => {
const { eventBus } = module;
// Emitir evento cuando el usuario se actualiza
eventBus.emit("usuario-actualizado", { userId: 123, action: "edit" });
});
}, []);
return Panel de Usuario;
};
export default UserPanel;Errores comunes
- Ciclos de dependencia: Configurar remotes de forma circular entre aplicaciones, causando errores de carga. Solucion: Diseñar una topologia jerarquica clara.
- Versionado inconsistente: Compartir librerias como React con versiones diferentes, llevando a errores en runtime. Solucion: Usar
sharedcon versiones exactas y estrategias de resolución. - Eventos no tipados: Emitir eventos sin estructura definida, dificultando el debug. Solucion: Definir contratos de eventos con TypeScript o documentacion.
- Falta de manejo de errores: No capturar fallos en la carga de modulos remotos. Solucion: Implementar retries y estados de fallback.
- Acoplamiento excesivo: Micro-frontends que dependen demasiado de detalles internos de otros. Solucion: Limitar la comunicacion a eventos genericos y APIs publicas.
Checklist de dominio
- Configurar Module Federation para exponer y consumir modulos entre al menos dos aplicaciones.
- Implementar un event bus o store global accesible via modulos federados.
- Manejar ciclos de vida de modulos remotos (carga, error, actualizacion).
- Garantizar consistencia en dependencias compartidas (ej: React, estado).
- Diseñar una estrategia de versionado para modulos federados.
- Probar la comunicacion en diferentes entornos (dev, prod).
- Documentar los contratos de eventos y APIs expuestas.
Implementar un Sistema de Notificaciones Federado entre Tres Micro-frontends
En este ejercicio, construiras un sistema de notificaciones que permita a tres micro-frontends independientes comunicarse usando Module Federation de Webpack. Sigue estos pasos:
- Configura el entorno: Crea tres aplicaciones React independientes (shell, userPanel, alertSystem) con Webpack 5. Instala Module Federation via
npm install webpack webpack-cli webpack-dev-server. - Configura el shell: En la aplicacion shell, configura Module Federation para exponer un modulo
notificationsque contenga un event bus. Usa el codigo de ejemplo de la leccion como base. - Configura los micro-frontends: En userPanel y alertSystem, configura Module Federation para consumir el modulo
notificationsdel shell. Asegurate de que compartan dependencias como React correctamente. - Implementa la comunicacion: En userPanel, agrega un boton que, al hacer clic, emita un evento
"usuario-actualizado"via el event bus. En alertSystem, escucha este evento y muestra una notificacion en la interfaz (ej: un mensaje emergente). - Prueba la integracion: Ejecuta las tres aplicaciones en puertos diferentes (ej: 3000, 3001, 3002) y verifica que la notificacion se muestre correctamente cuando se activa el evento.
- Agrega manejo de errores: Implementa un fallback en alertSystem en caso de que el modulo
notificationsno cargue, mostrando un mensaje de error amigable. - Documenta el flujo: Crea un diagrama simple que muestre como los eventos fluyen entre las aplicaciones y anade comentarios al codigo explicando las decisiones clave.
- Usa Webpack Dev Server con diferentes puertos para cada aplicacion y configura CORS si es necesario.
- Considera usar una libreria como "events" para el event bus si prefieres no implementarlo desde cero, pero exponla via Module Federation.
- Para compartir estado mas complejo, explora opciones como Redux o Zustand federados, pero empieza con un event bus simple.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.