¡Compártelo!

Angular en microfrontends: ventajas y uso

A medida que las aplicaciones web se vuelven más complejas, la necesidad de arquitecturas flexibles, escalables y mantenibles se hace más evidente. En este contexto, surgen los microfrontends, una arquitectura inspirada en la filosofía de los microservicios del lado del backend, donde la aplicación frontend se divide en módulos o “micro aplicaciones” independientes. Por otro lado, gracias a su sólido ecosistema y soporte nativo para el desarrollo modular, Angular en microfrontends se ha convertido en una de las herramientas clave en este enfoque. En este artículo abordaremos cómo implementar Angular en un entorno de microfrontends: qué ventajas ofrece, cómo integrarlo, la gestión de estados y mejores prácticas. Al finalizar, tendrás una visión clara de cómo adoptar este patrón y aplicarlo en tus propios proyectos a gran escala.

¿Qué son los microfrontends?

Antes que nada vamos a entender mejor qué son los microfrontends. Son una arquitectura moderna que divide una aplicación frontend monolítica en una serie de componentes o módulos más pequeños, autónomos y desplegables de forma independiente. 

Estos módulos pueden estar construidos con diferentes frameworks (Angular, React, Vue), diferentes lenguajes o incluso equipos de desarrollo trabajando de manera aislada, siempre que se definan contratos claros de comunicación.

La idea es que, en lugar de tener una sola base de código gigantesca y monolítica que crece en complejidad con el tiempo, podamos dividirla en bloques más pequeños. Cada bloque se encarga de una funcionalidad específica (por ejemplo, el módulo de gestión de usuarios, el módulo de pagos, el módulo de catálogos, etc.). 

Esto facilita la escalabilidad horizontal del equipo de desarrollo y la autonomía de cada unidad, reduciendo el riesgo de introducir problemas en todo el sistema al hacer cambios en una sola parte.

Ventajas de implementar microfrontends en Angular

1. Modularidad nativa

Angular, desde su concepción, se basa en un enfoque modular, esto permite estructurar la aplicación en módulos bien definidos, con áreas de responsabilidad claras. Este patrón se alinea muy bien con el concepto de microfrontends, ya que cada uno puede verse como un módulo Angular independiente (o una serie de módulos).

2. Tipado y escalabilidad

El uso de TypeScript, el sistema de tipado estático integrado en Angular, ofrece mayor seguridad y mantenibilidad en el tiempo. Al crecer la aplicación y dividirse en microfrontends, el tipado fuerte ayuda a prevenir errores y asegura el correcto acoplamiento entre las partes.

3. Herramientas del ecosistema

Angular CLI, Angular Schematics y el sólido ecosistema de librerías y herramientas simplifican el desarrollo, prueba y despliegue de microfrontends. Esto también incluye mecanismos robustos de lazy loading, enrutamiento modular y un sistema de dependencias bien estructurado.

Dividiendo la aplicación en módulos con Angular

Para implementar microfrontends, el primer paso es estructurar adecuadamente la aplicación. Imaginemos un escenario: tienes una aplicación grande de e-commerce desarrollada en Angular. Esta aplicación puede abarcar módulos como:

  • Módulo de catálogo de productos: presenta los productos, buscador, filtros, etc.
  • Módulo de detalle de producto: muestra el detalle de un producto seleccionado.
  • Módulo de carrito y checkout: gestiona los ítems en el carrito, el proceso de compra y el pago.
  • Módulo de usuario: permite registrar, iniciar sesión, mostrar el perfil, etc.

En un enfoque monolítico, todos estos módulos conviven dentro de una misma aplicación Angular. Sin embargo, con microfrontends podemos separarlos en distintas aplicaciones que se integran en un shell principal.

Pasos para la división

  • Identificación de límites de dominios: determina cuáles partes de la aplicación se pueden aislar de forma independiente. Por ejemplo, el módulo de “Carrito y Checkout” podría ser un microfrontend completo, cuyo frontend se desarrolla, versiona y despliega aparte.
  • Creación de librerías o paquetes internos: aprovecha Angular Libraries (ng generate library) para extraer código compartido. Estas librerías pueden incluir componentes comunes, servicios de comunicación con APIs, modelos de datos y utilidades. Además,se publican en un repositorio interno y se pueden consumir desde cada microfrontend.
  • Lazy loading y enrutamiento: el lazy loading es clave para modularizar. Cada microfrontend puede exponerse a través de rutas y cargarse bajo demanda. Por ejemplo, en la aplicación shell (aplicación anfitriona), al navegar a “/carrito”, se carga el microfrontend del Carrito que está alojado en otro bundle independiente.
  • Comunicación entre microfrontends: es importante definir cómo se comunicará el shell principal con los microfrontends. Esto puede hacerse a través de eventos del navegador, servicios compartidos inyectados vía DI (Dependency Injection) o canales de mensajería como RxJS Subjects expuestos entre microfrontends.

Integración con otras tecnologías

La gran ventaja de los microfrontends es que no estamos casados con un solo framework. Si bien Angular puede ser la elección principal, puedes tener otro equipo trabajando con React para el módulo de recomendaciones o con Vue para la sección de reseñas de usuarios.

Afortunadamente, existen patrones y herramientas para integrar estos módulos.

