Micro-frontends: El futuro del desarrollo web moderno

Margarita Syddall
Flux IT Thoughts

--

Arranquemos por lo básico. El concepto “micro-frontend” se refiere a una arquitectura vertical. El sistema se basa en pequeños y reutilizables módulos, independientes entre sí, que forman una única aplicación.

Diagrama explicativo:

Tres módulos independientes que juntos forman un ecommerce. Uno contiene el desarrollo del header y del footer, otro el desarrollo del carrito de compras y el tercero contiene el desarrollo de la home. El último consume el header y el footer por un lado y el carrito por el otro.

Un poco de historia

Haciendo un breve repaso de la historia de los sistemas arquitectónicos, sabemos que antes las aplicaciones se desarrollaban como un monolito; back y front formaban parte de un mismo bloque. No es necesario aclarar que las desventajas (riesgos, dificultades para el desarrollo y conflictos por resolver en cada fusión) eran evidentes.

Luego, back y front se separaron convirtiéndose en dos bloques independientes, lo que, si bien flexibilizó el desarrollo, al fin y al cabo, traía las mismas desventajas.

Entre el 2012 y 2014, se introdujo el concepto de microservicios en el back end. El back es ahora una aplicación formada por varios servicios que pueden desplegarse de forma independiente.

Por otro lado, en el front end, surgió el concepto de sistemas autocontenidos o Self-Contained Systems, un modelo de arquitectura enfocado en el desarrollo e implementación independiente de sus partes que se comunican entre sí a través de links (modelo de arquitectura vertical).

A partir de esto, en 2016 surgió por primera vez el concepto de micro-frontends, que desde entonces va adquiriendo cada día más popularidad a la hora de pensar en un proyecto escalable.

Hoy en día, reconocidas aplicaciones como Spotify, Netflix, Amazon, Airbnb, entre otras, tienen su arquitectura basada en MFs.

Beneficios

  • Implementación rápida y accesible: Al ser aplicaciones independientes con una responsabilidad específica es menor el tiempo que se invierte en los pipelines y el deployment. Esto resulta en una mejor experiencia para cada Developer y reduce el riesgo de errores.
  • Minimización de fallas y tareas bloqueantes: Las fallas y bloqueos en un módulo no afectan a los demás.
  • Simplificación de testing: Al ser aplicaciones con responsabilidades únicas y con límites definidos, se facilita el testeo de funciones y componentes.
  • Optimización de memoria: Cada micro-frontend cuenta solo con sus propias librerías y herramientas necesarias, optimizando el uso de la memoria. Debido a que el navegador solo carga el módulo necesario, esto resulta más rápido que si se tuviera que cargar toda la aplicación, logrando así un mejor rendimiento.
  • Equipos especializados: Debido a que el sistema está formado por varias aplicaciones independientes, existe la posibilidad de formar equipos autónomos especializados para cada módulo, potenciando las habilidades de cada integrante.

Si bien no puedo señalar desventajas específicas del uso de micro-frontends, sí cabe aclarar que no es una arquitectura aplicable a cualquier caso y que hay varios puntos por tener en cuenta para lograr la implementación exitosa de este modelo:

  • Principio de la responsabilidad única: Para separar nuestro proyecto en varias aplicaciones independientes, debemos definir con precisión cuál será la función y responsabilidad de cada una, para asegurarnos así de un flujo correcto en la comunicación entre dichas apps.
  • Lineamientos de diseño: Entendiendo que este modelo se puede aplicar en equipos grandes y con proyección, es importante que todo el equipo esté al tanto del diseño y estilos esperados del proyecto para que no existan diferencias entre los módulos que puedan generar una mala experiencia para las personas usuarias.
  • Estados independientes: Es importante evitar compartir estados entre las aplicaciones, porque de esta manera dejarían de ser independientes entre sí.

Aplicando micro-frontends

Existen varias maneras de implementar MFs en nuestro desarrollo: herramientas como Single-Spa, Module Federation y SystemJS son las más usadas.

En este artículo estaremos abordándolo a través del plug-in ModuleFederation de Webpack5.

Por un lado, existe un comando que resuelve todas las complicaciones de configuración y deja el código listo para que empecemos a desarrollar y conectar aplicaciones.

npx create-mf-app

Muy similar al resultado que obtenemos de CRA (create-react-app), este comando crea un archivo llamado webpack.config.js donde sucede toda la magia. Dicho archivo tiene todas las configuraciones necesarias para buildear nuestra app y consumir los archivos necesarios, como estilos, imágenes, etc. Este cuenta con una clave llamada plugins que cuenta con un array con varios plugins de webpack. Uno de ellos es ModuleFederationPlugin que contiene:

  • name: Corresponde al nombre que le daremos a la aplicación en la que estamos trabajando.
  • filename: Corresponde al archivo que se creará con la información necesaria para que la puedan consumir otras aplicaciones. Por convención, su valor será ‘remoteEntry.js’
  • remotes: Un objeto que contiene la información de las aplicaciones remotas, es decir las consumidas por la aplicación en cuestión. Cada aplicación consumida tendrá un nombre (igual al name designado es su propio webpack.config) y una URL.
  • exposes: Contiene los componentes para compartir con otras aplicaciones.
  • shared: Contiene las dependencias que se compartirán entre aplicaciones para que el navegador no las cargue más de una vez.
webpack.config.js example

Archivo de configuración de webpack en App host:

Archivo de configuración de webpack en App remote:

Migrar una app de CRA a MF

En caso de querer migrar una aplicación creada con CRA a MF son varios los obstáculos, ¡pero no es imposible!

Lo primero que tenemos que saber es que CRA cuenta con varias dependencias y configuraciones que están por detrás del código que podemos ver; no podremos encontrarlas en nuestro package.json y por esto no podremos editarlas fácilmente y mucho menos instalar nuevas versiones.

Una de estas dependencias es webpack versión 3.

Ya que ModuleFederationPlugin está disponible a partir de la versión 5, tenemos que romper con las configuraciones por default de nuestro CRA con el comando npm run eject. Este comando nos trae las dependencias permitiéndonos editarlas o eliminarlas, pero a su vez rompe sus configuraciones, así que dependerá de nosotros el desarrollo de dichas configuraciones para que nuestra aplicación vuelva a funcionar.

Cabe aclarar que este comando es definitivo y una vez corrido no podremos volver atrás.

Una vez hecho esto, seguiremos los mismos pasos para poder conectar nuestra aplicación con otras a través de Module Federation.

Conclusión

Lo más importante para tener en cuenta al momento de encarar un proyecto basado en micro-frontends es que, lejos de ser una solución mágica, será un desafío tras otro. Esta arquitectura aún se sigue perfeccionando, y no hay una única receta para lograr el mejor resultado.

Pero si estamos desarrollando una app con cierta complejidad o buscando una arquitectura que nos permita obtener un flujo de desarrollo eficiente y autónomo, los micro-frontends son la opción ideal para lograr un código escalable y performante.

Agradecimientos

Este artículo está escrito con la colaboración de mi líder fluxer Leonardo Galdames, Technical Leader en Flux IT. Disfrutá la lectura!

Conocé más sobre Flux IT: Website · Instagram · LinkedIn · Twitter · Dribbble · Breezy

--

--

Margarita Syddall
Flux IT Thoughts

Front-end developer building cool stuff with React. Also a total aerial acrobat and nature enthusiast. 🌎✨ Living in Buenos Aires. Don't forget to clap!