Concepto clave
En arquitecturas de micro-frontends, gestionar el estado global es como coordinar varios departamentos en una gran empresa. Cada micro-frontend (equipo) trabaja de forma independiente, pero necesita compartir información crítica como datos de usuario, preferencias o estado de la aplicacion. Redux emerge como una solucion robusta para este desafio, proporcionando un almacen centralizado y predecible que puede ser accedido por multiples aplicaciones federadas.
Imagina una cadena de hoteles donde cada propiedad (micro-frontend) tiene su propia gestion, pero todas comparten un sistema central de reservas (estado global). Redux actua como ese sistema central: mantiene una unica fuente de verdad, define reglas claras para actualizaciones (a traves de acciones y reducers), y notifica a todas las propiedades cuando hay cambios relevantes. Esto evita que un micro-frontend modifique datos que otro esta usando, previniendo conflictos y comportamientos inesperados.
Como funciona en la practica
Implementar Redux en micro-frontends con Module Federation requiere un enfoque estratificado. Primero, defines un store de Redux en un modulo remoto (host) que sera consumido por los micro-frontends (remotes). Este store debe exponerse via Module Federation, permitiendo que otros bundles lo importen como una dependencia compartida.
Paso a paso: 1) Crea un proyecto host que configure el store de Redux con sus reducers y middlewares. 2) En la configuracion de Webpack, expone el store mediante exposes en Module Federation. 3) En los proyectos remotes, configura remotes para importar el store del host. 4) Usa Provider de React-Redux en el host para envolver la aplicacion, y en los remotes, conecta los componentes usando hooks como useSelector y useDispatch. Esto asegura que todos los micro-frontends accedan al mismo estado, sincronizando datos como autenticacion o temas visuales.
Codigo en accion
Configuracion del store en el host (proyecto principal):
// host/src/store.js
import { createStore, combineReducers } from 'redux';
import userReducer from './reducers/userReducer';
import themeReducer from './reducers/themeReducer';
const rootReducer = combineReducers({
user: userReducer,
theme: themeReducer
});
const store = createStore(rootReducer);
export default store;Exposicion en Webpack config del host:
// host/webpack.config.js
module.exports = {
// ... otras configuraciones
plugins: [
new ModuleFederationPlugin({
name: 'host',
filename: 'remoteEntry.js',
exposes: {
'./store': './src/store'
},
shared: { 'react': { singleton: true }, 'react-dom': { singleton: true } }
})
]
};Uso en un micro-frontend remote:
// remote/src/App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from 'host/store'; // Importacion federada
import UserComponent from './UserComponent';
function App() {
return (
<Provider store={store}>
<UserComponent />
</Provider>
);
}
export default App;Errores comunes
- No compartir dependencias de Redux: Si
react-reduxno se comparte como singleton en Module Federation, puede causar multiples instancias y errores de contexto. Solucion: Asegurate de incluir'react-redux': { singleton: true }en la configuracion shared. - Estado inconsistente entre recargas: Al recargar un micro-frontend, el store podria reiniciarse si no esta bien persistido. Solucion: Usa middlewares como
redux-persistpara guardar el estado en localStorage o sessionStorage. - Acciones no serializables: Enviar funciones o Promises en acciones de Redux puede romper la predictibilidad. Solucion: Manten las acciones como objetos planos con tipos y datos simples, usando thunks o sagas para logica asincrona.
- Sobrecarga del store global: Incluir todo el estado en el store compartido puede ralentizar la aplicacion. Solucion: Divide el estado en global (compartido) y local (especifico de cada micro-frontend), usando Redux solo para lo esencial.
Checklist de dominio
- Configurar un store de Redux en un host y exponerlo via Module Federation.
- Importar y usar el store en al menos dos micro-frontends remotes.
- Compartir dependencias criticas como
react-reduxcomo singletons. - Implementar acciones y reducers que manejen datos compartidos, como usuario o tema.
- Usar hooks de React-Redux (
useSelector,useDispatch) en componentes remotes. - Probar la sincronizacion del estado al realizar cambios desde diferentes micro-frontends.
- Optimizar el rendimiento evitando rerenders innecesarios con selectores memorizados.
Integrar Redux en una arquitectura de micro-frontends con Module Federation
En este ejercicio, implementaras un estado global compartido usando Redux entre un host y dos micro-frontends. Sigue estos pasos:
- Crea un proyecto host con Webpack y Module Federation. Configura un store de Redux que gestione un estado simple, como un contador y un nombre de usuario.
- Expone el store desde el host usando
exposesen la configuracion de Module Federation. Asegurate de compartirreact-reduxcomo singleton. - Crea dos proyectos remotes (micro-frontends) que importen el store del host. En cada uno, desarrolla un componente que muestre y modifique el estado compartido (e.g., incrementar contador, actualizar usuario).
- Conecta los componentes a Redux usando
useSelectorpara leer el estado yuseDispatchpara enviar acciones. - Ejecuta los proyectos y verifica que los cambios en un micro-frontend se reflejen inmediatamente en el otro, demostrando el estado global sincronizado.
- Usa
createStorede Redux en el host y combina reducers para manejar multiples slices de estado. - En la configuracion de Webpack, define
shared: { 'react-redux': { singleton: true } }para evitar conflictos. - Prueba con acciones simples al principio, como incrementar un numero, antes de agregar logica compleja.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.