Concepto clave
El versionado y rollback en micro-frontends con Module Federation es como gestionar una flota de aviones comerciales. Cada micro-frontend es un avion que puede actualizarse independientemente, pero todos deben coordinar sus versiones para evitar colisiones en el aire. El versionado semantico (SemVer) es crucial: MAJOR.MINOR.PATCH, donde MAJOR indica cambios incompatibles, MINOR añade funcionalidad compatible, y PATCH corrige errores.
En un entorno distribuido, el rollback no es simplemente revertir codigo; es restaurar un estado funcional del sistema cuando una nueva version causa problemas. Esto requiere estrategias como blue-green deployments o canary releases, donde se despliegan multiples versiones simultaneamente y se enruta el trafico gradualmente. La clave es mantener la compatibilidad hacia atras y tener un plan de contingencia claro.
Como funciona en la practica
Imagina que tienes tres micro-frontends: Header (v1.2.0), ProductList (v2.1.0), y Checkout (v1.5.0). Al actualizar ProductList a v2.2.0:
- Primero, defines la nueva version en el package.json del micro-frontend ProductList.
- Configuras Module Federation para exponer la nueva version con un identificador unico, como "[email protected]".
- En el shell (aplicacion principal), actualizas la referencia remota para apuntar a la nueva version, pero mantienes la antigua disponible temporalmente.
- Implementas un sistema de enrutamiento que permita cambiar entre versiones basado en cookies o headers HTTP.
- Monitoreas metricas como errores de JavaScript y tiempo de carga; si hay problemas, activas el rollback redirigiendo el trafico a la version anterior.
Codigo en accion
Configuracion de Module Federation para versionado explicito:
// webpack.config.js del micro-frontend ProductList (v2.2.0)
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
output: {
publicPath: 'https://cdn.tuempresa.com/product-list/2.2.0/',
},
plugins: [
new ModuleFederationPlugin({
name: 'productList',
filename: 'remoteEntry.js',
exposes: {
'./ProductList': './src/ProductList',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
},
}),
],
};
Antes: referenciar una version fija en el shell podia causar bloqueos. Despues: usar un sistema dinamico que permita cambiar versiones:
// shell (aplicacion principal) - configuracion dinamica de remotes
const loadRemote = (url, scope, module) => {
return async () => {
await __webpack_init_sharing__('default');
const container = window[scope];
await container.init(__webpack_share_scopes__.default);
const factory = await container.get(module);
return factory();
};
};
// Ejemplo: cargar ProductList v2.2.0 o v2.1.0 basado en configuracion
const productListVersion = getConfig().productListVersion; // ej: '2.2.0'
const remoteUrl = `https://cdn.tuempresa.com/product-list/${productListVersion}/remoteEntry.js`;
const ProductListModule = await loadRemote(remoteUrl, 'productList', './ProductList');
Errores comunes
- No probar la compatibilidad entre versiones: Desplegar un micro-frontend con cambios MAJOR sin verificar que el shell y otros micro-frontends sigan funcionando. Solucion: Usar pruebas de integracion automatizadas que simulen el entorno completo.
- Olvidar el versionado de dependencias compartidas: Si React se actualiza en un micro-frontend pero no en otros, puede causar errores. Solucion: Definir versiones estrictas en shared y usar singleton.
- Rollback manual lento: Confiar en procesos manuales para revertir cambios, lo que aumenta el tiempo de inactividad. Solucion: Automatizar el rollback con scripts o herramientas CI/CD.
- Ignorar el cache del navegador
- No documentar los cambios de version: Los equipos no saben que versiones son compatibles. Solucion: Mantener un CHANGELOG y usar herramientas como semantic-release.
Checklist de dominio
- ¿Implementas versionado semantico (SemVer) en todos los micro-frontends?
- ¿Tienes un sistema para cargar dinamicamente diferentes versiones de remotes en tiempo de ejecucion?
- ¿Automatizas el proceso de rollback con triggers basados en metricas (ej: tasa de errores > 5%)?
- ¿Probaste la compatibilidad hacia atras al desplegar nuevas versiones MINOR o PATCH?
- ¿Configuraste dependencias compartidas con versiones estrictas y singleton para evitar conflictos?
- ¿Documentas los cambios de version y su impacto en otros micro-frontends?
- ¿Usas estrategias de despliegue como blue-green o canary para reducir riesgo?
Implementar un sistema de rollback automatizado para un micro-frontend
En este ejercicio, configuraras un sistema basico de rollback para un micro-frontend usando Module Federation y scripts de CI/CD. Sigue estos pasos:
- Crea dos versiones de un micro-frontend simple (ej: un componente que muestra un mensaje). Version A: mensaje "Hola Mundo". Version B: mensaje "Hola Universo" (simula un cambio que podria fallar).
- Configura Module Federation para exponer cada version en URLs diferentes (ej: /v1/ y /v2/).
- En el shell, implementa una funcion que cargue dinamicamente la version del micro-frontend basada en una variable de configuracion (ej: un archivo JSON o variable de entorno).
- Crea un script de despliegue (puede ser un archivo bash o Node.js) que:
- Despliegue la nueva version (v2).
- Espere 30 segundos y monitoree logs o metricas simuladas (ej: contar errores en la consola).
- Si se detectan mas de 2 errores simulados, automaticamente cambie la configuracion para usar la version anterior (v1).
- Ejecuta el script y verifica que el rollback ocurra cuando simules errores.
- Usa publicPath en webpack para diferenciar versiones en URLs.
- Puedes simular errores agregando console.error() en el codigo de la version B.
- Considera usar herramientas como PM2 o scripts simples para gestionar el cambio de configuracion.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.