Saltar al contenido

Lección 14 de 16 · Lectura y práctica

Implementar Componentes Federados y Comunicación

Concepto claveLos componentes federados son módulos de UI que se desarrollan, despliegan y ejecutan de forma independiente, pero que pueden ser consumidos dinámicamente por otras aplicaciones en tiempo de ejecución. Imagina una.

Del concepto a la práctica

Taller de esta lección

La implementación integradora debe coordinar componentes y comunicación sin convertir al host en dueño de cada detalle. Props sirven para datos dirigidos al componente; eventos sirven para hechos que pueden tener varios consumidores. Elegir uno evita contratos ambiguos.

Ejemplo resuelto

El host pasa selectedTeam='alpha' a Métricas. Incidencias emite incident:selected con { id: 'I-4' }; el host actualiza una región contextual sin leer el estado interno de Incidencias. El contrato no contiene referencias a componentes React.

Pruébalo

  1. Clasifica cada dato como entrada dirigida o hecho publicado.

  2. Implementa la prop para el equipo seleccionado.

  3. Publica el evento al seleccionar I-4 y registra un único consumidor.

  4. Haz que la integración que monta Incidencias sea propietaria de la suscripción; al desmontar esa integración, elimina su listener y comprueba el contador de callbacks. Error frecuente: pasar una función interna del remoto al host y después compartir sus estructuras privadas. Corrección: convierte la interacción en prop simple o evento versionado.

Comprueba tu resultado

Con selectedTeam='alpha' y una selección de I-4, el resultado esperado es Métricas mostrando alpha e información contextual con I-4. Cambiar el estado interno de Incidencias sin emitir el evento no debe alterar el host.

Navegador, API y base de datos conectados por solicitudes, consultas y respuestas en sentidos opuestos.
CursaloMapa de práctica
Del navegador a los datos

El navegador envía una solicitud a la API. El servidor valida la operación y consulta los datos; después devuelve una respuesta que el navegador puede mostrar. La base de datos se comunica con el servidor y no directamente con el navegador.

Ver la infografía en tamaño completo ↗

Concepto clave

Los componentes federados son módulos de UI que se desarrollan, despliegan y ejecutan de forma independiente, pero que pueden ser consumidos dinámicamente por otras aplicaciones en tiempo de ejecución. Imagina una ciudad donde cada edificio (micro-frontend) tiene su propia administración y reglas, pero comparten servicios públicos (componentes federados) como parques o bibliotecas que cualquier residente puede usar sin necesidad de construirlos desde cero.

La comunicación entre micro-frontends es crucial para mantener la coherencia del estado y la experiencia de usuario. En lugar de acoplar las aplicaciones, se establecen contratos claros mediante eventos, props compartidos o un estado global ligero. Piensa en cómo los departamentos de una empresa colaboran: cada uno tiene autonomía, pero se coordinan mediante reuniones (eventos) y documentos compartidos (estado), evitando interferir en los procesos internos del otro.

Cómo funciona en la práctica

Para implementar componentes federados, primero defines un remote en Webpack que expone módulos específicos. Luego, en la aplicación host, configuras un remotes para consumir esos módulos. La magia ocurre en tiempo de ejecución: cuando el host necesita un componente, Webpack lo carga dinámicamente desde el remote, inyectándolo en la aplicación como si fuera local.

La comunicación se maneja típicamente mediante un bus de eventos o un store compartido. Por ejemplo, si un componente federado de carrito de compras necesita notificar a la aplicación host sobre un cambio, emite un evento custom. El host escucha ese evento y actualiza su estado o UI correspondiente. Esto mantiene el desacoplamiento: el componente no necesita saber detalles de implementación del host, solo sigue el contrato definido.

Codigo en accion

Configuración en el remote (app-productos):

// webpack.config.js del remote
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "productos",
      filename: "remoteEntry.js",
      exposes: {
        "./ProductCard": "./src/components/ProductCard",
        "./ProductList": "./src/components/ProductList"
      },
      shared: ["react", "react-dom"]
    })
  ]
};