Posibles enfoques de integración

  • Web Components: angular permite crear componentes encapsulados como Web Components gracias a la API de Angular Elements. Estos Web Components pueden ser consumidos por cualquier otro framework, siempre que se les pase la información necesaria a través de propiedades o eventos custom. De esta manera, el microfrontend Angular se integra de forma transparente en una aplicación React o viceversa.
  • Módulos federados con Module Federation (Webpack 5): la federación de módulos es una técnica que permite cargar código remoto en tiempo de ejecución. Un microfrontend Angular podría exponer su AppModule o componentes específicos como módulos federados, que luego el shell principal consume. Con Webpack Module Federation la integración entre distintas bases de código es más sencilla y mantiene la separación lógica entre equipos.
  • Comunicación vía APIs REST o GraphQL: si la lógica de negocio se encuentra en un backend de microservicios, es posible que los diferentes microfrontends solo necesiten datos que puedan obtener a través de llamadas HTTP. Cada microfrontend puede ser completamente independiente y solo comunicarse con el backend y con el shell principal a través de endpoints bien definidos.

Gestión de estados en un entorno de microfrontends

Uno de los mayores retos en entornos con microfrontends es la gestión del estado. En una aplicación monolítica Angular, se podría usar NgRx, NgXs u otra solución de estado global. Sin embargo, en un ambiente distribuido, debemos pensar cuidadosamente en cómo y dónde mantener el estado.

Opciones de gestión de estado

  • Estado local dentro de cada microfrontend: cada microfrontend maneja su propio estado con NgRx u otra librería, manteniéndolo aislado del resto. Esto facilita la independencia, pero si necesitamos compartir cierta información (por ejemplo, el ID del usuario logueado o el token de autenticación) con otros microfrontends, debemos definir un mecanismo de intercambio.
  • Estado centralizado en el shell principal: el shell principal podría actuar como un “contenedor” que mantiene ciertos datos globales (estado de la sesión, configuración inicial u opciones de idioma). Cada microfrontend solicita esta información al shell a través de un servicio compartido o eventos globales.
  • Herramientas externas para el estado global: otra opción es utilizar un “event bus” o un contenedor de estado global basado en algo como RxJS Subjects en el shell, al que cada microfrontend se suscribe. También existen soluciones más avanzadas como usar un Data Layer global (similar al concepto del data layer en Tag Managers) donde los microfrontends lanzan eventos y el shell los distribuye.
  • El objetivo principal es minimizar las dependencias entre microfrontends y garantizar que el estado que debe compartirse esté disponible de forma clara y segura, evitando acoplamientos excesivos.

Mejores prácticas para optimizar el rendimiento

La adopción de microfrontends, si no se hace con cuidado, puede introducir sobrecarga en el rendimiento. Tener múltiples bundles, frameworks y puntos de entrada puede generar tiempos de carga más altos. Por ello, es fundamental seguir ciertas buenas prácticas.

Recomendaciones clave

  • Lazy loading y carga bajo demanda: ya mencionado anteriormente, el lazy loading es clave. Carga cada microfrontend sólo cuando el usuario lo requiera. Esto reduce el tiempo de carga inicial y mejora la percepción de rendimiento.
  • Caché y CDN: al tratar con múltiples microfrontends, es posible que cada uno se despliegue por separado. Asegúrate de servir los archivos estáticos (JavaScript, CSS, imágenes) desde CDNs de alto rendimiento y habilitar el caché del navegador.
  • Optimización de dependencias comunes: si varios microfrontends están construidos con Angular, busca formas de compartir dependencias comunes (como el runtime de Angular) a través del shell principal. Así evitarás duplicar dependencias en cada microfrontend. Webpack Module Federation facilita este tipo de configuración.
  • Uso de Web Components o Micro-librerías: para partes críticas del frontend que requieren alta velocidad, podrías adoptar componentes web nativos o librerías más pequeñas en lugar de frameworks pesados.
  • Monitoreo y métricas de rendimiento: implementa métricas de rendimiento (Lighthouse, Web Vitals) y registra datos para entender qué partes de la aplicación tardan más en cargar.

Flujo de trabajo y estrategias de despliegue

La implementación de Angular en microfrontends requiere también un cambio en la organización general. Algunas buenas prácticas en el flujo de trabajo incluyen:

Buenas prácticas

  • Automatización del pipeline CI/CD
  • Versionado independiente
  • Contrato de interfaces y comunicación clara

Angular en microfrontends como arquitectura del futuro

La implementación de Angular en microfrontends ofrece una potente combinación: la robustez del framework, su enfoque modular nativo y la capacidad de integrar diferentes tecnologías y equipos de forma ordenada. 

Al dividir una aplicación grande en módulos más pequeños y autónomos, se gana escalabilidad, facilidad de mantenimiento, mayor independencia entre equipos y la posibilidad de evolucionar partes del sistema sin impactar en el resto.

Es fundamental entender que la transición hacia microfrontends no es sólo una decisión técnica, sino también un cambio completo en la arquitectura y en la organización. Sin embargo, si se adoptan buenas prácticas y se monitoriza el rendimiento, es posible construir soluciones flexibles que crezcan sin sacrificar la calidad.

Así, Angular en microfrontends hace posible un desarrollo más ágil, flexible y escalable. Ayudando a las organizaciones a adaptarse rápidamente a las demandas de los usuarios y del mercado, sin la complicación que suponían los antiguos monolitos frontales.

¡Sigue aprendiendo sobre Angular y más mundo tech en nuestras redes sociales!

Artículos ​ relacionados