Muchas empresas en todo el mundo están considerando adoptar Micro-Frontends para mejorar la agilidad empresarial y la escala, sin embargo, hay muchas incógnitas cuando se trata de cómo se ve en la práctica el camino de migración. En esta charla, discutiré los pasos necesarios para migrar con éxito una aplicación React monolítica a una arquitectura de frontend más modular y desacoplada.
De Monolito a Micro-Frontends
Video Summary and Transcription
Se considera a los Microfrontends como una solución a los problemas de crecimiento exponencial, duplicación de código y propiedad poco clara en aplicaciones antiguas. La transición de un monolito a microfrontends implica desacoplar el sistema y explorar opciones como un monolito modular. Los Microfrontends permiten implementaciones independientes y composición en tiempo de ejecución, pero hay una discusión sobre la alternativa de mantener una aplicación integrada compuesta en tiempo de ejecución. Elegir un modelo de composición y un enrutador son decisiones cruciales en el plan técnico. Se utilizan el patrón Strangler y el patrón Strangler inverso para reemplazar gradualmente partes del monolito con la nueva aplicación.
1. Introducción a Microfrontends
Vamos a hablar sobre cómo transformar monolitos en micro-frontends. React ha estado aquí durante mucho tiempo y las aplicaciones que ahora son un poco antiguas comienzan a crecer y a romperse. Los problemas suelen estar relacionados con la organización y las complicaciones que vienen con el crecimiento. El crecimiento exponencial, la duplicación de código y la propiedad poco clara son algunos de los problemas. Muchas personas y empresas han considerado a los microfrontends como una solución.
Entonces, mi nombre es Ruben y soy ingeniero en Postman. Y el tema de hoy es interesante. Vamos a hablar sobre cómo transformar monolitos en micro-frontends. Ahora, esta es nuestra conferencia de React, ¿verdad? Bueno, React ha estado aquí durante mucho tiempo, ¿verdad? El próximo año, React tendrá ¿cuántos años? Diez años, ¿verdad? Entonces, los reclutadores probablemente dirán, oh, finalmente, vamos a pedir diez años de experiencia en React. React ha estado aquí durante mucho tiempo. Si tienes aplicaciones que ahora son un poco antiguas. Bueno, técnicamente, no viejas, viejas, pero en el largo esquema de las cosas de la tecnología, probablemente están envejeciendo un poco. Y el problema con eso es que las aplicaciones envejecen y comienzan a crecer y crecer y crecer. Y ¿cuál es el problema con el crecimiento? Bueno, probablemente empiece a romperse en algún momento. Y probablemente estaremos experimentando. Ahora, si piensas, si has estado trabajando con React, piensa en los problemas que tienes ahora, probablemente tendrás una larga sesión de personas simplemente quejándose sobre los problemas que tienes. Pero en su mayoría no se trata de React en sí, suele ser sobre la organización. Se trata de cómo a medida que tu empresa y la aplicación crecen, las cosas comienzan a complicarse y a ser difíciles de escalar. Entonces, empiezas a tener cosas como crecimiento exponencial, como tienes muchas líneas de código. Tienes más desarrolladores, sabes, cuando empezaste ese proyecto solo eran dos o tres. Ahora tienes muchos grupos de desarrolladores, especialmente para empresas que son bastante grandes. CI tarda mucho tiempo en completarse. Todos odiamos eso. Queremos que las cosas sean rápidas. Duplicación de código. No hay una propiedad clara. ¿Quién posee qué? Etcétera, etcétera. Entonces, tenemos muchos problemas. Ese gráfico de dependencias es el peor. Lo odio. Como que tenemos muchas dependencias y no sabemos de dónde vienen o qué está usando qué. Entonces, hay muchos problemas. Probablemente estés familiarizado con esto. Entonces, todos estos problemas han llevado a muchas personas a pensar en microfrontends. ¿Deberíamos usar microfrontends para resolver este problema? Y muchas personas y empresas
2. Transición de Monolito a Microfrontends
¿Cómo pasamos de un monolito a microfrontends? El objetivo principal de pasar del monolito a los microfrontends es eliminar el acoplamiento y el acoplamiento accidental. La gente quiere pasar a los microfrontends, pero no entienden por qué. Si quieres pasar a una arquitectura distribuida, si quieres resolver esos problemas que tienes con la escalabilidad de una gran aplicación monolítica, primero necesitas desacoplarla.
Bueno. Pero, primero, ¿qué son los microfrontends? Esto es una broma. No voy a explicar qué es un microfrontend. Cada charla sobre microfrontends comienza con esa diapositiva. Si no estás familiarizado, puedes ver algunas charlas sobre qué son. Voy a estar más enfocado en cómo llegar allí, en lugar de qué son. Y puedo tocar un par de conceptos. Pero ese es el objetivo principal de esto... De hecho, voy a decirte cuál es el objetivo principal de esta presentación. ¿Quieres saber cuál es el objetivo principal de esta presentación? Voy a hacerte inteligente. Voy a hacerte lucir bien. Cuando vayas a la próxima reunión, ¿verdad?, si quieres impresionar a todos en esa sala, ¿verdad?, te lo mostraré. Te daré la clave. ¿Estás listo para la clave? Una vez que estés en esa reunión, solo tienes que decir, bueno, creo que necesitamos encontrar una oportunidad para desacoplar estas piezas. Bien. Inmediatamente. Eso te hará sonar como la persona más inteligente de esa sala. Así que desacoplar las piezas, y eso es Ryan Florence, por cierto. Gran cita. Eso no soy yo. Así que el acoplamiento es un gran problema. Y, de hecho, lo más grande que el acoplamiento es el acoplamiento accidental. Eso es lo peor de todo. Así que el objetivo principal de, bueno, no de esta charla, sino el objetivo principal de pasar del monolito a los microfrontends es eliminar el acoplamiento y el acoplamiento accidental. Ese es el objetivo principal, ¿verdad? ¿Cómo logramos ese objetivo? Bueno, te lo mostraré en un minuto, pero lo que me gusta decir, esta es mi cita, por cierto, creo, así que se me ocurrió. La gente quiere pasar a los microfrontends, pero no entienden por qué. Y esta es una razón realmente suficiente. Si quieres pasar a una arquitectura distribuida, si quieres, ya sabes, resolver esos problemas que tienes con la escalabilidad de una gran aplicación monolítica, primero necesitas desacoplarla,
3. Desacoplamiento y el Monolito Modular
Antes de aplicar micro frontends, comienza con el desacoplamiento del sistema. Los micro frontends buscan desacoplar el monolito y dar sentido al gráfico de dependencias. Sin embargo, es importante considerar otras opciones y explorar los pasos intermedios. Un enfoque es un monolito modular, que ayuda a organizar la aplicación dentro del monolito.
No vayas y digas, OK, los micro frontends son la solución. Hay muchas soluciones. Yo llegué a un gráfico, como un diagrama, que llamé el espectro desacoplado y distribuido, que es un largo lugar donde puedes ir de uno al siguiente hasta que resuelvas tu problema. Explicaré este gráfico brevemente. Así que, tenemos el monolito, ¿verdad? Eso es donde estamos ahora mismo. Algunas personas tienen el monolito con backend y frontend todavía. Pero vamos a suponer que no tenemos eso. Supongamos que el backend ya está dividido en microservices. Todavía tenemos el monolito y la aplicación frontend en el monolito. Estamos luchando porque no podemos desplegar, es muy difícil, todos estos problemas que discutimos brevemente. Si salto directamente a los micro frontends y no he explorado todos los pasos en el medio, estoy llegando a esta conclusión que podría no ser la solución para mi problema. Recuerda, uno de los principales problemas es el desacoplamiento. ¿Cómo desacoplamos? Vamos paso a paso. Probemos un monolito modular. Este enfoque también es realmente bueno. Algunas empresas lo están usando. Y tienen su aplicación un poco más organizada dentro de su monolito.
4. Transición a Microfrontends
Los monolitos modulares proporcionan cierta propiedad de equipo y límites dentro de una aplicación monolítica, pero todavía tienen acoplamiento y no pueden ser desplegados de forma independiente. Las aplicaciones integradas ofrecen más flexibilidad, pero aún se despliegan como una única unidad. Los microfrontends permiten despliegues independientes y composición en tiempo de ejecución, permitiendo despliegues separados de unidades individuales. Sin embargo, los despliegues independientes no siempre pueden ser la mejor solución, y hay una masterclass después de esta que discute la alternativa de mantener una aplicación integrada compuesta en tiempo de ejecución. Ahora, vamos a centrarnos en cómo hacer la transición de un monolito a microfrontends con un plan de acción.
Todavía es un monolito, todavía se despliega como una sola unidad, pero tienen cierta propiedad de equipo, tienen algunos límites, pueden entender un poco mejor la aplicación, y todavía tienen cierto acoplamiento, por lo que todavía estamos en la escala de acoplamiento scale en lugar de la escala de desacoplamiento scale, pero no pueden desplegarse de forma independiente. Eso es una de las cosas principales con los monolitos modulares, tienes que desplegar todo el conjunto, y todavía tienes mucho acoplamiento dentro, por lo que toda la UI y las bibliotecas y todo está ahí. Pero para tu empresa, para tu caso de uso, un monolito modular podría ser perfectamente adecuado y podría funcionar y podría resolver muchos de tus problemas. Así que, compruébalo si quieres. Echa un vistazo a un monolito modular. Y luego el siguiente paso es, oh, ¿qué tal las aplicaciones integradas? Las aplicaciones integradas son un poco más flexibles que un monolito modular. Hay muchos sabores y muchas herramientas de monorepo intentan ayudarte con una aplicación integrada, que básicamente tienes múltiples aplicaciones todavía dentro de una base de code. Podría ser un monorepo. Y se despliegan y componen en tiempo de construcción. Así que, todavía no puedes desplegar de forma independiente. Todavía puedes desplegar, pero una vez que lanzas la aplicación, esto es clave, se lanza como esa única unidad todavía. Así que, esa es la principal diferencia. Ahora, finalmente hemos llegado a los microfrontends. Entonces, ¿qué obtienes si aplicas microfrontends? Si no te detienes en las aplicaciones integradas y los monorepos. Y la clave son los despliegues independientes. Así que, tendrás despliegues independientes y composición en tiempo de ejecución con microfrontends, lo que significa que no tienes que desplegar esa única unidad de nuevo de una vez. Puedes desplegar esas unidades independientes por separado. Y eso podría ser lo que necesitas. O puede que no sea lo que necesitas. ¿Correcto? Así que, podría ser que los despliegues independientes en realidad vayan a causar muchos problemas. Y de hecho, hay una gran charla justo después de mi charla de mi buen amigo Alex. Él va a hablar exactamente de eso, que es ¿qué pasa si no vamos a los despliegues independientes? ¿Qué pasa si simplemente mantenemos una aplicación integrada que se compone en tiempo de ejecución? Así que, no te la pierdas. Es después de esta charla. Pero, prometí que iba a mostrarte cómo pasar de un monolito a un microfrontend. Hemos decidido que necesitamos microfrontends. Necesitamos despliegues independientes. ¿Cómo lo hacemos? Correcto. Así que, necesitamos un plan de acción. Y este plan de acción es dos cosas.
5. Plan Técnico: Elección de un Modelo de Composición
Necesitamos un plan técnico y organizativo. Si estás desplegando de forma independiente y componiendo cosas, necesitas encontrar un modelo de composición. Para una aplicación de página única de React, la renderización en el lado del cliente con modus operation de Webpack es una buena elección. Modus operation permite flexibilidad y decisiones reversibles, evitando la inversión en la tecnología equivocada.
Necesitamos un plan técnico y organizativo. Y espero poder repasar lo técnico. Y al final, hablaremos de lo organizativo. Entonces, lo primero es, si estás desplegando de forma independiente y estás componiendo cosas, necesitas encontrar cómo vas a hacerlo, ya sabes, cómo vas a juntar todo. Y esta es una forma muy común de dividir microfrontends, que es, ya sabes, verticalmente por, ya sabes, la ruta, el enrutador y la URL, o horizontalmente, como widgets y cosas así. Pero hay muchas formas de hacer esto. Puedes hacerlo en el borde. Puedes hacerlo en el lado del servidor. Puedes hacerlo en el lado del cliente. Necesitas elegir un modelo de composición. Entonces, imaginemos que tenemos una aplicación de React. Para mantenerlo simple, es una aplicación de una sola página. No se renderiza en el lado del servidor. Voy a elegir un modelo de composición basado en la renderización en el lado del cliente y voy a utilizar modus operation de Webpack, que es una gran herramienta y te diré por qué me gusta. Pero, básicamente, vamos a mantenerlo simple. La composición de renderización en el lado del servidor es posible. Es solo un poco más difícil. Pero, si tienes una aplicación de una sola página, una aplicación de React, y quieres elegir un modelo de composición, este es uno bueno para optar con modus operation de Webpack. Te dije por qué iba a decir por qué me gusta modus operation. Una cosa importante y es muy flexible. Y una cosa importante en este viaje de monolito a microtransparencia, necesitas asegurarte de que tomas decisiones reversibles. Que haces la transición gradualmente. Modus operation te permite tener esa flexibilidad. Porque estoy importando un módulo externo usando modus operation, y ahora estoy importando, oh, es la misma diapositiva. En realidad, no es la misma diapositiva. Estoy importando un módulo local. Si decido que modus operation no es lo mío y no está funcionando para mí, bueno, es realmente fácil volver a la composición en tiempo de construcción y cargar desde MPM en lugar de desde modus operation. Así que, tomar decisiones que son reversibles es muy, muy importante. Porque no quieres embarcarte en un viaje de, de nuevo, ir a micro front ends y te das cuenta a mitad de camino de que esto no es para nosotros. Has invertido mucho en nuestra tecnología y arquitectura que probablemente no será muy buena
6. Elección de un Router para Microfrontends
Modus operation te permite componer componentes de React en tiempo de ejecución en lugar de en tiempo de construcción. Elegir un router es una decisión crucial al pasar de un monolito a microfrontends. Hay tres opciones: un router de nivel superior, un router de sub-aplicación y un router de micro-frontend. El router de nivel superior es similar a un router normal, pero tiene más acoplamiento y requiere desplegar la carcasa y nuevas rutas. El ajuste fino del acoplamiento es esencial en esta arquitectura.
7. Multi-Router Distributivo
Para mi caso de uso, me gusta la opción de compartir el contexto y desplegar mi aplicación shell. Otra opción es el multi-router distributivo, donde cada aplicación tiene su propio router y puede desplegar sus propias rutas de forma independiente. Sin embargo, este modelo es muy complejo y requiere comunicación entre los routers. Solo un router puede utilizar el historial del navegador, mientras que el resto utiliza el historial de memoria y métodos de sincronización. A pesar de la complejidad, este modelo ofrece un sistema completamente desacoplado.
Así que este, la diferencia es que no hay un solo router. Hay varios. Así que el de arriba, React Router, sí, está bien. Y luego todos estos pueden ser 5, 4 o lo que quieras usar allí. Cada aplicación tendrá su propio router. Y esto es genial. Cada aplicación es su propia unidad. Básicamente pueden desplegar sus propias rutas como quieran. No tienen que depender de nadie más para definir y desplegar nuevas rutas. Y son realmente aplicaciones individuales de React. Hacen el renderizado de React por separado. Así que no están compartiendo nada, ni el árbol ni nada en absoluto. Son aplicaciones absolutamente completamente independientes. El problema que tengo con este modelo es que es muy complejo. No sé si alguien lo ha hecho en producción. Sé que hay mucho material por ahí. Es muy complejo. Necesitas comunicarte entre los routers. Solo un router tiene permiso para usar el historial del navegador. El resto tendrá que hacer un historial de memoria y un método de sincronización. Es muy complejo. Pero obtienes un sistema absolutamente 100% desacoplado. Así que si estás buscando absolutamente 100% no hay acoplamiento en absoluto, ni siquiera las instancias de React que se comparten, entonces esto
8. React Router y Contexto Compartido
Si quiero algunas características de React Router 6, que son geniales, por cierto, no funcionarán porque no hay un contexto compartido. Para mi aplicación principal, tengo un router que es solo un router React normal, compartiendo un solo contexto y yo lo controlo. Pero hay una aplicación fuera de este contexto que necesita ser completamente separada. Puedes mezclarlos, pero hay cierto acoplamiento en algunas de las partes aquí.
9. Patrones Strangler y Reverse Strangler
No podemos hacer una migración de golpe, así que usaremos el patrón Strangler o el patrón Reverse Strangler. El patrón Strangler implica reemplazar gradualmente partes del monolito con la nueva aplicación. El patrón Reverse Strangler implica poner todo el código del monolito en la nueva aplicación y eliminar gradualmente el código heredado. Los microfrontends buscan resolver problemas organizativos, no solo técnicos.
10. Visión, Estrategia y Compromiso
Al considerar los micro front-ends, es importante pensar en la visión y la estrategia. Establecer un sentido de urgencia para asegurar el compromiso. Involucrar a las personas enfatizando la visión compartida y estando abierto a nuevos enfoques. Las decisiones reversibles son cruciales debido a la naturaleza siempre cambiante de las cosas.