Microfrontends Federados a Escala

Spanish audio is available in the player settings
Rate this content
Bookmark

La charla será una historia de cómo Personio pasó de renderizar a través de una arquitectura monolítica de PHP, a una aplicación Next JS orientada a microfrontends, impulsada por la Federación de Módulos y la herramienta NX monorepo.

31 min
02 Jun, 2023

Video Summary and Transcription

Esta charla discute la transición desde un monolito de PHP hasta una configuración federada de microfrontends en Personio. Implementaron la orquestación y la federación utilizando Next.js como anfitrión de módulos y enrutador. El uso de módulos federados y la biblioteca de integración permitieron un único tiempo de ejecución mientras se construía e implementaba de forma independiente. La charla también destaca la importancia de los primeros adoptantes y los desafíos de construir un sistema de código abierto interno.

Available in English

1. Introducción a los Micro-Frontends

Short description:

Hablemos de micro-frontends, del tipo federado. La arquitectura frontend de Personio ha pasado por tres momentos diferentes: monolito de PHP, micro-frontends dependientes del monolito y configuración federada de micro-frontends. El cambio fue necesario porque el monolito se convirtió en una bestia mítica y la empresa creció más rápido que sus conceptos arquitectónicos. Así que, Personio cambió a micro-frontends, con aplicaciones separadas en repositorios separados, activos almacenados en AWS S3 y una aplicación independiente de React renderizada en los navegadores de los usuarios.

Ya me presentaron, pero, ya saben, mi nombre es Daniel. Llevo unos 10 años trabajando en cosas de frontend y actualmente trabajo como ingeniero principal en Personio. Pueden encontrarme allí en caso de que lo que diga sea interesante. Y hoy estoy aquí para contarles una pequeña historia. Es una historia sobre el cambio, sobre la evolución, pero sobre todo, sobre cómo estamos gestionando más de 60 micro-frontends propiedad de docenas de equipos y manteniendo nuestra cordura mientras lo hacemos, la mayor parte del tiempo.

Así que, sí. La historia comienza, por supuesto, con el cambio y lo que está cambiando en este caso es la arquitectura frontend de Personio, que en sus ocho años de existencia ha pasado por tres momentos diferentes. El primero fue el monolito de PHP, algo muy simple, el monolito recibía solicitudes, las gestionaba, y enviaba cosas al cliente. Luego, el esfuerzo de Personio con los micro-frontends, aún dependiendo en gran medida del monolito para los datos y como vehículo de renderizado, y finalmente, lo que llamamos configuración federada de micro-frontend que es el punto principal de la charla de hoy. No se preocupen por el tamaño de los gráficos, los veremos más grandes más adelante. Y comencemos primero con, bueno, antes de eso, cuando hablamos de cambio, creo que lo más importante que hay que decir sobre el cambio es por qué se necesitaba el cambio, ¿verdad? Porque eso muchas veces también informa por qué terminamos donde terminamos. Así que comencemos con el primer momento, cómo Personia llegó a existir y por qué tuvimos que alejarnos de él. Como dije, la mayoría de la gente lo llamaría legado. Yo lo llamo vintage, porque se aprecia con el tiempo, ya saben, es algo que genera dinero. No me gusta la palabra legado, todavía tiene connotaciones negativas. Pero es una aplicación monolítica de PHP Laravel, hace absolutamente de todo, y la gente que construyó Personia comenzó el proyecto, se hizo popular, se le agregaron características y seguimos agregando características. Y saben, miras atrás un par de años después y tu proyecto, que comenzó bastante bien, de repente se ve así. Es una bestia mítica, muy poderosa, pero también muy desordenada. Y eso es lo que le sucedió a Personia, ya saben, la empresa creció más rápido que sus conceptos arquitectónicos podían seguir. Específicamente en el frontend, se veía así. Teníamos jQuery coexistiendo con Laravel y React, y desplegar cualquier cosa llevaba una hora y media o dos horas, si tenías suerte, así que algo tenía que cambiar.

Así que cambió a través de la distribución. Ahora, si estuvieron en la escena del frontend en 2019, la palabra de moda más ocupada era micro-frontends. Eso es lo que hizo Personia. Construyeron micro-frontends y nuestra versión de micro-frontends se veía algo como esto. Teníamos aplicaciones separadas en repositorios separados bajo un único framework que era React. En el momento de la compilación, estas aplicaciones enviaban los activos al almacenamiento de archivos en el bucket de AWS S3 y también sincronizaban su última compilación con un servicio interno llamado Servicio de Artefactos. Este servicio mantenía un mapa de la aplicación con los activos, algo así. Luego, cuando el monolito recibía una solicitud, le preguntaba al Servicio de Artefactos, oye, ¿qué activos debo renderizar aquí?, los pasaba al cliente, luego se descargaban, JavaScript hacía su trabajo y una aplicación independiente de React se renderizaba y se montaba en los navegadores de los usuarios.

2. Orquestación y Federación

Short description:

