Saltar a contenido

Microfrontend

Autor Fagundez Antony.

Introducción

El término de microfrontends apareció a finales de 2016, cómo la respuesta natural a los microservicios llevados al browser por la aparición de aplicaciones cada vez más complejas del lado del frontend.

Ya que la definición en gran parte es muy reciente, hemos hecho un análisis con los microfrontends actualmente implementados en la compañía, para llegar y tratar de vislumbrar una definición que sea válida en la compañía, en dónde estamos y hacia dónde deberían ir los esfuerzos generales.

Actualidad

Actualmente se ha implementado microfrontends en dos áreas, por un lado, el DMS, por su enfoque modular y en Punto de terceros, ambos conservan el mismo enfoque.

¿Cómo está organizado?

Se encuentran en distintos repositorios, permitiendo distintos ciclos de cicd, aplicaciones puras de React, con un nginx de proxy reverso para reforzar la seguridad.

Arquitectura

Se basa principalmente en dos tipos de aplicación, el Shell que es el orquestador, que se encarga de inyectar en el DOM los scripts de los microfrontends, se encarga de routing y de la seguridad. Por el momento esta inyección se hace de todos los microfrontends justo al momento de inicio.

Y de las aplicaciones, o microfront que contienen páginas o extractos que comparten el layout impuesto y la información brindada por el Shell. Cada uno de estos módulos agrega un render que es una función que se encarga del renderizado, dicha función se agrega directamente en el objeto global window.

mfe mfe

Por cómo está implementado los microfronts no pueden ni modificar ni alterar el contexto global, es unidireccional, no existen casos de usos actuales dónde se necesite cambiar el contexto global.

En la mayoría de los casos actuales se usan los microfronts por rutas específicas.

¿Qué es microfrontend?

Ha evolucionado estos últimos años la definición en sí misma, pero podemos discernir ciertos puntos que definen que es un microfrontend * CICD particular * Poder consumir el contexto global, única fuente de información. * Debe ser lo suficientemente desacoplado para que la aplicación exista sin un microfrontend. * Existe una plataforma para comunicarse entre ambos * Agnóstico a la tecnología. *

  • Actualmente en Andreani se definió React cómo tecnología del front, por lo tanto, este punto no está cubierto en la actualidad.

Por lo tanto si no reúne la mayoría de estas características podríamos estar hablando realmente de estándar web. (Redirecciones, subdominios y aplicaciones totalmente distintas una de la otra)

Ahora en la actualidad existen distintas herramientas o formas de encarar un microfrontend.

IFrame

Con las configuraciones necesarias de seguridad y un manejo de eventos adecuados podemos trabajar con microfrontends a través de Iframes, es habitual su uso en casos de migraciones parciales de aplicaciones antiguas. Por su nivel de seguridad e intercomunicación entre microfrontends, se desaconseja su uso recurrentemente en la comunidad.

Inyección en el DOM

Es la manera en que actualmente se hace en la compañía, en el caso que expusimos brevemente.

Module Federation

Es la manera más moderna de poder consumir JavaScript de una forma remota. Pasan a ser dependencias en Runtime.

Se agregó como un plugin más a partir de Webpack 5, y está actualmente bastante optimizada para solo compartir el código necesario. Se puede configurar para que “comprenda” que hay dependencias en común que están a cargo del Shell (React, React-router, Redux).

No está limitado netamente a microfrontend, sino también a librerías que se pueden exponer desde un puerto especifico.

Para hacer la comparativa de Module Federation con lo actual nos dispusimos a hacer una Prueba de concepto.

Build-time microfrontend

Es la manera más habitual de hacer microfrontend, y exponerlo por lo general de una librería, acá suele ser muy confuso y las separaciones en base a las mismas serían definidas por negocio, cuando le corresponda a otro equipo, pero viva en una aplicación que otro equipo deba realizar, sería un microfrontend.

¿Qué diferencia a un microfrontend en build-time y a un componente?

Es el principal punto de diferenciación que podríamos hacer. Una funcionalidad específica y completamente autónoma podría ser un diferencial base de un componente y un microfrontend en tiempo de build.

Supongamos una tarjeta que se comunica con un servicio por sí mismo y renderiza la información necesaria, eso sería un microfrontend.

