Concepto clave
Module Federation de Webpack es una tecnología que permite a aplicaciones web independientes cargar código de otras aplicaciones en tiempo de ejecución. Imagina un edificio de apartamentos donde cada departamento es una aplicación completa con su propia cocina, baño y sala, pero comparten servicios como el ascensor y la recepción. En Module Federation, cada micro-frontend es como un apartamento: autónomo, pero puede usar componentes o funciones de otros apartamentos cuando sea necesario.
La clave está en que no necesitas reconstruir todo el edificio cada vez que cambias un apartamento. Cada micro-frontend se construye y despliega por separado, y en tiempo de ejecución, Webpack coordina la carga de módulos remotos. Esto es fundamental para arquitecturas distribuidas donde equipos diferentes trabajan en partes distintas del frontend, permitiendo actualizaciones independientes sin afectar el todo.
Cómo funciona en la práctica
Para crear tu primer micro-frontend básico, sigue estos pasos: primero, configura dos proyectos independientes: uno como host (la aplicación principal) y otro como remote (el micro-frontend). En el remote, defines qué módulos exponer al exterior usando la configuración de Module Federation. En el host, configuras qué módulos remotos consumir. Webpack genera archivos especiales que permiten la comunicación entre ambos.
Por ejemplo, si tienes un equipo trabajando en un carrito de compras y otro en un catálogo de productos, el carrito puede exponer un componente CartButton que el catálogo consume dinámicamente. Al construir, Webpack crea un manifest que lista los módulos disponibles, y en tiempo de ejecución, el host carga el módulo remoto solo cuando se necesita, reduciendo el tamaño inicial de la aplicación.
Codigo en accion
Configuración básica en el remote (micro-frontend):
// webpack.config.js en el proyecto remote
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
output: {
publicPath: "http://localhost:3001/",
},
plugins: [
new ModuleFederationPlugin({
name: "remoteApp",
filename: "remoteEntry.js",
exposes: {
"./Button": "./src/components/Button",
},
shared: ["react", "react-dom"],
}),
],
};
Configuración en el host (aplicación principal):
// webpack.config.js en el proyecto host
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: "hostApp",
remotes: {
remoteApp: "remoteApp@http://localhost:3001/remoteEntry.js",
},
shared: ["react", "react-dom"],
}),
],
};
Uso en el host para cargar el componente remoto:
// En un componente del host
import React, { Suspense } from "react";
const RemoteButton = React.lazy(() => import("remoteApp/Button"));
function App() {
return (
Aplicación Host
Cargando... }>