Entonces, hicimos la transición de un monolito a microfrontends separados, lo cual inicialmente resolvió algunos problemas pero creó ineficiencias. Para abordar esto, introdujimos la orquestación, que implicaba el renderizado a través de algo diferente al monolito. Implementamos la federación, donde los módulos son expuestos y consumidos por un controlador central en tiempo de ejecución, permitiendo lanzamientos de módulos separados. El orquestador frontend actúa como un controlador ligero y funciona como un enrutador para mapear las URL a los módulos.

Entonces, para darles una idea visual de cómo se veía esto, este es el panel de control de Personio, y pasamos de esto, el monolito que hacía absolutamente todo, a algo como esto, donde teníamos dos aplicaciones separadas, dos microfrontends separados, eran independientes, no compartían nada. Y esto fue realmente bueno. Resolvimos parte de los problemas, como que las personas no podían trabajar de forma independiente, teníamos un desorden, todo mezclado, y el despliegue era doloroso. Pero también tenía sus desventajas, ¿saben? Compartir cosas como el estado, dependencias comunes, todo era muy difícil, requería mucha coordinación, y después de un tiempo decidimos que realmente no valía la pena el esfuerzo de compartir cosas, así que cada aplicación tenía todo en sí misma, y era muy ineficiente. Además, estábamos descontinuando el monolito, por lo que el vehículo de renderizado iba a desaparecer, que es probablemente la razón principal por la que tuvimos que construir algo diferente, ¿verdad?

Ese es el tercer momento, al que llamo orquestación. Y este tercer momento tenía dos objetivos. Uno de ellos era renderizar a través de algo diferente al monolito, porque recuerden que iba a desaparecer, y el otro era mantener las partes buenas mientras mejorábamos las limitaciones. Las partes buenas incluían la independencia de los equipos y cómo podían construir y lanzar de forma separada. Las limitaciones eran las que mencioné antes, era muy ineficiente, difícil de compartir cosas, y así sucesivamente. Y se veía así. Esta es una versión no tan detallada, entraremos en detalle en un momento. Pero tenemos un monorepo NX, y luego tenemos nuestros microfrontends expuestos como módulos federados, consumidos por una aplicación que llamamos el orquestador frontend, y esa aplicación renderiza cosas y las envía al cliente.

Hablemos del primer aspecto de esto, que es la federación. En términos políticos, esto se trata de provincias, ya saben, parcialmente independientes con un gobierno central. En nuestro mundo, en JavaScript, es muy similar. Tienes cosas parcialmente auto-gobernadas o parcialmente independientes que pueden ser consumidas por un controlador central. Así que tenemos dos aspectos principales, ¿verdad? Tenemos los módulos, que son expuestos por un sistema, cualquier sistema, y cualquier cosa puede ser un módulo. Y estos son consumidos por un host. Y también los módulos pueden ser hosts ellos mismos. Ahora, si miras esto, podrías preguntarte, bueno, ¿qué lo hace diferente de una instalación regular de NPM? Sabes, también consumo módulos cuando importo un módulo de NPM, y es algo muy pequeño, pero también es muy grande. Lo que lo hace diferente es que el consumo de los módulos ocurre en tiempo de ejecución. Por lo tanto, el host no necesita saber qué es el módulo cuando se está construyendo, solo necesita saber dónde se encuentra. Y luego lo buscará y lo consumirá en tiempo de ejecución. Y esto nos permite hacer algo muy poderoso, que es lanzar módulos por separado de una versión o una reconstrucción del host principal. Cuando hablamos de microfrontends y queremos mantener la independencia, bueno, esto es imprescindible.

Ok, eso es muy divertido. Tienes hosts, tienes módulos. Los módulos pueden ser hosts, pero aún necesitas algo central para consumirlos, por eso necesitamos un controlador central pero ligero. La palabra `ligero` tiene un poco de énfasis porque realmente queremos que el orquestador frontend, que es como llamamos a nuestro controlador central, sea realmente simple. Queremos que haga dos cosas. Una de esas dos cosas es que necesitamos que sea un enrutador para que pueda mapear las URL a los módulos.

3. Federated Module Host and Router

Short description:

Utilizamos Next.js como un host y enrutador de módulos federados, pero nuestra configuración no depende de ninguna característica específica de Next.js. Para lograr esto, creamos estándares a través de Monorepo y NX Monorepo, generando una carpeta de frontend para la lógica empresarial y una biblioteca de integración. Esta biblioteca genera automáticamente un componente que puede ser consumido por cualquier microfrontend en el Monorepo o el orquestador de frontend como un módulo federado.

Y el otro es que necesita poder consumir módulos federados, por lo que necesita ser un host. ¿De acuerdo? Básicamente, estas dos cosas. Es un host y enrutador de módulos federados. Y usamos Next.js para eso. Y la razón por la que Next está tan pequeño y en una esquina, no es que Next no sea genial. Next es genial y nos encanta. Pero es porque nuestra configuración no depende de ninguna característica específica de Next, ¿verdad? Cualquier framework o sistema de compilación interno que pueda consumir módulos federados y actuar como un enrutador habría funcionado de la misma manera.

