Crear tu Primer Micro-frontend Básico

Lectura
25 min~4 min lectura

Concepto clave

Module Federation de Webpack es una tecnología que permite a aplicaciones web independientes cargar código de otras aplicaciones en tiempo de ejecución. Imagina un edificio de apartamentos donde cada departamento es una aplicación completa con su propia cocina, baño y sala, pero comparten servicios como el ascensor y la recepción. En Module Federation, cada micro-frontend es como un apartamento: autónomo, pero puede usar componentes o funciones de otros apartamentos cuando sea necesario.

La clave está en que no necesitas reconstruir todo el edificio cada vez que cambias un apartamento. Cada micro-frontend se construye y despliega por separado, y en tiempo de ejecución, Webpack coordina la carga de módulos remotos. Esto es fundamental para arquitecturas distribuidas donde equipos diferentes trabajan en partes distintas del frontend, permitiendo actualizaciones independientes sin afectar el todo.

Cómo funciona en la práctica

Para crear tu primer micro-frontend básico, sigue estos pasos: primero, configura dos proyectos independientes: uno como host (la aplicación principal) y otro como remote (el micro-frontend). En el remote, defines qué módulos exponer al exterior usando la configuración de Module Federation. En el host, configuras qué módulos remotos consumir. Webpack genera archivos especiales que permiten la comunicación entre ambos.

Por ejemplo, si tienes un equipo trabajando en un carrito de compras y otro en un catálogo de productos, el carrito puede exponer un componente CartButton que el catálogo consume dinámicamente. Al construir, Webpack crea un manifest que lista los módulos disponibles, y en tiempo de ejecución, el host carga el módulo remoto solo cuando se necesita, reduciendo el tamaño inicial de la aplicación.

Codigo en accion

Configuración básica en el remote (micro-frontend):

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

module.exports = {
  output: {
    publicPath: "http://localhost:3001/",
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "remoteApp",
      filename: "remoteEntry.js",
      exposes: {
        "./Button": "./src/components/Button",
      },
      shared: ["react", "react-dom"],
    }),
  ],
};

Configuración en el host (aplicación principal):

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

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

Uso en el host para cargar el componente remoto:

// En un componente del host
import React, { Suspense } from "react";
const RemoteButton = React.lazy(() => import("remoteApp/Button"));

function App() {
  return (
    

Aplicación Host

Cargando...
}> ); } export default App;

Errores comunes

  • Error en la URL pública: Si publicPath en el remote no coincide con la URL de despliegue, el host no podrá cargar los módulos. Verifica que sea accesible y use HTTPS en producción.
  • Versiones incompatibles de dependencias compartidas: Al definir shared como ["react", "react-dom"], asegúrate de que host y remote usen versiones compatibles; de lo contrario, pueden ocurrir errores en tiempo de ejecución. Usa rangos semánticos en package.json.
  • Falta de manejo de carga: No usar Suspense o manejo de errores al importar módulos remotos puede causar caídas en la interfaz. Siempre envuelve las importaciones dinámicas en componentes de carga.
  • Configuración incorrecta de nombres: El name en ModuleFederationPlugin debe ser único y coincidir con la referencia en remotes. Un typo aquí rompe la comunicación.

Checklist de dominio

  1. Configurar un proyecto remote que exponga al menos un módulo usando Module Federation.
  2. Configurar un proyecto host que consuma un módulo remoto y lo renderice correctamente.
  3. Verificar que las dependencias compartidas estén alineadas entre host y remote.
  4. Probar la carga dinámica con Suspense para manejar estados de carga y error.
  5. Desplegar ambos proyectos en entornos separados y asegurar la comunicación vía URLs públicas.
  6. Optimizar el rendimiento configurando lazy loading solo para módulos necesarios.
  7. Documentar la arquitectura para otros equipos, incluyendo convenciones de nombres y versionado.

Crear un micro-frontend de carrito de compras consumible

En este ejercicio, crearás un micro-frontend básico que simule un carrito de compras y lo consumirás desde una aplicación host. Sigue estos pasos:

  1. Inicia dos proyectos React independientes usando Create React App: uno llamado cart-remote y otro shop-host.
  2. En cart-remote, instala Webpack 5 y el plugin Module Federation. Configura el webpack.config.js para exponer un componente CartSummary que muestre un mensaje simple como "Carrito: 3 items".
  3. En shop-host, configura Module Federation para consumir el componente CartSummary desde cart-remote. Asegúrate de definir las dependencias compartidas como react y react-dom.
  4. En el host, crea una página que importe dinámicamente CartSummary usando React.lazy y Suspense, y renderízalo en la interfaz.
  5. Ejecuta ambos proyectos en puertos diferentes (ej. 3001 para remote, 3000 para host) y verifica que el componente se cargue correctamente.
  6. Prueba a cambiar el mensaje en el remote y recarga el host para ver la actualización sin reconstruir el host.
Pistas
  • Asegúrate de que el publicPath en el remote apunte a la URL correcta donde se sirve el remoteEntry.js.
  • Usa la consola del navegador para depurar errores de carga de módulos, revisando la red y los mensajes de Webpack.
  • Si hay errores de versión, verifica que ambos proyectos usen las mismas versiones mayores de react y react-dom en package.json.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.