Volver al blog

Micro Frontends: Cómo Escalar Aplicaciones Frontend Con Arquitectura Modular

Hola HaWkers, si trabajas en una empresa con equipos grandes de frontend o en un monolito que está difícil de mantener, probablemente ya oíste hablar de micro frontends. Esta arquitectura promete traer al frontend los mismos beneficios que microservicios trajeron al backend.

¿Pero vale la pena? ¿Y cómo implementar de forma que no se convierta en una pesadilla? Vamos a explorar esto en profundidad.

Qué Son Micro Frontends

Micro frontends es una arquitectura donde una aplicación web es dividida en partes menores e independientes, cada una desarrollada, testeada y desplegada separadamente.

Analogía simple:

  • Monolito frontend = Una tienda donde todos los departamentos comparten la misma caja
  • Micro frontends = Un shopping donde cada tienda opera independientemente

Características principales:

  1. Independencia de deploy - Cada parte puede ser actualizada sin afectar las otras
  2. Autonomía de equipo - Equipos diferentes pueden trabajar en partes diferentes
  3. Tecnología agnóstica - Cada parte puede usar tecnologías diferentes
  4. Aislamiento de fallas - Problemas en una parte no tumban el sistema entero

🏗️ Contexto: El término fue acuñado en 2016, pero ganó tracción a partir de 2019 cuando empresas como IKEA, Spotify y DAZN compartieron sus experiencias.

Cuándo Usar Micro Frontends

Antes de adoptar esta arquitectura, necesitas tener certeza de que resuelve un problema real:

Señales de Que Necesitas

Indicadores organizacionales:

  • Múltiples equipos trabajando en el mismo frontend
  • Conflictos constantes de merge
  • Deploy bloqueado esperando otras features
  • Tiempo de build/test muy largo
  • Dificultad de onboarding de nuevos devs

Indicadores técnicos:

  • Aplicación con cientos de miles de líneas de código
  • Bundle size muy grande
  • Performance de desarrollo degradada
  • Tests lentos demás

Señales de Que NO Necesitas

Cuándo evitar:

  • Equipo pequeño (menos de 10 desarrolladores frontend)
  • Aplicación de tamaño medio
  • Dominio de negocio fuertemente acoplado
  • Startup en fase inicial
  • Equipo sin experiencia en arquitectura distribuida

Regla de oro: Si no tienes problemas claros de escala u organización, micro frontends va a adicionar complejidad sin beneficio.

Patrones de Implementación

Existen varias formas de implementar micro frontends. Veamos las principales:

1. Module Federation (Webpack 5+)

El abordaje más moderno y popular actualmente:

// webpack.config.js del Host (Shell)
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'host',
      remotes: {
        // Carga micro frontend de carrito de otro servidor
        cartMfe: 'cartMfe@http://localhost:3001/remoteEntry.js',
        // Carga micro frontend de productos
        productsMfe: 'productsMfe@http://localhost:3002/remoteEntry.js',
      },
      shared: {
        react: { singleton: true, requiredVersion: '^18.0.0' },
        'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
      },
    }),
  ],
};

// webpack.config.js del Micro Frontend de Carrito
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'cartMfe',
      filename: 'remoteEntry.js',
      exposes: {
        './Cart': './src/components/Cart',
        './CartButton': './src/components/CartButton',
      },
      shared: {
        react: { singleton: true, requiredVersion: '^18.0.0' },
        'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
      },
    }),
  ],
};

Uso en el Host:

// App.jsx en el Host
import React, { Suspense } from 'react';

// Importación dinámica del micro frontend remoto
const RemoteCart = React.lazy(() => import('cartMfe/Cart'));
const RemoteProducts = React.lazy(() => import('productsMfe/ProductList'));

function App() {
  return (
    <div className="app">
      <header>Mi Tienda</header>

      <main>
        <Suspense fallback={<div>Cargando productos...</div>}>
          <RemoteProducts />
        </Suspense>
      </main>

      <aside>
        <Suspense fallback={<div>Cargando carrito...</div>}>
          <RemoteCart />
        </Suspense>
      </aside>
    </div>
  );
}

2. Single-SPA

Framework dedicado para orquestar micro frontends:

// root-config.js
import { registerApplication, start } from 'single-spa';

// Registra micro frontend de navegación
registerApplication({
  name: '@myorg/navbar',
  app: () => System.import('@myorg/navbar'),
  activeWhen: ['/'],
});

// Registra micro frontend de productos (activo en /products)
registerApplication({
  name: '@myorg/products',
  app: () => System.import('@myorg/products'),
  activeWhen: ['/products'],
});

// Registra micro frontend de checkout (activo en /checkout)
registerApplication({
  name: '@myorg/checkout',
  app: () => System.import('@myorg/checkout'),
  activeWhen: ['/checkout'],
});

start();

Comunicación Entre Micro Frontends