Entonces, tenemos módulos federados. Tenemos la cosa que los va a consumir. Pero recuerden, también teníamos microfrontends existentes que ahora necesitan convertirse en módulos federados, necesitan ser expuestos para que la nueva cosa los pueda consumir, buscarlos, renderizarlos, hacer todas las cosas buenas que queremos hacer con ellos. Y la forma en que encontramos para lograr esto es a través de la creación de estándares, a través de alguna estandarización. Y esto lo hacemos a través de Monorepo y NX Monorepo, de hecho. Tal vez hayan visto su stand afuera. Son bastante geniales. Los recomiendo un poco.

Y todo se trata de generar código. Ahora, cada vez que se crea un nuevo microfrontend o cuando se está migrando un microfrontend existente al Monorepo, generamos estas dos cosas. Una carpeta de frontend. Muy aburrido, solo vive allí toda la lógica empresarial del frontend. No nos importa eso, no hoy. Y una biblioteca de integración. Y aquí es donde ocurren las partes divertidas. Porque esto genera automáticamente un componente que puede ser consumido por cualquier otro microfrontend en el Monorepo o por el orquestador de frontend, ya saben, el host principal, como un módulo federado. Aquí es donde sucede todo. Y es bastante simple. Se ve así. Tienes algunas props para que el módulo federado sepa dónde se encuentran sus módulos expuestos de forma remota. Luego exponemos un componente de memwise que, ya sabes, ese componente de módulo federado que ves allí, eso es algo interno que construimos y no puedo mostrarte cómo se ve, pero podemos hablar sobre lo que hace más tarde. Es un poco demasiado detalle para los 20 minutos que tengo. Pero ya sabes, ven a encontrarme si estás interesado en lo que hace.

4. Biblioteca de Integración y Único Tiempo de Ejecución

Short description:

Pero en resumen, sabe dónde buscar el módulo federado y cómo renderizarlo. Nx es genial porque hacer generadores es muy fácil, y adaptarlos también es muy fácil. Nos ha ahorrado mucho trabajo con lo simple que hace generar código. Los comandos afectados por Nx permiten a las personas construir dentro de un monorepo con más de 60 aplicaciones y aún así ejecutar un pipeline solo para sus cambios. NX Effective nos brinda independencia co-ubicada, el beneficio de estar en el mismo código base pero aún así ser independientes. El uso de módulos federados y todas las herramientas dentro del monorepo nos permite tener un único tiempo de ejecución, aunque estemos construyendo y desplegando de forma independiente. Nos permite compartir estado y código sin problemas con otros microfrontends. Gracias a los módulos federados y el pegamento que tenemos, podemos cargar cosas solo una vez. Ahora, nuestro punto de entrada es mucho más simple, con todo lo demás trasladado al componente de la aplicación del orquestador.

Pero en resumen, sabe dónde buscar el módulo federado y cómo renderizarlo. Y, ya saben, Nx es genial porque hacer generadores es muy fácil, y adaptarlos también es muy fácil. Y nos ha ahorrado mucho trabajo con lo simple que hace generar código. Pero también porque, recuerden, queríamos mantener la independencia de los equipos, los comandos afectados por Nx son increíbles para nuestro caso.

Es lo que permite a las personas construir dentro de un monorepo con más de 60 aplicaciones y aún así ejecutar un pipeline solo para sus cambios. Así que es algo así, ya saben, con una configuración donde tienes una biblioteca A que es consumida por la aplicación A y C, pero no por la aplicación B, los cambios realizados en la biblioteca A resultarán en un pipeline solo para la aplicación A y C. Así que solo la aplicación A y C ejecutarán sus pruebas, se reconstruirán y se volverán a implementar. Así que hurra por NX Effective. También hay algo de trucos en el pipeline para hacer que estas cosas sean dinámicas, pero eso está fuera de alcance.

Entonces, ya saben, NX Effective nos brinda lo que yo llamo independencia co-ubicada, nos brinda el beneficio de estar en el mismo código base, como en el mismo repositorio, pero aún así ser independientes, de modo que cada aplicación sea su propia cosa y funcione a su propio ritmo y sea propiedad de su propio equipo. Genial, así que unamos estas tres piezas y veamos el gráfico inicial con un poco más de detalle. Tenemos el monorepo NX, ¿verdad?, esta cosa tiene bibliotecas compartidas, tiene herramientas, muchas herramientas, y tiene el pegamento de integración que conecta los microfrontends con el orquestador. Luego tenemos las propias aplicaciones frontend, que a su vez tienen su lógica empresarial frontend y exponen una biblioteca de integración, que luego es consumida por el orquestador frontend como un módulo federado y se renderiza en el cliente, ¿verdad? Muy simple en términos de diseño, veámoslo. No tiene muchas piezas, ¿verdad? Pero como con la mayoría de las cosas simples, el diablo realmente está en los detalles.

