Español

Desbloquea el poder de los micro-frontends con la Federación de Módulos de JavaScript en Webpack 5. Aprende a construir aplicaciones web escalables, mantenibles e independientes.

Federación de Módulos de JavaScript con Webpack 5: Una Guía Completa para Micro-frontends

En el panorama siempre cambiante del desarrollo web, construir aplicaciones grandes y complejas puede ser una tarea abrumadora. Las arquitecturas monolíticas tradicionales a menudo conducen a un aumento del tiempo de desarrollo, cuellos de botella en el despliegue y desafíos para mantener la calidad del código. Los micro-frontends han surgido como un poderoso patrón arquitectónico para abordar estos desafíos, permitiendo a los equipos construir y desplegar partes independientes de una aplicación web más grande. Una de las tecnologías más prometedoras para implementar micro-frontends es la Federación de Módulos de JavaScript (JavaScript Module Federation), introducida en Webpack 5.

¿Qué son los Micro-frontends?

Los micro-frontends son un estilo arquitectónico en el que una aplicación frontend se descompone en unidades más pequeñas e independientes, que pueden ser desarrolladas, probadas y desplegadas de forma autónoma por diferentes equipos. Cada micro-frontend es responsable de un dominio de negocio o característica específica, y se componen en tiempo de ejecución para formar la interfaz de usuario completa.

Piénsalo como una empresa: en lugar de tener un equipo de desarrollo gigante, tienes múltiples equipos más pequeños enfocados en áreas específicas. Cada equipo puede trabajar de forma independiente, lo que permite ciclos de desarrollo más rápidos y un mantenimiento más fácil. Considera una gran plataforma de comercio electrónico como Amazon; diferentes equipos podrían gestionar el catálogo de productos, el carrito de compras, el proceso de pago y la gestión de cuentas de usuario. Todos estos podrían ser micro-frontends independientes.

Beneficios de los Micro-frontends:

Desafíos de los Micro-frontends:

¿Qué es la Federación de Módulos de JavaScript?

La Federación de Módulos de JavaScript (JavaScript Module Federation) es una característica de Webpack 5 que permite compartir código entre aplicaciones JavaScript compiladas por separado en tiempo de ejecución. Te permite exponer partes de tu aplicación como "módulos" que pueden ser consumidos por otras aplicaciones, sin necesidad de publicarlos en un repositorio central como npm.

Piensa en la Federación de Módulos como una forma de crear un ecosistema federado de aplicaciones, donde cada aplicación puede contribuir con su propia funcionalidad y consumir funcionalidad de otras aplicaciones. Esto elimina la necesidad de dependencias en tiempo de compilación y permite despliegues verdaderamente independientes.

Por ejemplo, un equipo de sistema de diseño puede exponer componentes de UI como módulos, y diferentes equipos de aplicación pueden consumir estos componentes directamente desde la aplicación del sistema de diseño, sin necesidad de instalarlos como paquetes de npm. Cuando el equipo del sistema de diseño actualiza los componentes, los cambios se reflejan automáticamente en todas las aplicaciones consumidoras.

Conceptos Clave en la Federación de Módulos:

Configurando la Federación de Módulos con Webpack 5: Una Guía Práctica

Vamos a recorrer un ejemplo práctico de configuración de la Federación de Módulos con Webpack 5. Crearemos dos aplicaciones simples: una aplicación Host (Anfitrión) y una aplicación Remote (Remota). La aplicación Remota expondrá un componente, y la aplicación Anfitrión lo consumirá.

1. Configuración del Proyecto

Crea dos directorios separados para tus aplicaciones: `host` y `remote`.

```bash mkdir host remote cd host npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom cd ../remote npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom ```

2. Configuración de la Aplicación Remota

En el directorio `remote`, crea los siguientes archivos:

src/index.js:

```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (

Aplicación Remota

); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

src/RemoteComponent.jsx:

```javascript import React from 'react'; const RemoteComponent = () => (

¡Este es un Componente Remoto!

Renderizado desde la Aplicación Remota.

); export default RemoteComponent; ```

webpack.config.js:

```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3001, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'remote', filename: 'remoteEntry.js', exposes: { './RemoteComponent': './src/RemoteComponent', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```

Crea `public/index.html` con una estructura HTML básica. Lo importante es `

`

3. Configuración de la Aplicación Anfitrión

En el directorio `host`, crea los siguientes archivos:

  • `src/index.js`: Punto de entrada de la aplicación.
  • `webpack.config.js`: Archivo de configuración de Webpack.

src/index.js:

```javascript import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; const RemoteComponent = React.lazy(() => import('remote/RemoteComponent')); const App = () => (

Aplicación Anfitrión

Cargando Componente Remoto...
}>
); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

