Microfrontas: ¿de qué estamos hablando?

Todos estos años, usted, el desarrollador frontend, ha escrito monolitos, aunque entendió que era un mal hábito. Dividió su código en componentes, usó require o import y definió paquetes npm en package.json o generó repositorios git en su proyecto, pero de todos modos escribió un monolito.
Es hora de cambiar de posición.

¿Por qué su código puede considerarse un monolito?


Por naturaleza, todas las aplicaciones frontend son monolíticas, excepto las aplicaciones que implementan micro frontends. La razón es que está desarrollando utilizando la biblioteca React, y dos equipos están haciendo el trabajo. Ambos deberían usar la misma versión de React y mantenerse actualizados con actualizaciones, lo que significa que siempre resolverán conflictos cuando el código sea más pequeño. No son completamente independientes entre sí en la base del código. Probablemente todos usan el mismo repositorio y un sistema de compilación. ¡Los microservicios pueden ahorrar desde aplicaciones monolíticas! Pero como es eso? Después de todo, ¡son para el backend! * sorpresa increíble *

¿Qué son los microservicios?


En términos simples, los microservicios son una técnica de desarrollo que permite a los desarrolladores realizar entregas independientes de funcionalidad (lanzamientos) para diferentes partes de la plataforma, y ​​al mismo tiempo los lanzamientos no se rompen entre sí. Los suministros independientes les permiten recolectar servicios aislados o poco acoplados. Hay varias reglas que hacen que esta arquitectura sea más robusta. Brevemente, se pueden definir de la siguiente manera: cada servicio debe ser pequeño y realizar solo una tarea. Por lo tanto, el equipo que trabaja en él también debe ser pequeño. Cuán grande puede ser un proyecto y un equipo, explique James Lewis y Martin Fowler:

Los desarrolladores que interactúan con microservicios nombran diferentes tamaños. Los más grandes cumplen con la estrategia del equipo de dos pizzas de Amazon: no más de 10-12 personas. El polo inverso: equipos de 5-6 personas, donde cada uno admite un servicio.

Aquí hay un diagrama que explica la diferencia entre un monolito y microservicios:



Se puede ver en el diagrama que cada servicio en el sistema de microservicio es una aplicación separada, excepto por la interfaz de usuario, ¡sigue siendo un todo! Cuando todos los servicios son respaldados por un equipo, el riesgo es grande de que, a medida que la empresa crezca, el equipo frontend ya no se mantendrá al día con la interfaz de usuario. Esta es la vulnerabilidad de esta arquitectura.



La arquitectura puede traer problemas de organización. Supongamos que la empresa ha crecido y adoptado una metodología de desarrollo flexible (estoy hablando de Agile). Requieren pequeños equipos interfuncionales. Por supuesto, en nuestro ejemplo abstracto, los gerentes comenzarán a separar las tareas del frontend y el backend, y los equipos interfuncionales no serán verdaderamente interfuncionales. Y todos los esfuerzos serán en vano: el equipo puede parecer flexible, pero de hecho estará muy dividido. Administrar un equipo así no es para los débiles de corazón. En cada reunión habrá una pregunta: ¿hay suficientes tareas frontend, hay suficientes tareas de back-end en el sprint? Para resolver estos y muchos otros problemas, hace un par de años apareció la idea de microfront, que rápidamente ganó popularidad.

Solución al problema: microfrontas


La solución parece bastante obvia, porque durante mucho tiempo se han aplicado con éxito principios similares en el trabajo en servicios de back-end: dividir una interfaz monolítica en pequeños fragmentos de interfaz de usuario. Sin embargo, la interfaz de usuario no es muy similar a los servicios: es una interfaz entre el usuario final y el producto, debe ser reflexiva y sistemática. Además, en la era de las aplicaciones de una sola página, se lanzan aplicaciones completas a través de un navegador en el lado del cliente. Estos ya no son simples archivos HTML, son componentes complejos que pueden contener varias interfaces de usuario y lógica de negocios. Ahora, quizás, es necesario definir microfrontas.

El principio de los microfrontes: la presentación de un sitio web o aplicación web como un conjunto de funciones de las que son responsables los equipos independientes. Cada equipo tiene su propia misión, su propio campo de trabajo en el que se especializa. El equipo es multifuncional y se desarrolla
todo el ciclo : desde la base de datos hasta la interfaz de usuario ( micro-fontend.org ).