Entonces, ¿recuerdan la biblioteca de integración? Eso parece pequeño, pero el uso de módulos federados y todas las herramientas que tenemos dentro del monorepo para que este módulo federado se integre sin problemas con otros microfrontends o con el orquestador frontend nos permite tener un único tiempo de ejecución, aunque estemos construyendo y desplegando de forma independiente. Y un único tiempo de ejecución, especialmente cuando no teníamos un único tiempo de ejecución como lo teníamos antes, ya saben, cada aplicación tenía su propio tiempo de ejecución, es divertido. Es genial. Nos permite hacer dos cosas muy importantes. Una sola instancia de proveedores que luego compartirá estado y compartirá, bueno, cualquier cosa que pongas en el proveedor, realmente, con otros microfrontends, y te permite compartir código de manera muy sencilla, tanto para bibliotecas internas como para dependencias comunes, ¿verdad? Gracias a los módulos federados y todo el pegamento que tenemos, podemos cargar cosas solo una vez. Entonces, para darte un ejemplo muy básico, todos nuestros componentes del sistema de diseño, aunque eran reutilizados por la mayoría de los microfrontends, antes se cargaban cada vez que un microfrontend estaba en la pantalla, a veces varias veces por página porque todos usan el componente de tipografía. Ahora se carga una sola vez, cada vez que se carga una página y luego se comparte a través de la federación de módulos con cualquier otro microfrontend que lo requiera.

Entonces, esto es lo que parece un punto de entrada. Ves todas estas cosas que parecen plantillas, todos estos proveedores, proveedores de clientes de consulta, proveedores de sentry, todas estas cosas globales. Incluso falta en la imagen mucha configuración como configurar nuestra biblioteca de internacionalización, configurar algo de solicitud que tenemos internamente. Ahora se ve así. Expones tu aplicación, tu punto de entrada, y eso es todo, porque todo lo demás se trasladó al componente de la aplicación del orquestador, recuerda que usamos Next. Esto se comparte en cada página dentro de la aplicación de Next. Esa es la belleza de tener un único tiempo de ejecución, te permite hacer cosas como esta. Teníamos dos objetivos, inicialmente, ¿cómo nos fue con esta idea que se nos ocurrió? Comparemos. Retrocedí.

5. Lecciones No Técnicas y Caso de Uso

Short description:

No, no lo hice. Esto fue solo para recordar los objetivos. Renderizar algo diferente al monolito y mejorar las limitaciones manteniendo las partes buenas. Los equipos aún construyen e implementan de forma independiente muchas veces al día y sin conflictos. El nuevo orquestador frontend es un enrutador y anfitrión de módulos eficiente. Ahora podemos compartir dependencias y código común fácilmente en un único tiempo de ejecución. No fue un objetivo inicial, pero las páginas servidas a través del orquestador frontend han visto una mejora del 30% en las métricas web. Al diseñar y construir un proyecto como este, tenga un caso de uso real en mente de inmediato para evitar posibles problemas.

No, no lo hice. Esto fue solo para recordar los objetivos. Renderizar algo diferente al monolito y mejorar las limitaciones manteniendo las partes buenas.

Teníamos un monolito y micro frontends a la izquierda y a la derecha. El primero es la independencia del equipo. ¿Los equipos siguen siendo tan independientes como lo eran cuando las aplicaciones vivían en repositorios separados? La respuesta es sí. Gracias a Nx y algunas de las cosas que hicimos con nuestros pipelines para hacerlos dinámicos, los equipos aún construyen e implementan de forma independiente muchas veces al día y sin conflictos.

¿Tenemos un controlador central? Sí, lo tenemos. En ambos casos, no hay diferencia. Pero, ¿es eficiente? ¿Es rápido? ¿No hace muchas cosas? En el caso del monolito, hacía absolutamente todo. Mantenía los datos, renderizaba, buscaba cosas. Hacía de todo. En el nuevo orquestador frontend, no hace nada. Es un enrutador que también es un anfitrión de módulos y eso es todo.

¿Podemos compartir dependencias y código común fácilmente? Ahora podemos. Porque estamos en un único tiempo de ejecución. Esto no era algo que realmente buscáramos mejorar, pero hemos notado que las páginas que ahora se sirven a través del orquestador frontend han visto una mejora del 30% en sus métricas web. Lo cual, si lo piensas, tiene sentido porque no tienen que volver a montar todo, ya que también estamos compartiendo dependencias. Como dije, no fue un objetivo inicial, pero es algo que nos alegra ver.

Ahora, algunas lecciones no técnicas aprendidas al estar en el equipo que diseñó y construyó este proyecto. Realmente deberías tener un caso de uso real. Si estás haciendo algo así, ten un caso de uso real en mente de inmediato. Quiero decir, teníamos un caso de uso real, pero construye con la idea de que estarás llevando algo a producción lo más rápido posible. Elige una página que no sea muy visitada y simplemente ponla ahí. Puede que no funcione muy bien, no importa. Ponla ahí. No tuvimos eso. Terminamos probándolo por primera vez en producción con el panel, la página más visitada. Y Personium, algunos podrían decir que fue valiente, pero también fue imprudente y nos causó muchos dolores de cabeza. Así que, ya sabes, no lo hagas.

6. Desafíos con el Sistema de Código Abierto Interno

Short description:

La parte más difícil de construir nuevos sistemas de software son las personas, y no me refiero a individuos, ¿verdad? Me refiero a las organizaciones. Queríamos que este nuevo sistema funcionara como un sistema de código abierto interno, pero no funcionó. No teníamos un sistema de infraestructura crítico que respaldara este enfoque. Así que ahora tenemos un equipo que es dueño del sistema, y funciona mejor.

Lanzar a producción lo más rápido posible en un lugar pequeño. La parte más difícil de construir nuevos sistemas de software son las personas, y no me refiero a individuos, ¿verdad? Me refiero a las organizaciones, así que algo que no mencioné antes es que queríamos que estas dos nuevas piezas funcionaran como un sistema de código abierto interno, ¿sabes? Como si fuéramos el grupo de mantenedores. Las personas colaborarían. Contribuiríamos, colaboraríamos con ellos. Sería genial, ¿sabes? Sería glorioso. Eso no funcionó. No teníamos un sistema de infraestructura crítico que funcionara así, y resulta que el enfoque contrario, donde primero construyes un sistema y luego esperas que las estructuras organizativas de tu empresa se adapten al sistema existente, no funciona. Así que, ya sabes, esto puede sonar genial, pero ahora tenemos un equipo que es dueño de las cosas, y hay ideas muy claras de a quién debes contactar si algo se rompe o quién está a cargo de desarrollarlo, y funciona mejor, ¿sabes? La organización Personia no estaba lista para una idea como esta, y perdimos mucho tiempo intentando hacer que funcionara.

7. Importancia de los primeros adoptantes y Conclusión

Short description:

Los primeros adoptantes son cruciales para construir algo nuevo. Proporcionan comentarios e ideas valiosas. Si te encuentras en una posición similar, considera el patrón arquitectónico de microfrontends federados. Un saludo al equipo original y gracias por asistir a la charla.

Y finalmente, cuando estás construyendo algo nuevo, tus primeros adoptantes son los mejores adoptantes. Te amarán, te odiarán, pero lo más importante, te harán saber qué funciona y qué definitivamente no, ¿verdad? Así que encuentra a los primeros adoptantes y atesóralos. Son los mejores.

Ahora, algunos de ustedes pueden estar en posiciones similares y podrían estar pensando, eh, eso suena interesante, tal vez debería intentarlo. Ya sabes, la respuesta siempre es, es bastante simple, es un tal vez, ya sabes, depende. Nuestra situación era bastante especial. Teníamos varios equipos que necesitaban lanzar bajo demanda y necesitaban hacer que estos lanzamientos estuvieran disponibles para los clientes de inmediato. Ya teníamos experiencia con microfrontends, así que sabíamos cómo ejecutar un sistema de frontend distribuido, no, no federado. Estábamos descontinuando nuestro mecanismo de entrega existente, por lo que nos vimos obligados a construir algo nuevo. Y teníamos experiencia interna en la construcción de un sistema similar. Creo en lo que construimos, pero si algunas de esas cosas no estuvieran allí, podríamos haber mantenido lo que teníamos en su lugar, en lugar de construir algo diferente. Si tu situación se parece en algo a la nuestra, no tiene que ser exactamente igual a la nuestra, pero si se parece en algo a la nuestra, entonces tal vez considerar esta idea, este patrón arquitectónico de microfrontends federados podría valer la pena investigar para ti. Ese es el final de la historia, pero antes de pasar a las preguntas y respuestas, quiero dar un saludo a las caras en esta diapositiva. Fueron el equipo original que trabajó conmigo en esto. Personas muy geniales. Sí, solo quería mostrar sus caras. Y gracias por venir. Gracias por escuchar. Gran charla. Muchas gracias.

QnA

Alternativa a NX y TurboRepo

Short description:

Podríamos usar una alternativa. Lo que necesitamos de NX es generar código fácilmente y un comando afectado. No he investigado mucho sobre TurboRepo, pero si TurboRepo puede hacer algo así que permita que las aplicaciones monorepo sigan sintiéndose independientes y trabajando de forma independiente, entonces también funcionaría.

Tenemos muchas preguntas. No podremos responder a todas las preguntas, así que si tienes preguntas específicas que veas en Sli.do, por favor vota por ellas y las responderemos primero. Muy bien. Entonces, primera pregunta. ¿Depende tu configuración de funcionalidades específicas de NX o podrías usar una alternativa como TurboRepo? Podríamos usar una alternativa. Lo que necesitamos de NX es generar código fácilmente y un comando afectado, ya sabes. No he investigado mucho sobre TurboRepo, pero si TurboRepo puede hacer algo así que permita que las aplicaciones monorepo sigan sintiéndose independientes y trabajando de forma independiente, entonces también funcionaría. Genial, sí. Yo tampoco lo he probado, así que, ya sabes, inténtalo.

Versionado y Diversidad Tecnológica

Short description:

