Microfrontends con CRA¶
Deprecated
CRA se encuentra deprecado y ya no es posible crear proyectos utilizando estos templates. La documentación queda como referencia para todas aquellos proyectos que todavía no se han migrado.
Se tienen dos templates de CRA para trabajar con Microfrontend, para módulo y shell, que utilizan Module Federation para generar las configuraciones necesarias que permiten convertir una aplicación en un MF.
Los templates de MF estan basados en el template base de CRA. Se puede visualizar el Workshop de Frontend realizado, para ver mejor como está conformado y su funcionamiendo.
Module Federation¶
El archivo moduleFederation.config.js
es una parte esencial de la configuración de un microfrontend basado en Module Federation. Proporciona información crucial para la correcta integración y comunicación entre diferentes microfrontends en una arquitectura distribuida.
Propiedades¶
-
name
: El nombre único del microfrontend que se utilizará para identificarlo dentro del sistema. -
library
: Define cómo se expone el microfrontend como un módulo, generalmente utilizando el formato "var", "amd", "commonjs" o "umd". -
filename
: El nombre del archivo generado para el microfrontend. Se puede personalizar para facilitar la caché y el versionamiento. -
remotes
: Una lista de microfrontends externos a los que este microfrontend desea acceder. Aquí se definen las dependencias y módulos remotos. -
expose
: Los módulos locales que este microfrontend está dispuesto a compartir con otros microfrontends. -
shared
: Los módulos compartidos que pueden ser utilizados por varios microfrontends. Esto permite reducir el tamaño del paquete y mejorar la eficiencia de la aplicación.
En conjunto, el moduleFederation.config.js
es un archivo crucial para establecer la interoperabilidad entre los diferentes microfrontends en una arquitectura de Module Federation, permitiendo que los microfrontends se comuniquen y compartan recursos de manera eficiente y organizada.
Template Shell¶
El template nos provee toda la configuracion inicial para poder levantar un shell sin problemas ejecutando npm start donde ya tiene integrado su login para comenzar a trabajar con b2c, tambien unos ejemplos para tener como referencias como las rutas (como generarlas), pages, ejemplos de domain y services para ayudar a la implementacion.
npm start
En cuanto a la arquitectura de carpetas dentro de src:
name | descripción |
---|---|
adapters | ejemplo de como adaptar un objeto o transformarlo a una necesidad |
app | ejemplo de como llamar a un metodo configurado en el services |
components | alerts - idTokenClaims - SecureWrapper |
domain | estructuras de objetos |
hooks | van nuestras funciones Hook customizadas con un ejemplo |
layout | pagina presentacional inicial |
pages | declaracion de paginas de la app con sus nombres y estilos |
routes | componente donde se declaran las rutas con su path y se configura el path con el que se consumira el module |
services | donde se declaran los endpoint a consumir , un ejemplo de datos locales |
store | ejemplo de como gestionar el estado global compartido entre los diferentes componentes del microfrontend. Es una estructura centralizada que permite acceder y modificar los datos desde cualquier parte del microfrontend de manera predecible y eficiente |
Las configuraciones para conectar un shell y un módulo, se deberían hacer utilizando las utilidades de la librería @architecture-it/microfrontend-utils, en cuya documentación se especifican las configuraciones a realizar.
REACT_APP_MFE_REMOTE=remote@http://localhost:3001/remoteEntry.js
Info
En los environments del shell Luego de REACT_APP_MFE_{nombre del module} (nombre del modulo) aqui especifica que se conectara con el microfrontend subido al puerto 3001, lo que quiere decir que para acceder y probar su convivencia necesitamos tener levantado ambos proyectos y basandonos en la configuracion que mencionamos en las rutas para acceder a las rutas del module debemos agregar el path /module para acceder al index del microfront consumido (module) o al path del mismo desde nuestro shell
Template Módulo¶
Al igual que para el shell, el template del módulo tiene todas las configuraciones básicas para levantar un proyecto y conectarlo con otros MF.
Se debe configurar Module Federation para discriminar el nombre identificatorio del módulo (el que luego también va a utilizar el shell para conectarse) y para exponer todas las secciones de nuestra aplicación que se quieran poder consumir desde otros microfrontends, utilizando la propiedad expose
.
Warning
-
Recordar que para probar la conexion entre ambos luego de dichas configuraciones es necesario que ambos proyectos esten levantados.
-
Para el uso de librerias compartidas entre dos MFEs donde el shell especifica la version para compartir dicha libreria, por el momento optamos por no compartir ninguna libreria en el ecosistema. Se levanto una issue para analizar el problema y su configuracion ya que la misma en el moduleFederation no reacciona como deberia. Se deja la imagen como ejemplo:
FAQ¶
Los estilos entre los MicroFrontends se pisan
-
Instalar la librería microfrontend-utils utilizando el manejador de paquetes de tu proyecto npm/pnpm:
pnpm i @architecture-it/microfront-utils
-
Agregar la función
addMicrofrontCssIdenName
dentro del export deoverride
enviando los parámetrosconfig
yenv
provenientes de la configuración de webpack antes de retornar config. - Aplicar el mismo procedimiento para los módulos.
Ejemplo de implementación en un proyecto legacy:
const { addMicrofrontCssIdenName } = require("@architecture-it/microfront-utils/overwrite");
const webpack = require("webpack");
/**
*
* @param {import("webpack").Configuration} config
* @param {*} env
* @returns {import("webpack").Configuration}
*/
module.exports = function override(config, _env) {
const fallback = config.resolve.fallback || {};
Object.assign(fallback, {
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("stream-browserify"),
assert: require.resolve("assert"),
http: require.resolve("stream-http"),
https: require.resolve("https-browserify"),
os: require.resolve("os-browserify"),
url: require.resolve("url"),
util: require.resolve("util/"),
});
config.resolve.fallback = fallback;
config.plugins = (config.plugins || []).concat([
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
}),
]);
config.ignoreWarnings = [/Failed to parse source map/];
// Agrega la función para manejar los prefijos de CSS
addMicrofrontCssIdenName(config, _env);
return config;
};