Mi experiencia actual muestra que para muchas empresas puede ser difícil aceptar la arquitectura propuesta anteriormente. Para otros, la carga del antiguo código no permite la transición a una nueva arquitectura. Por lo tanto, se necesita una forma de migración más fluida, fácil y confiable. Habiendo examinado la arquitectura con más detalle, intentaré ofrecer mi visión para resolver el problema. Antes de profundizar en los detalles, familiarícese con la terminología.

Estructura general y algo más de terminología.

Imagine que dividimos la estructura de una aplicación monolítica verticalmente, por funciones comerciales. Obtendremos varias aplicaciones más pequeñas con la misma estructura que la aplicación monolítica. Pero si agregamos una aplicación especial sobre estas pequeñas aplicaciones monolíticas, los usuarios interactuarán con ella. A su vez, integrará la interfaz de usuario de esas pequeñas aplicaciones. Llamamos a este nivel el enlace, porque toma los elementos de la interfaz de usuario de cada microservicio y los combina en una única interfaz: esta es la implementación más directa del microfront. * sincera admiración *



Para aclararlo, a continuación llamaré a cada pequeña aplicación monolítica una micro aplicación, ya que estos no son solo microservicios, sino aplicaciones independientes: cada uno de ellos tiene elementos de interfaz de usuario y cada uno de ellos representa una función comercial completa. Como saben, el ecosistema front-end de hoy es muy diverso y puede ser bastante complejo. Y estas soluciones simples y obvias pueden no ser apropiadas en el proceso de implementación del producto.

Problemas a resolver


Cuando nació la idea de este artículo, comencé un tema en Reddit para discutirlo. Gracias a los miembros de la comunidad y sus comentarios, puedo enumerar los problemas que deben abordarse.

Problema número 1: lograr un comportamiento consistente y consistente desde la interfaz de usuario cuando tenemos varias micro aplicaciones completamente autónomas

No hay panacea, pero existe la idea de crear una biblioteca de interfaz de usuario común, que también sería una micro aplicación independiente. En este caso, todas las demás micro aplicaciones deberán depender de esta biblioteca de IU. Y eso mata su independencia.

Otra opción es crear variables CSS comunes en el nivel raíz. La ventaja de esta solución es que obtenemos un tema personalizado global para todas las aplicaciones.

O podemos hacer que las variables e impurezas SASS sean comunes a todos los equipos. Entre las desventajas de este enfoque estará la implementación repetida de elementos de IU y la necesidad de una verificación constante del diseño de elementos similares en todas las micro aplicaciones.

Problema número 2: asegúrese de que un equipo no reescriba CSS de otro equipo

En primer lugar, puede limitar el alcance de CSS utilizando selectores formados por el nombre de la microaplicación. Al colocar esta restricción en el nivel medio, puede reducir el tiempo de desarrollo general, pero al mismo tiempo, aumentará la responsabilidad del nivel medio.

En segundo lugar, puede hacer que cada microaplicación se convierta en un componente web personalizado . La ventaja de este enfoque es que el navegador maneja la restricción. Sin embargo, todo tiene un precio: con Shadow DOM, es casi imposible renderizar en el lado del servidor. Además, los elementos personalizados no son 100% compatibles con los navegadores , especialmente si necesita soporte de IE.

Problema número 3: hacer que la información global sea común a diferentes micro aplicaciones

Este problema es uno de los más comunes, pero se resuelve con bastante facilidad. HTML5 tiene una funcionalidad bastante poderosa, casi inexplorada por la mayoría de los desarrolladores front-end.
Una de estas características son los eventos personalizados que le permiten hacer que la información sea común a las micro aplicaciones.

Una implementación de pub-sub o T39 también puede ayudar. Si necesita un controlador de estado global más sutil, puede implementar un Redux general pequeño, lo que proporciona una arquitectura más receptiva.

Problema número 4: si todas las micro aplicaciones son autónomas, ¿cómo realizar el enrutamiento en el lado del cliente?