Nuestra estrategia para el versionado de MicroFrontEnds es tener un único archivo package JSON raíz, asegurando una única versión de las dependencias en todo el monorepo. Tenemos un versionado estricto en nuestros módulos federados para garantizar que todos obtengan la misma versión. Servimos un único archivo de entrada remoto sin hash, pero estamos introduciendo un hash para la versión. Aunque utilizamos React para la homogeneidad, los equipos pueden tomar decisiones sobre bibliotecas y frameworks específicos. Actualmente, no admitimos el renderizado del lado del servidor con Módulos Federados, pero puede evolucionar en el futuro.

¿Qué hay del versionado de tus MicroFrontEnds? ¿Qué sucede si los modules comunes difieren entre esas versiones? ¿Cómo manejarías esto en tu aplicación de host final? Correcto. En este momento, nuestra estrategia para resolver eso es no permitirlo. Eso es algo más que NX hace por ti. Tiene un único archivo package JSON raíz. Por lo tanto, solo tienes una única versión de las dependencias en todo el monorepo. A veces, actualizar puede ser doloroso, pero resuelve algunos de los problemas en este caso.

Otra cosa que tenemos es que tenemos un versionado estricto en nuestros modules federados, lo que significa que cuando una dependencia entra y se sirve a un MicroFrontEnd como un módulo federado, sabemos que todos obtendrán la misma versión. Para nuestro propio versionado interno, en este momento, no lo tenemos realmente. Las nuevas versiones siempre son la última versión. Servimos un único archivo de entrada remoto sin hash, pero estamos introduciendo un hash para la versión. ¿Recuerdas el servicio de artefactos que mencioné? Tenemos una nueva versión de eso, que mantendrá la referencia a cuál es el último archivo de entrada y lo serviremos al orquestador cuando se solicite.

Sí, tiene sentido. Destacaré una pregunta que se hizo aquí y que no estaba en la parte superior, que es, tienes un monorepo, lo que te permite tomar decisiones en un solo punto, como acabas de mencionar, fijar versiones. Pero, ¿tienes alguna diversidad tecnológica en el stack? ¿La gente usa tal vez diferentes bibliotecas, frameworks, patrones arquitectónicos, o es algo homogéneo? No es completamente homogéneo, pero está cerca. Solo usamos React. Eso ya es una gran ventaja, porque nos permite simplificar las herramientas que crean módulos autoritarios, solo tuvimos que lidiar con un framework. Y proporcionamos algunas cosas listas para usar que esperamos que la gente use, como React Query, por ejemplo. Ese es nuestro mecanismo de gestión del estado del servidor. Pero aún así, los equipos pueden tomar decisiones sobre los detalles de lo que usan. Entonces, por ejemplo, si un microfrontend realmente necesita algún gestor de estado para él, aparte del estado del servidor, pueden usar Redux o Jotai o lo que quieran. Por lo tanto, es homogéneo en las piezas grandes, pero no tanto en las más pequeñas.

Genial. Hay una pregunta aquí que ha recibido muchas votaciones. Intentamos la misma solución, pero nos quedamos atascados en SSR. ¿Cómo están trabajando ustedes con SSR y los Módulos Federados? Sí, eso es bueno. No lo estamos haciendo. No tenemos la necesidad de hacerlo en este momento. Y sé que es un punto importante. Los módulos federados aún no están configurados adecuadamente para el renderizado del lado del servidor, o al menos no lo estaban la última vez que verificamos. Las cosas pueden haber evolucionado en el intermedio y definitivamente evolucionarán eventualmente para admitir eso.

Manejo de Datos en Tiempo Real y Federación de Módulos

Short description:

Nuestra aplicación depende en gran medida de los datos de recursos humanos en tiempo real, por lo que no utilizamos mucho SSR. Utilizamos una caché compartida para deduplicar las solicitudes y mejorar la eficiencia asíncrona. Los cambios disruptivos en los módulos federados se manejan con una herramienta que permite realizar fácilmente rollbacks. Implementamos nuestra propia solución de federación de módulos, que es similar a las existentes. Requerimos una cobertura de código del 100% para las bibliotecas compartidas para minimizar los problemas causados por los cambios de un equipo que afectan a otro.

Nuestra aplicación depende mucho de que los datos estén actualizados en tiempo real, porque son datos de recursos humanos. Es muy importante que las cosas estén actualizadas. Por lo tanto, no utilizamos mucho SSR. Sí, me di cuenta de que están utilizando React Query, ¿es correcto? Sí, algo así. Probablemente tengan una caché compartida, ¿es así como deduplican las solicitudes y se aseguran de que cada paquete no haga una búsqueda de datos innecesaria? Sí, exactamente. Esa es la capa que nos permite ser más eficientes con nuestras solicitudes asíncronas.

Sí, eso es genial. Aquí está la pregunta que ya hemos abordado, pero creo que necesita un poco más de explicación. ¿Cómo manejan los cambios disruptivos en los módulos federados, que necesitan despliegues independientes? Correcto. Sí, tenemos, como dije, esta herramienta que estamos implementando ahora, que es la nueva versión del Servicio de Artefactos, que facilita mucho el rollback. Tiene una interfaz que podemos usar para decir: `Oye, esto se rompió, márcalo como inestable y devuelve el último`. Por lo tanto, se resuelve con herramientas, básicamente.