PoC

Detalle

Para esto creamos todo basados en aplicaciones base con React 17. CRA (CLI por default de React), Stylesystem, Redux y con Docker siguiendo los estándares actuales. Para la configuración sólo debemos cambiar ciertos archivos iniciales para que se ejecute el import de forma dinámica, a efectos de la PoC, lo hicimos extendiendo la configuración de CRA con un plugin que permite sobrescribirlo y un plugin que configura justo Module Federation. (React-app-rewired)

En este caso la configuración puede hacerse con variables en tiempo de ejecución de entorno tranquilamente, haciéndolo compatible con el sistema actual de CICD.

En esta configuración se puede indicar cuales son las dependencias que son singleton y que se comparten a través de los microfrontends (evitando posible duplicidad de dependencias), aparte por debajo Webpack resuelve, cuando son usadas, y pueden consumir distintas versiones anidadas en el node_modules ( con sus excepciones especificas)

Se comprobó el uso de Azure B2C, compartiendo información de la cuenta con el microfrontend, y el mismo solo siendo accesible si está autenticado.

  • Shell: La aplicación Shell maneja autenticación y provee a través de propiedades la información de la cuenta del usuario.
  • Module: Microfront cómo modulo con una ruta específica, y sus rutas anidadas, y configurado para poder desarrollar sólo el microfront, por separado del container, y en build solo exponer el JavaScript sin la aplicación (seguridad).

mfe

Check de requerimientos

  1. Por la complejidad y el tema de atarnos a client-side-rendering preferiblemente este caso de uso debería considerarse sobre aplicaciones, vs webs.
  2. Configuración extendida de Webpack, o configuración custom.

Ventajas y Desventajas

Module Federation puede presentar las siguientes desventajas 1. En ocasiones puede resultar en un overkill para ciertas aplicaciones. 2. No contiene versionado hoy por hoy los módulos federados. 3. Está soportado actualmente sólo por webpack. (Hay acercamientos interesantes por la comunidad en vite, pero nada lo suficientemente estable). 4. El módulo remoto puede correr por si mismo pero las rutas anidadas en modo desarrollo tienen conflictos actualmente con la configuración de module Federation Por el contrario, tiene las siguientes ventajas: 1. Las dependencias son compartidas, por lo que podrían compartir una misma instancia de la dependencia (caso Redux y/o caso React). 2. Es gratuito y tiene soporte oficial de Webpack. (hay algunos plugins pagos en caso de que necesitemos un caso avanzado, cómo streaming o server side rendering). 3. No representa un cambio de esquema para las aplicaciones actuales. 4. La dinámica de cómo se carga el microfront se encarga Webpack por debajo, es transparente en la implementación. 5. No necesita prefetch en la carga inicial, lo hace a través de Dynamic imports. 6. Hay ejemplos actualmente para tener microfronts React consumiendo microfronts en Vue. 7. Microsoft, Netflix, Reddit, Alibaba, entre otras ya están usando module Federation.

Conclusión

Podemos concluir este análisis argumentando que, por un lado, ambas estrategias de microfrontends contienen similitudes, pero Module Federation nos ofrece el soporte de la comunidad y el proyecto en sí mismo para obtener los beneficios de esta. Por otro lado, puede presentar un beneficio en performance el hecho de no cargar todo en el inicio de la aplicación (prefetch) y hacerlo dinámicamente, e inclusive el hecho de las dependencias compartidas y la noción de estas (evitar duplicidad por ejemplo de React).

La recomendación es optar por microfrontend en el caso del que la complejidad de negocio lo requiera, y optar por estándar web en el caso que no sea necesario este overkill. Por lo que sugiere que a medida que se más una aplicación web se puede considerar el caso de uso de microfronts, a sabiendas de las complicaciones que esta decisión puede acarrear

mfe

Anexo

Prueba de PoC

Se disponibilizó dos repositorios con los desarrollos mencionados en esta PoC, se disponibilizaron a sí mismos como templates en la organización de arquitectura:

Shell: https://github.com/architecture-it/template-microfront-shell Module:https://github.com/architecture-it/template-microfront-remote

Aplicación en vivo: https://shell-architecture-it-test.apps.ocptest.andreani.com.ar/