La solución al problema depende de la implementación. Todos los principales marcos modernos tienen mecanismos potentes de enrutamiento del lado del cliente que utilizan el estado del historial del navegador. El problema es qué aplicación es responsable de la ruta actual y cuándo exactamente.

Mi enfoque pragmático es crear un enrutador cliente común, responsable solo de las rutas de nivel superior, y el resto está a merced de las micro aplicaciones correspondientes. Supongamos que tenemos una definición de ruta /content/:id. El enrutador común resolverá la parte c /content , y la ruta resuelta se pasará a ContentMicroApp. ContentMicroApp es un servidor independiente que solo se llamará con /:id .

Problema número 5: ¿realmente necesitamos SSR (representación del lado del servidor), ¿es posible cuando se usan microfrontes?

La representación del lado del servidor no es fácil. Si desea agrupar micro aplicaciones usando iframes, olvídese del renderizado del lado del servidor. Del mismo modo, los componentes web para el enlace no son más fuertes que los iframes. Sin embargo, si cada una de las micro aplicaciones es capaz de representar contenido del lado del servidor, entonces la capa de conexión solo será responsable de combinar fragmentos HTML en el lado del servidor.

Problema 6: “¡La integración con el entorno existente es necesaria como el aire! ¿Cómo hacerlo?

Para la integración con los sistemas existentes, quiero describir mi visión, que llamo " implementación gradual ".

En primer lugar, debemos implementar la capa de middleware para que tenga la funcionalidad de un servidor proxy transparente. Después de eso, podemos definir el sistema existente como una microaplicación ( LegacyMicroApp ) declarando una ruta especial hacia él. Todo el tráfico que alcance el nivel de conexión se representará de manera transparente al sistema existente, ya que todavía no tenemos otras micro aplicaciones.

El siguiente paso es la implementación gradual. Tomaremos una pequeña parte de LegacyMicroApp , eliminando la navegación principal y reemplazándola por una dependencia. Esta dependencia es una micro-aplicación implementada usando la nueva tecnología brillante, NavigationMicroApp.

Ahora LegacyMicroApp interceptará todas las rutas a través de la dependencia NavigationMicroApp y la procesará internamente.

Luego, de manera similar, rehaceremos el pie de página.

Entonces continuaremos mordiendo un pedazo de LegacyMicroApp hasta que no quede nada de él.

Problema número 7: orquestar el lado del cliente para que no tenga que volver a cargar la página cada vez

La capa de middleware resuelve problemas en el lado del cliente, pero no en el lado del servidor. En el lado del cliente, al descargar un solo HTML, no podemos cargar partes individuales al cambiar las URL. Por lo tanto, necesitamos un mecanismo que cargue fragmentos de forma asincrónica. El problema es que estos fragmentos pueden tener dependencias, y estas dependencias deben poder resolverse en el lado del cliente. Esto significa que la solución de microfronte debería ofrecer un mecanismo para cargar micro aplicaciones e implementar la inyección de dependencia.

Los problemas enumerados anteriormente se pueden combinar en los siguientes temas:

Lado del cliente

  • Orquestación
  • Enrutamiento
  • Micro aislamiento
  • Interacción de la aplicación
  • Micro aplicaciones de UI de Unity

Lado del servidor

  • Representación del servidor
  • Enrutamiento
  • Gestión de dependencias

Arquitectura flexible y potente pero simple


Por el bien de esto, ¡valió la pena soportar el comienzo del artículo! Los principales elementos y requisitos de la arquitectura de microfronte finalmente han comenzado a surgir;)

Guiado por los requisitos y las preocupaciones, comencé a desarrollar una solución llamada microfe . * anticipación de comentarios *
Aquí describiré la arquitectura del proyecto, describiendo brevemente sus componentes principales.

La forma más fácil de comenzar es desde el lado del cliente, que tiene tres estructuras principales separadas: AppsManager, Loader, Router , así como una MicroAppStore adicional.



AppsManager
AppsManager es el núcleo de la orquestación de micro aplicaciones del lado del cliente. El objetivo principal de AppsManager es crear un árbol de dependencias. Una vez que se resuelven todas las dependencias, AppsManager inicia la microaplicación.

Cargador
Otra parte crucial de la orquestación del lado del cliente es Loader. Es responsable de descargar aplicaciones para el lado del cliente.