Bueno, esto nos lleva a nuestra siguiente pregunta. ¿Utilizaron alguna biblioteca de federación de módulos existente o implementaron la suya propia? Y si hicieron la suya propia, ¿qué opinan de algunas de las soluciones disponibles en el mercado? Correcto. Creo que uno de mis compañeros de equipo sería el mejor para responder esta pregunta. Pero si recuerdo correctamente, y Rob, disculpa si me equivoco, terminamos implementando la nuestra propia, pero se parece mucho a algo existente. Fue más como ajustamos pequeños detalles para adaptarlo a nuestro caso de uso específico, considerando un fork de lo que ya estaba disponible para el complemento de módulos federados de NextJS, creo. ¿Y qué pienso de ellos? Quiero decir, todos son geniales. Si puedes usarlos, úsalos. No tiene sentido crear algo propio para algo que ya ha sido resuelto. Simplemente no funcionó exactamente como queríamos.

Genial. ¿Cómo manejan cuando un equipo rompe algo de otro equipo a través de una biblioteca compartida? ¿Hay algún tipo de ritual de avergonzarlos, ponerles un sombrero divertido, señalarlos? No, pero desearía que lo hubiera. No, quiero decir, somos muy estrictos en las bibliotecas en sí. Las bibliotecas que se comparten con diferentes microfrontends requieren una cobertura de código del 100%. No estoy diciendo que eso lo haga más seguro. Pero por lo general, al menos hace que las personas piensen más en sus cambios.

Revisión de Código, Seguridad de Tipos y Compartición de Datos

Short description:

Los equipos revisan el código utilizando un archivo detallado de propietarios de código y requieren la aprobación de todos los equipos consumidores antes de implementarlo en producción. TypeScript y la biblioteca de integración garantizan la seguridad de tipos y las completaciones de código en VS Code. Los contextos comunes entre los microfrontends se comparten a través de bibliotecas de datos que utilizan React Query. El monorepo en sí proporciona información sobre los datos disponibles y el acceso a la caché.

Y también deben ser revisados por el equipo que lo utiliza. Porque utilizamos un archivo detallado de propietarios de código. Y luego, al construir las solicitudes de fusión que lo implementarán en producción, necesita requiere la aprobación de cada equipo que lo consume. Así es como nos protegemos de ese escenario. No digo que no suceda, ¿verdad? Pero cuando sucede, también nos ocupamos de ello como equipo. Como un grupo de personas de diferentes sitios para resolverlo. Sin avergonzar a nadie.

Sí, eso tiene sentido. De hecho, destacaré otra pregunta de aquí, que no puedo encontrar ahora mismo. Pero se trataba de... Así que supongo que también usan algún tipo de TypeScript para tener type safety en todos los paquetes Pero, ¿qué hay de cosas como las completaciones de código y la función de hacer clic en el comando dentro de VS Code, por ejemplo? ¿Funcionan cuando se está federando en runtime?

Sí, lo hacen, porque tenemos este paquete de integración que les mostré, la biblioteca de integración. Eso se consume como cualquier otra importación regular, ¿verdad? Lo que hace en runtime está dentro de él. Cada aplicación, cada microfrontend se desarrolla de forma individual. Todo tiene seguridad de tipos. Todo está en TypeScript. Es seguro en cuanto a tipos. Y es consumido por el orquestador del frontend que también es seguro en cuanto a tipos, y el lado asíncrono que podría romperse ocurre bajo el capó, y nadie realmente lo toca. Así es como nos protegemos de eso. Genial.

Tenemos tiempo para una pregunta más. Ya hemos tocado esto antes, pero creo que vale la pena explorarlo un poco más. ¿Cómo comparten los microfrontends los contextos comunes? Así que supongo que esto es un contexto de runtime, como cosas como data. Mencionaste React Query. Pero ¿podrías decir algunas palabras más sobre cómo se orquesta todo eso? ¿Cómo saben los equipos que están construyendo una funcionalidad en particular qué data está disponible? ¿Qué se va a almacenar en la caché? ¿Importa, etc., etc.?

Sí, importa, y ese es un punto que aún no hemos resuelto completamente. Tenemos una idea, y ya funciona. Tenemos lo que llamamos bibliotecas de data. Los equipos proporcionan bibliotecas de data comunes que utilizan, en el fondo, utilizan React Query. Exponen hooks para que podamos compartir las mismas claves de consulta y, por lo tanto, acceder a la misma caché cuando diferentes equipos lo utilizan. Pero debido a que estamos migrando microfrontends existentes que son independientes, aún no están completamente allí. Pero cuando lleguen allí, no tendremos el problema de saber qué está disponible porque dentro del propio monorepo, te dirá qué puedes obtener de forma segura accediendo a una caché si existe. Genial, eso es realmente genial. Increíble.