Consumo en el host (app-principal):

// webpack.config.js del host
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "principal",
      remotes: {
        productos: "productos@http://localhost:3001/remoteEntry.js"
      },
      shared: ["react", "react-dom"]
    })
  ]
};

// Uso en un componente React del host
import React, { Suspense } from 'react';
const ProductCard = React.lazy(() => import("productos/ProductCard"));

function App() {
  return (
    Cargando...}>
       {
        // Emitir evento o actualizar store compartido
        window.dispatchEvent(new CustomEvent('cart-update', { detail: product }));
      }} />
    
  );
}

Errores comunes

  • Version mismatch de dependencias compartidas: Si el remote y el host usan versiones diferentes de React, pueden ocurrir errores críticos. Solución: Usa shared en Webpack con versiones exactas o rangos compatibles, y considera herramientas como singleton para bibliotecas clave.
  • Comunicación acoplada: Implementar comunicación directa entre componentes (ej., llamadas a funciones internas) rompe la independencia. Solución: Usa eventos custom o un store global ligero (como Zustand o Redux con namespaces) que defina contratos claros.
  • Falta de manejo de errores en carga dinámica: Si el remote falla, la aplicación host puede bloquearse. Solución: Envuelve los imports dinámicos en Error Boundaries en React y provee fallbacks UX.
  • Omitir el lazy loading: Cargar todos los remotes al inicio impacta el performance. Solución: Usa React.lazy o import() dinámico solo cuando el componente sea necesario.
  • Configuración incorrecta de CORS: En entornos de desarrollo o producción, los remotes pueden bloquearse por políticas de seguridad. Solución: Configura headers CORS apropiados en el servidor del remote y usa HTTPS en producción.

Checklist de dominio

  1. Configuré exitosamente un remote que expone al menos dos componentes federados.
  2. Implementé un host que consume dinámicamente componentes de múltiples remotes.
  3. Establecí un mecanismo de comunicación (eventos o store) entre host y remotes sin acoplamiento.
  4. Manejé errores de carga y versiones en dependencias compartidas.
  5. Optimicé el performance con lazy loading y chunk splitting.
  6. Probé la arquitectura en un entorno local y simulado de producción.
  7. Documenté los contratos de comunicación para otros equipos.

Crear un ecosistema de micro-frontends con carrito federado

En este ejercicio, construirás un sistema donde una app principal (host) consume componentes de dos remotes independientes: uno para productos y otro para carrito, con comunicación en tiempo real.

  1. Configura tres proyectos React independientes: app-host, app-productos, y app-carrito. Usa Webpack 5 con Module Federation.
  2. En app-productos, expone un componente ProductList que muestre una lista de productos. Cada producto debe tener un botón "Agregar al carrito".
  3. En app-carrito, expone un componente CartSummary que muestre el número de ítems en el carrito y un total.
  4. En app-host, consume ambos componentes y renderízalos en una misma página. Implementa comunicación: cuando se hace clic en "Agregar al carrito" en ProductList, el CartSummary debe actualizarse automáticamente.
  5. Usa un bus de eventos global (puedes implementar uno simple con window.dispatchEvent y window.addEventListener) para la comunicación. Asegúrate de que los componentes no tengan dependencias directas entre sí.
  6. Prueba el sistema: ejecuta los tres proyectos en puertos diferentes (ej., 3000, 3001, 3002) y verifica que la comunicación funcione sin errores.
Pistas
  • Usa shared: ['react', 'react-dom'] en todas las configuraciones de Module Federation para evitar versiones duplicadas.
  • Para el bus de eventos, define un nombre de evento constante (ej., 'cart-updated') y pasa datos en el detail del CustomEvent.
  • Considera usar Suspense y fallbacks en el host para manejar la carga asíncrona de componentes federados.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con Arquitectura de Micro-frontends con Module Federation de Webpack

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.