Diseñar la Arquitectura del Dashboard Modular

Lectura
25 min~4 min lectura

Concepto clave

Diseñar la arquitectura de un dashboard modular con Module Federation implica descomponer una aplicación monolítica en micro-frontends independientes que pueden ser desarrollados, desplegados y escalados por equipos separados. Imagina un edificio de oficinas donde cada departamento (equipo) diseña y mantiene su propio espacio (micro-frontend), pero todos comparten servicios comunes como ascensores y recepción (shared dependencies).

La clave está en definir límites claros de responsabilidad entre módulos, estableciendo contratos de comunicación bien definidos. Esto permite que equipos trabajen en paralelo sin bloquearse, similar a cómo en una fábrica de automóviles diferentes equipos ensamblan motores, chasis y sistemas eléctricos de forma independiente, pero siguiendo especificaciones precisas para que todo encaje al final.

Cómo funciona en la práctica

Comienza identificando los dominios funcionales del dashboard. Por ejemplo, un dashboard de analítica podría tener: módulo de métricas, módulo de gráficos, módulo de alertas y módulo de configuración. Cada módulo será un micro-frontend independiente.

Paso 1: Define la estructura del proyecto. Crea un repositorio principal (host) y repositorios separados para cada módulo (remotes).

Paso 2: Configura Module Federation en cada proyecto. El host expone componentes compartidos y consume los remotes. Los remotes exponen sus módulos específicos.

Paso 3: Establece contratos de comunicación usando eventos personalizados o un estado global ligero (como Zustand) para interacciones entre módulos.

Paso 4: Implementa estrategias de despliegue independiente, asegurando versionado semántico y pruebas de integración automatizadas.

Codigo en accion

Configuración básica de Module Federation en el host (dashboard principal):

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

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

Configuración de un remote (módulo de métricas):

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

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

Errores comunes

  • Acoplamiento excesivo entre módulos: Evita que los módulos dependan directamente de la implementación interna de otros. Usa contratos basados en props o eventos.
  • Mala gestión de dependencias compartidas: No compartas librerías que cambian frecuentemente. Comparte solo dependencias estables como React.
  • Falta de estrategia de versionado: Sin versionado semántico claro, los despliegues independientes pueden romper la aplicación. Implementa tests de integración.
  • Comunicación ineficiente entre módulos: No uses callbacks complejos. Opta por un bus de eventos ligero o estado global.
  • Ignorar el rendimiento de carga: Carga perezosa de módulos no críticos. Usa dynamic imports para módulos grandes.

Checklist de dominio

  1. ¿He definido límites claros entre módulos basados en dominios funcionales?
  2. ¿Cada módulo puede ser desarrollado y desplegado independientemente?
  3. ¿Los contratos de comunicación entre módulos están documentados y son estables?
  4. ¿Las dependencias compartidas están minimizadas y versionadas correctamente?
  5. ¿Existe una estrategia de pruebas de integración automatizadas?
  6. ¿La arquitectura soporta la adición de nuevos módulos sin refactorizar el core?
  7. ¿Se ha considerado el rendimiento de carga inicial y lazy loading?

Diseñar y configurar un dashboard modular con dos micro-frontends

En este ejercicio, crearás un dashboard modular con Module Federation que incluya dos micro-frontends independientes.

  1. Crea tres proyectos React separados: uno como host (dashboard principal) y dos como remotes (módulo de usuarios y módulo de productos).
  2. Configura Module Federation en cada proyecto usando Webpack 5. El host debe consumir ambos remotes.
  3. En el remote de usuarios, expone un componente UserList que muestre una lista de usuarios simulada.
  4. En el remote de productos, expone un componente ProductTable que muestre una tabla de productos.
  5. Integra ambos componentes en el host, renderizándolos en secciones separadas del dashboard.
  6. Implementa un bus de eventos simple usando CustomEvents para que al hacer clic en un usuario en UserList, se actualice ProductTable mostrando solo los productos de ese usuario.
  7. Despliega los proyectos localmente en puertos diferentes y verifica que funcionen correctamente.
Pistas
  • Usa create-react-app con webpack 5 para generar los proyectos rápidamente.
  • Asegúrate de que las dependencias compartidas (react, react-dom) tengan la misma versión en todos los proyectos.
  • Para el bus de eventos, define un nombre de evento constante y usa dispatchEvent en el remoto y addEventListener en el host.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.