Concepto clave
Module Federation de Webpack es una arquitectura que permite a aplicaciones web independientes cargar código de otras aplicaciones en tiempo de ejecución. Imagina un edificio modular donde cada departamento (micro-frontend) tiene su propia entrada y funcionalidad, pero comparten servicios comunes como el ascensor o la recepción. En este contexto, Module Federation actúa como el sistema de compartimentación que permite a cada módulo exponer y consumir componentes sin necesidad de un build monolítico.
La clave está en la federación: cada aplicación mantiene su independencia de desarrollo y despliegue, pero puede integrar componentes de otras aplicaciones como si fueran locales. Esto es crucial para equipos distribuidos que trabajan en diferentes partes de una plataforma, permitiendo actualizaciones independientes y reduciendo acoplamiento. No se trata solo de dividir código, sino de crear un ecosistema donde cada pieza evoluciona a su ritmo.
Cómo funciona en la práctica
Para implementar un componente federado, necesitas dos roles: un host (consumidor) y un remote (proveedor). El remote expone componentes a través de su configuración de Webpack, definiendo qué módulos están disponibles para otros. El host configura qué remotes puede consumir y los carga dinámicamente cuando son necesarios.
Paso a paso: primero, en el remote, defines en webpack.config.js qué componentes exportarás. Luego, en el host, configuras la referencia al remote y usas import() dinámico para cargar el componente. Webpack maneja la carga asíncrona y el sharing de dependencias, asegurando que librerías como React no se dupliquen. Esto permite, por ejemplo, que un equipo desarrolle un carrito de compras y otro lo integre en su aplicación sin coordinación de builds.
Codigo en accion
Configuración en el remote (app-carrito/webpack.config.js):
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
output: {
publicPath: "http://localhost:3001/",
},
plugins: [
new ModuleFederationPlugin({
name: "carrito",
filename: "remoteEntry.js",
exposes: {
"./CarritoComponent": "./src/components/CarritoComponent",
},
shared: {
react: { singleton: true, eager: true },
"react-dom": { singleton: true, eager: true },
},
}),
],
};
Uso en el host (app-productos/src/App.js):
import React, { Suspense } from 'react';
const CarritoComponent = React.lazy(() => import("carrito/CarritoComponent"));
function App() {
return (
Productos
Cargando carrito...}>
);
}
export default App;
Errores comunes
- PublicPath incorrecto: Si el publicPath en el remote no coincide con la URL de despliegue, el host no podrá cargar el módulo. Verifica que sea accesible desde el navegador.
- Sharing de dependencias mal configurado: No definir shared o usar versiones incompatibles puede causar errores de duplicación. Usa singleton: true para React y asegura versiones iguales.
- Falta de Suspense: Olvidar envolver el componente federado en Suspense resultará en errores de carga. Siempre maneja estados de carga.
- Nombre del remote inconsistente: El name en ModuleFederationPlugin debe coincidir con el usado en el import del host. Un typo rompe la federación.
- No probar en producción: Las configuraciones locales pueden funcionar, pero fallar en entornos con CORS o HTTPS. Prueba con builds reales.
Checklist de dominio
- Configurar ModuleFederationPlugin en un proyecto para exponer un componente.
- Consumir un componente federado desde otro proyecto usando import dinámico.
- Manejar shared dependencies para evitar duplicación de librerías.
- Implementar error boundaries o Suspense para estados de carga.
- Verificar que el remoteEntry.js sea accesible públicamente.
- Probar la integración en un entorno de desarrollo con múltiples puertos.
- Documentar la API expuesta por el remote para otros equipos.
Crear y consumir un componente de header federado
En este ejercicio, implementarás un sistema donde una aplicación host consume un componente Header desde un remote. Sigue estos pasos:
- Crea dos proyectos React independientes: app-header (remote) y app-main (host). Usa create-react-app o tu setup preferido.
- En app-header, configura webpack con ModuleFederationPlugin para exponer un componente Header que muestre un logo y un menú simple. Asegúrate de definir shared para react y react-dom.
- En app-main, configura webpack para consumir el remote app-header. Usa React.lazy y Suspense para cargar el Header dinámicamente.
- Ejecuta ambas aplicaciones en puertos diferentes (ej: 3001 y 3002) y verifica que app-main muestre el Header correctamente.
- Modifica el componente Header en app-header y recarga app-main para ver los cambios sin rebuild del host.
Objetivo: Tener un header federado funcionando entre dos apps separadas.
Pistas- Asegúrate de que el publicPath en el remote apunte a la URL correcta donde se sirve la app.
- Usa la consola del navegador para depurar errores de carga de módulos, revisando la red.
- Si hay errores de CORS, configura los headers apropiados en el servidor de desarrollo.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.