Una pregunta final para mí. ¿Cuál es tu tipo de letra Serif favorita? Meriwether. Genial. Bueno, muchas gracias, y te dejo ir. Buen trabajo con la charla. Gracias. Damos un último aplauso.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
Remix is a web framework that gives you the simple mental model of a Multi-Page App (MPA) but the power and capabilities of a Single-Page App (SPA). One of the big challenges of SPAs is network management resulting in a great deal of indirection and buggy code. This is especially noticeable in application state which Remix completely eliminates, but it's also an issue in individual components that communicate with a single-purpose backend endpoint (like a combobox search for example).
In this talk, Kent will demonstrate how Remix enables you to build complex UI components that are connected to a backend in the simplest and most powerful way you've ever seen. Leaving you time to chill with your family or whatever else you do for fun.
React Advanced Conference 2022React Advanced Conference 2022
29 min
Understanding React’s Fiber Architecture
Top Content
We've heard a lot about React's Fiber Architecture, but it feels like few of us understand it in depth (or have the time to). In this talk, Tejas will go over his best attempt at understanding Fiber (reviewed by other experts), and present it in an 'explain-like-I'm-five years old' way.
TechLead Conference 2023TechLead Conference 2023
35 min
A Framework for Managing Technical Debt
Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt.In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.

React Summit 2023React Summit 2023
24 min
Debugging JS
As developers, we spend much of our time debugging apps - often code we didn't even write. Sadly, few developers have ever been taught how to approach debugging - it's something most of us learn through painful experience.  The good news is you _can_ learn how to debug effectively, and there's several key techniques and tools you can use for debugging JS and React apps.

Workshops on related topic

DevOps.js Conf 2024DevOps.js Conf 2024
163 min
AI on Demand: Serverless AI
Featured WorkshopFree
In this workshop, we discuss the merits of serverless architecture and how it can be applied to the AI space. We'll explore options around building serverless RAG applications for a more lambda-esque approach to AI. Next, we'll get hands on and build a sample CRUD app that allows you to store information and query it using an LLM with Workers AI, Vectorize, D1, and Cloudflare Workers.
React Summit 2023React Summit 2023
145 min
React at Scale with Nx
Featured WorkshopFree
We're going to be using Nx and some its plugins to accelerate the development of this app.
Some of the things you'll learn:- Generating a pristine Nx workspace- Generating frontend React apps and backend APIs inside your workspace, with pre-configured proxies- Creating shared libs for re-using code- Generating new routed components with all the routes pre-configured by Nx and ready to go- How to organize code in a monorepo- Easily move libs around your folder structure- Creating Storybook stories and e2e Cypress tests for your components
Table of contents: - Lab 1 - Generate an empty workspace- Lab 2 - Generate a React app- Lab 3 - Executors- Lab 3.1 - Migrations- Lab 4 - Generate a component lib- Lab 5 - Generate a utility lib- Lab 6 - Generate a route lib- Lab 7 - Add an Express API- Lab 8 - Displaying a full game in the routed game-detail component- Lab 9 - Generate a type lib that the API and frontend can share- Lab 10 - Generate Storybook stories for the shared ui component- Lab 11 - E2E test the shared component
Node Congress 2023Node Congress 2023
160 min
Node Monorepos with Nx
WorkshopFree
Multiple apis and multiple teams all in the same repository can cause a lot of headaches, but Nx has you covered. Learn to share code, maintain configuration files and coordinate changes in a monorepo that can scale as large as your organisation does. Nx allows you to bring structure to a repository with hundreds of contributors and eliminates the CI slowdowns that typically occur as the codebase grows.
Table of contents:- Lab 1 - Generate an empty workspace- Lab 2 - Generate a node api- Lab 3 - Executors- Lab 4 - Migrations- Lab 5 - Generate an auth library- Lab 6 - Generate a database library- Lab 7 - Add a node cli- Lab 8 - Module boundaries- Lab 9 - Plugins and Generators - Intro- Lab 10 - Plugins and Generators - Modifying files- Lab 11 - Setting up CI- Lab 12 - Distributed caching
React Summit Remote Edition 2021React Summit Remote Edition 2021
87 min
Building a Shopify App with React & Node
Top Content
WorkshopFree
Shopify merchants have a diverse set of needs, and developers have a unique opportunity to meet those needs building apps. Building an app can be tough work but Shopify has created a set of tools and resources to help you build out a seamless app experience as quickly as possible. Get hands on experience building an embedded Shopify app using the Shopify App CLI, Polaris and Shopify App Bridge.We’ll show you how to create an app that accesses information from a development store and can run in your local environment.
JSNation Live 2021JSNation Live 2021
113 min
Micro Frontends with Module Federation and React
Workshop
Did you ever work in a monolithic Next.js app? I did and scaling a large React app so that many teams can work simultaneously is not easy. With micro frontends you can break up a frontend monolith into smaller pieces so that each team can build and deploy independently. In this workshop you'll learn how to build large React apps that scale using micro frontends.
JSNation 2022JSNation 2022
41 min
Build a chat room with Appwrite and React
WorkshopFree
API's/Backends are difficult and we need websockets. You will be using VS Code as your editor, Parcel.js, Chakra-ui, React, React Icons, and Appwrite. By the end of this workshop, you will have the knowledge to build a real-time app using Appwrite and zero API development. Follow along and you'll have an awesome chat app to show off!