Uno de los mayores desafíos es hacer los micro frontends comunicarse:

Event Bus

Patrón simple y eficaz:

// eventBus.js - Compartido entre todos los MFEs
class EventBus {
  constructor() {
    this.events = {};
  }

  subscribe(event, callback) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);

    // Retorna función para unsubscribe
    return () => {
      this.events[event] = this.events[event].filter((cb) => cb !== callback);
    };
  }

  publish(event, data) {
    if (this.events[event]) {
      this.events[event].forEach((callback) => callback(data));
    }
  }
}

// Singleton global
window.eventBus = window.eventBus || new EventBus();
export default window.eventBus;

Uso:

// En el MFE de Productos
import eventBus from '@shared/eventBus';

function ProductCard({ product }) {
  const addToCart = () => {
    eventBus.publish('cart:add', {
      productId: product.id,
      quantity: 1,
    });
  };

  return (
    <div className="product">
      <h3>{product.name}</h3>
      <button onClick={addToCart}>Agregar al Carrito</button>
    </div>
  );
}

// En el MFE de Carrito
import eventBus from '@shared/eventBus';

function Cart() {
  const [items, setItems] = useState([]);

  useEffect(() => {
    const unsubscribe = eventBus.subscribe('cart:add', (data) => {
      setItems((prev) => [...prev, data]);
    });

    return unsubscribe;
  }, []);

  return <div>{/* Renderiza items */}</div>;
}

Desafíos y Trampas

Micro frontends traen complejidad. Prepárate:

1. Consistencia de UI

Problema: Cada MFE puede tener estilos diferentes.

Solución: Design System compartido

// @myorg/design-system - Paquete npm interno
export { Button } from './components/Button';
export { Card } from './components/Card';
export { theme } from './theme';
export { GlobalStyles } from './GlobalStyles';

2. Duplicación de Dependencias

Problema: React cargado múltiples veces.

Solución: Shared dependencies en Module Federation

shared: {
  react: {
    singleton: true,
    requiredVersion: '^18.0.0',
    eager: true
  }
}

3. Performance

Problema: Múltiples requests de red.

Soluciones:

  • Prefetch de MFEs críticos
  • Service workers para cache
  • CDN compartido

4. Tests End-to-End

Problema: ¿Cómo testar la aplicación completa?

Solución: Ambiente de integración dedicado

# docker-compose.integration.yml
services:
  shell:
    build: ./packages/shell
    ports:
      - '3000:3000'

  cart-mfe:
    build: ./packages/cart
    ports:
      - '3001:3001'

  products-mfe:
    build: ./packages/products
    ports:
      - '3002:3002'

Herramientas del Ecosistema

El ecosistema evolucionó bastante en 2024-2025:

Build y Bundling

Herramienta Uso Soporte MFE
Webpack 5 Module Federation nativo Excelente
Vite vite-plugin-federation Bueno
Rspack Module Federation Excelente
esbuild Customización necesaria Básico

Frameworks de Orquestación

Framework Complejidad Madurez
Single-SPA Alta Alta
Module Federation Media Alta
Qiankun Media Media
Luigi (SAP) Alta Alta

Monorepo Tools

Para gestionar múltiples MFEs:

  • Nx - Más popular, óptimo soporte a MFE
  • Turborepo - Performance, integración Vercel
  • Lerna - Clásico, menos features
  • pnpm workspaces - Leve y eficiente

Conclusión

Micro frontends son una herramienta poderosa para escalar equipos y aplicaciones grandes. Pero como toda arquitectura distribuida, traen complejidad que necesita ser justificada.

Usa si:

  • Tienes múltiples equipos independientes
  • Aplicación genuinamente grande
  • Problemas claros de escala
  • Equipo experiente en sistemas distribuidos

Evita si:

  • Equipo pequeño o medio
  • Aplicación de tamaño normal
  • Buscando solución para problemas organizacionales
  • Sin experiencia en arquitectura distribuida

Si decides implementar, comienza pequeño: extrae un MFE, aprende con los desafíos, y escala gradualmente. La peor cosa que puedes hacer es migrar todo de una vez.

Para complementar tu conocimiento en arquitecturas modernas de frontend, recomiendo revisar el artículo Vite vs Webpack en 2025 donde vas a entender las herramientas de build que soportan estas arquitecturas.

¡Vamos a por ello! 🦅

💻 Domina JavaScript de Verdad

El conocimiento que adquiriste en este artículo es solo el comienzo. Hay técnicas, patrones y prácticas que transforman desarrolladores principiantes en profesionales requeridos.

Invierte en Tu Futuro

Preparé un material completo para que domines JavaScript:

Formas de pago:

  • 1x de R$9,90 sin intereses
  • o R$9,90 al contado

📖 Ver Contenido Completo

Comentarios (0)

Este artículo aún no tiene comentarios 😢. ¡Sé el primero! 🚀🦅

Añadir comentarios