Enrutador
Para realizar el enrutamiento del lado del cliente, implementé Router en microfe. A diferencia de los enrutadores convencionales del lado del cliente, el enrutador microfe tiene una funcionalidad limitada. No procesa páginas, sino micro aplicaciones. Digamos que tenemos URL /content/detail/13 y ContentMicroApp. En este caso, el enrutador de microfe procesará la URL a /content/* y llamará a la parte ContentMicroApp /detail/13 .

Microapppore
Para resolver la interacción del cliente entre micro aplicaciones, implementé MicroAppStore en microfe. Tiene la misma funcionalidad que la biblioteca Redux, pero con una advertencia: es más flexible con respecto a la modificación asíncrona de datos y al reductor de una declaración.

***


El lado del servidor es quizás un poco más complicado de implementar, pero tiene una estructura más simple. Se compone de dos partes principales: StitchingServer y MicroAppServer.

Microappserver




La funcionalidad MicroAppServer más pequeña posible se puede expresar como: init y serve.
Cuando se inicia MicroAppServer, lo primero que debe hacer es llamar a SticthingServer y registrar un punto final con la micro-aplicación anunciada. Define las dependencias, los tipos y las URL del esquema MicroAppServer. Creo que hablar sobre el servicio es innecesario, no hay nada interesante aquí.

Servidor de costura




StitchingServer le permite registrar un punto final con MicroAppServers. Cuando MicroAppServer se registra con StichingServer, StichingServer registra la declaración de MicroAppServer.

Más tarde, StitchingServer usa el anuncio para resolver MicroAppServices desde la URL solicitada.

Después de permitir MicroAppServer y todas sus dependencias, la URL pública correspondiente aparecerá en los nombres de todas las rutas correspondientes en CSS, JS y HTML. Un paso adicional es agregar un prefijo MicroAppServer exclusivo a los selectores CSS para evitar conflictos entre las microaplicaciones en el lado del cliente.

Luego, la tarea principal de StitchingServer entra en escena: el diseño de todas las partes recibidas y el regreso de una página HTML completa.

Algunas palabras sobre otras implementaciones


Incluso antes de que apareciera el término microfrontend en 2016, muchas grandes empresas intentaron resolver problemas similares, por ejemplo, Facebook con su BigPipe .
Ahora la idea está ganando impulso. Las empresas de todos los tamaños están interesadas en este tema, invirtiendo tiempo y dinero en él. Por ejemplo, Zalando proporcionó el código fuente abierto para su solución Project Mosaic . Puedo decir que microfe y Project Mosaic siguen enfoques similares, pero con algunas diferencias cardinales. Si las microfe recurren a un enrutamiento totalmente descentralizado para hacer que cada microaplicación sea más independiente, Project Mosaic prefiere el enrutamiento centralizado y la definición de patrones para cada ruta. Por cierto, Project Mosaic facilita la realización de pruebas AB y la generación dinámica de plantillas sobre la marcha.

Existen otros enfoques, en particular, el uso de iframs como capa de conexión, obviamente, no en el lado del servidor, sino en el lado del cliente. Esta es una solución muy simple que no requiere una estructura de servidor especial y la participación de DevOps. El equipo de front-end puede implementarlo de forma independiente, lo que significa que crea menos problemas de organización para la empresa y cuesta menos.

Todavía hay un marco de spa único. El proyecto se basa en convenciones de nomenclatura para cada aplicación para permitir y descargar micro aplicaciones. Fácil de entender la idea y seguir patrones. Por lo tanto, el marco puede ser útil para conocer y experimentar con el sistema en su entorno local. El inconveniente del proyecto es que debe construir cada micro aplicación de una manera estrictamente definida; de lo contrario, el marco puede no aceptarlo.

Conclusión (y enlaces)


Creo que con el tiempo el tema de los microfrontes se considerará con más detalle. Si comienza a atraer la atención de más y más empresas, este concepto se convertirá en el método de desarrollo predeterminado en equipos grandes. Será útil para cada desarrollador front-end familiarizarse con esta arquitectura en un futuro próximo y adquirir una valiosa experiencia trabajando con ella.

servidor de registro de aplicaciones micro fe
infraestructura de micro front end

Source: https://habr.com/ru/post/459540/


All Articles