webpack.config.js:

```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3000, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { remote: 'remote@http://localhost:3001/remoteEntry.js', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```

Crea `public/index.html` con una estructura HTML básica (similar a la aplicación remota). Lo importante es `

`

4. Instalar Babel

En ambos directorios, `host` y `remote`, instala las dependencias de Babel:

```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```

5. Ejecutar las Aplicaciones

En ambos directorios, `host` y `remote`, añade el siguiente script a `package.json`:

```json "scripts": { "start": "webpack serve" } ```

Ahora, inicia ambas aplicaciones:

```bash cd remote npm start cd ../host npm start ```

Abre tu navegador y navega a `http://localhost:3000`. Deberías ver la aplicación Anfitrión con el Componente Remoto renderizado dentro de ella.

Explicación de las Opciones de Configuración Clave:

Técnicas Avanzadas de Federación de Módulos

La Federación de Módulos ofrece muchas características avanzadas que pueden ayudarte a construir arquitecturas de micro-frontends aún más sofisticadas.

Remotos Dinámicos

En lugar de codificar las URLs de las aplicaciones remotas en la configuración de Webpack, puedes cargarlas dinámicamente en tiempo de ejecución. Esto te permite actualizar fácilmente la ubicación de las aplicaciones remotas sin tener que reconstruir la aplicación anfitrión.

Por ejemplo, podrías almacenar las URLs de las aplicaciones remotas en un archivo de configuración o una base de datos y cargarlas dinámicamente usando JavaScript.

```javascript // En webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Asumimos que remoteUrl es algo como 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // la clave de la federación de módulos es que la aplicación remota está // disponible usando el nombre en el remoto resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

Ahora puedes cargar la aplicación anfitrión con un parámetro de consulta `?remote=http://localhost:3001/remoteEntry.js`

Módulos Compartidos Versionados

La Federación de Módulos puede manejar automáticamente el versionado y la deduplicación de módulos compartidos para asegurar que solo se cargue una versión compatible de cada módulo. Esto es especialmente importante cuando se trata de aplicaciones grandes y complejas que tienen muchas dependencias.

Puedes especificar el rango de versiones de cada módulo compartido en la configuración de Webpack.

```javascript // En webpack.config.js shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```

Cargadores de Módulos Personalizados

La Federación de Módulos te permite definir cargadores de módulos personalizados que se pueden usar para cargar módulos de diferentes fuentes o en diferentes formatos. Esto puede ser útil para cargar módulos desde un CDN o desde un registro de módulos personalizado.

Compartir Estado entre Micro-frontends

Uno de los desafíos de las arquitecturas de micro-frontend es compartir el estado entre diferentes micro-frontends. Hay varios enfoques que puedes tomar para abordar este desafío:

Mejores Prácticas para Implementar Micro-frontends con Federación de Módulos

Aquí hay algunas mejores prácticas a tener en cuenta al implementar micro-frontends con la Federación de Módulos:

Ejemplos del Mundo Real de la Federación de Módulos en Acción

Aunque los estudios de caso específicos suelen ser confidenciales, aquí hay algunos escenarios generalizados donde la Federación de Módulos puede ser increíblemente útil:

Conclusión

La Federación de Módulos de JavaScript en Webpack 5 proporciona una forma poderosa y flexible de construir arquitecturas de micro-frontend. Te permite compartir código entre aplicaciones JavaScript compiladas por separado en tiempo de ejecución, permitiendo despliegues independientes, diversidad tecnológica y una mejor autonomía del equipo. Siguiendo las mejores prácticas descritas en esta guía, puedes aprovechar la Federación de Módulos para construir aplicaciones web escalables, mantenibles e innovadoras.

El futuro del desarrollo frontend se inclina indudablemente hacia arquitecturas modulares y distribuidas. La Federación de Módulos proporciona una herramienta crucial para construir estos sistemas modernos, permitiendo a los equipos crear aplicaciones complejas con mayor velocidad, flexibilidad y resiliencia. A medida que la tecnología madure, podemos esperar ver aún más casos de uso innovadores y mejores prácticas emergentes.