Así que lo que hacemos es cargar React 18 una segunda vez, y esta vez React 18.3.0, y básicamente hacemos un intercambio en caliente, que es el homónimo de esta solución, lo que significa que cargamos React 18 de nuevo, y básicamente sobrescribimos el objeto window.react18, y ahora estamos usando React 18.3.0, que debería ser compatible, si Sanver lo permite, con la versión anterior, que es 18.1.0. Ahora, el primer problema con el que nos encontramos es un problema de sub-dependencias. Así que algunas dependencias en nuestra lista dependen de otras dependencias en nuestra lista, por ejemplo, MobX React depende de ambos MobX y React, que ambos existen en nuestra lista, lo que crea muchas combinaciones variables. Así que tomemos dos ejemplos, por ejemplo, digamos que uno de nuestros micro-frontends tiene MobX React 8 y usa React 16, y otro tiene MobX React 8, nuevamente la misma versión de MobX React, y usa React 18. En este caso, ambos micro-frontends van a usar la misma versión global de MobX React, que es MobX React 8, pero el problema es que MobX React bajo el capó necesita una versión muy específica de React, necesita React 18, para funcionar correctamente en tiempo de ejecución y no obtener muchos errores de React y pantallas rojas de la muerte. Entonces, ¿qué hacemos al respecto? Nuestra solución fue muy, muy simple. Queremos asegurarnos de que cuando creamos nuestras dependencias, nos aseguramos de que las creamos con nombres compuestos, y eso significa que cada dependencia también incluye en su nombre global todas sus sub-dependencias. Así que digamos que tenemos MobX React, que depende de React. Cuando añadimos la combinación de MobX React 8 y React 16, vamos a hacer React 16 guion bajo MobX React 8, y cuando tenemos MobX React 8 y React 18, vamos a hacer React 18 guion bajo, y así sucesivamente. Este es un ejemplo simplificado. Podríamos terminar con una situación donde tengamos como tres sub-dependencias de diferentes niveles y podríamos terminar con un nombre compuesto muy largo, pero eso básicamente asegura que los micro-frontends y sus sub-dependencias obtengan la referencia correcta en producción. Eso también nos obliga a actualizar el archivo de metadatos para reflejar este cambio e incluir sub-dependencias.
Así que esto cambia un poco nuestra solución. En lugar de construir con un nombre simplificado, usamos la misma lista con las mismas versiones que obtenemos de Package.json para crear el paquete con nombres compuestos por dependencia. Esta es la única diferencia. Todos los demás pasos en el proceso de construcción y en el proceso de tiempo de ejecución permanecen iguales, y eso fue todo para este problema, pero nos encontramos con un problema diferente. Lo que pensamos que sucedería cuando intercambiamos en caliente dependencias en producción es lo siguiente. Digamos que cargamos nuestro primer micro-frontend que usa React 18.1.0 y hace referencia a window.react18, y ahora digamos que cargamos un segundo micro-frontend que usa React 18.3.0. Como mencionamos antes, React 18.
1.0 no es compatible con 18.3.0, que es lo que nuestro segundo micro-frontend necesita. Así que cargamos React de nuevo y reemplazamos el puntero window.react18 para apuntar a nuestra nueva versión de React, así que cargamos React dos veces. Lo que esperábamos que sucediera es que ambos de nuestros micro-frontends iban a referenciar window.react18 en el código de tiempo de ejecución, y todo estaría genial, pero lo que realmente terminó sucediendo es que nuestro primer micro-frontend mantuvo la referencia de memoria a la primera instancia de React que cargamos en la página. Así que en lugar de usar la misma nueva instancia que nuestro segundo micro-frontend, siguió usando la instancia antigua, lo que significaba que no fue recolectada por el recolector de basura y en realidad cargamos React dos veces en la página, lo cual pierde un poco el sentido de lo que estamos tratando de hacer aquí. Así que esto nos llevó a revisar toda nuestra solución y básicamente crear una versión v2 de nuestra solución, que llamamos dependencias globales. Así que las dependencias globales son muy similares a la solución anterior que teníamos tanto en el proceso de construcción como en el proceso de tiempo de ejecución. La única diferencia es que durante el proceso de construcción de nuestros micro-frontends, también actualizamos algún tipo de archivo de metadatos global que tenemos, que mantenemos en el servidor. Y básicamente, este archivo de metadatos global contiene referencias a qué micro-frontend en nuestro sistema tenía la versión más alta por mayor de nuestras dependencias. Así que en este ejemplo simplificado, podemos ver que, por ejemplo, si necesitas usar React18 en tu micro-frontend, y no importa qué micro-frontend seas, sabemos que micro-frontend1 tiene la versión más alta de React18 posible en el sistema. Así que esta podría ser una situación en la que, por ejemplo, tenemos micro-frontend1 usando React18.7.0 y micro-frontend3, por ejemplo, usa React18.3.0. Cuando micro-frontend3 se carga en la página, va a usar la versión de React18 que es proporcionada por micro-frontend1 y existe en esta URL. De esta manera, tenemos una lista con todos los, incluyendo los nombres compuestos y todas nuestras dependencias por versión mayor a través de nuestro sistema.
Comments