Exportar aplicaciones

Este capítulo explica cómo usar createBridgeComponent para exportar tu aplicación React como un módulo que se puede cargar de forma remota.

Instalación

npm
yarn
pnpm
npm install @module-federation/bridge-react@latest

Uso básico

Paso 1: crear la entrada de exportación

Para exportar una aplicación React, debes crear un archivo de exportación dedicado y usar createBridgeComponent para envolver la aplicación como un módulo remoto.

Suponiendo que la entrada de tu aplicación es App.tsx, crea un archivo nuevo export-app.tsx:

// ./src/export-app.tsx
import App from './App';
import { createBridgeComponent } from '@module-federation/bridge-react';

// Use createBridgeComponent to wrap App as a remote module and export
export default createBridgeComponent({
  rootComponent: App
});

Paso 2: configurar la exportación con exposes

A continuación, debes configurar Module Federation en tu herramienta de build para exponer el archivo de exportación que creaste, de modo que otras aplicaciones puedan usarlo.

Compatibilidad con herramientas de build

El siguiente ejemplo usa la configuración de Rsbuild. Ajústalo según tu herramienta de build:

  • Rsbuild: @module-federation/rsbuild-plugin
  • Rspack: @module-federation/enhanced/rspack
  • Webpack: @module-federation/enhanced/webpack
  • Vite: @module-federation/vite
// rsbuild.config.ts
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default {
  plugins: [
    pluginModuleFederation({
      name: 'remote1',
      exposes: {
        './export-app': './src/export-app.tsx', // Export application-type remote module
      },
    }),
  ],
};

Configuración de Bridge Router

React Bridge ofrece potentes capacidades de coordinación de rutas que pueden inyectar dinámicamente el basename y pasar el contexto de rutas según la ruta actual.

Compatibilidad con frameworks de enrutamiento
  • Actualmente, Bridge Router admite la funcionalidad de proxy de rutas para las versiones v5, v6 y v7 de React Router.

  • No admite otros frameworks de enrutamiento, como @tanstack/react-router. En aplicaciones que usan frameworks distintos de React Router, debes deshabilitar explícitamente enableBridgeRouter y gestionar la lógica de enrutamiento por tu cuenta.

Habilitar Bridge Router

// rsbuild.config.ts
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default {
  plugins: [
    pluginModuleFederation({
      name: 'remote1',
      exposes: {
        './export-app': './src/export-app.tsx',
      },
      bridge: {
        // Enable Bridge Router routing capabilities, default is true
        enableBridgeRouter: true,
      }
    }),
  ],
};

Descripción de la configuración

  • enableBridgeRouter: true (predeterminado): gestiona automáticamente el basename y la coordinación de rutas; admite React Router v5, v6 y v7
  • enableBridgeRouter: false: deshabilita las capacidades de proxy de rutas predeterminadas de Bridge; debes gestionar la integración del enrutamiento manualmente
Importante

Si habilitas Bridge Router, no configures react-router-dom como dependencia compartida; de lo contrario, provocará problemas en el enrutamiento.

Referencia de la API createBridgeComponent

Importante

@module-federation/bridge-react/v18 y /v19 importan createRoot desde react-dom/client.

Si solo configuras "react-dom" como dependencia compartida, react-dom/client no se compartirá, lo que puede provocar errores de incompatibilidad de versiones de React. Asegúrate de usar la forma de prefijo con barra final:

shared: {
  'react-dom/': {
    singleton: true,
  },
}

Firma de la función

function createBridgeComponent<T = any>(
  bridgeInfo: Omit<ProviderFnParams<T>, 'createRoot'>
): () => {
  render(info: RenderParams): Promise<void>;
  destroy(info: DestroyParams): void;
}

ProviderFnParams<T>

Parámetros de configuración del componente Bridge:

interface ProviderFnParams<T> {
  // Root component
  rootComponent: React.ComponentType<T>;
  
  // Custom render function (optional)
  render?: (App: React.ReactElement, id?: HTMLElement | string) => RootType | Promise<RootType>;
  
  // Custom createRoot function (optional, React 18+)
  createRoot?: (container: Element | DocumentFragment, options?: CreateRootOptions) => Root;
  
  // Default createRoot options (React 18+)
  defaultRootOptions?: CreateRootOptions;
}

RenderParams

Interfaz de los parámetros de renderizado:

interface RenderParams {
  moduleName?: string;
  basename?: string;
  memoryRoute?: {
    entryPath: string;
    initialState?: Record<string, unknown>;
  };
  dom: HTMLElement;                    // Target DOM element for rendering
  rootOptions?: CreateRootOptions;     // React 18+ createRoot options
  [key: string]: unknown;             // Other custom properties
}

DestroyParams

Interfaz de los parámetros de destrucción:

interface DestroyParams {
  moduleName: string;
  dom: HTMLElement;
}

CreateRootOptions

Opciones de createRoot de React 18+:

interface CreateRootOptions {
  identifierPrefix?: string;                                    // Identifier prefix
  onRecoverableError?: (error: unknown) => void;              // Recoverable error handling
  transitionCallbacks?: unknown;                               // Transition callbacks
}

Ejemplos de uso avanzado

Lógica de renderizado personalizada

// ./src/export-app.tsx
import App from './App';
import { createBridgeComponent } from '@module-federation/bridge-react';
import { createRoot } from 'react-dom/client';

export default createBridgeComponent({
  rootComponent: App,
  
  // Custom render function
  render: (App, container) => {
    const root = createRoot(container as HTMLElement, {
      identifierPrefix: 'my-app-'
    });
    root.render(App);
    return root;
  },
  
  // Default createRoot options
  defaultRootOptions: {
    identifierPrefix: 'remote-app-',
    onRecoverableError: (error) => {
      console.error('Remote app recoverable error:', error);
    }
  }
});

Compatibilidad con múltiples exportaciones

// ./src/export-app.tsx
import App from './App';
import Dashboard from './Dashboard';
import { createBridgeComponent } from '@module-federation/bridge-react';

// Export main application
export default createBridgeComponent({
  rootComponent: App
});

// Export dashboard component
export const dashboard = createBridgeComponent({
  rootComponent: Dashboard
});

Configuración de Module Federation correspondiente:

// rsbuild.config.ts
export default {
  plugins: [
    pluginModuleFederation({
      name: 'remote1',
      exposes: {
        './export-app': './src/export-app.tsx',     // Main application
        './dashboard': './src/export-app.tsx',      // Dashboard
      },
    }),
  ],
};

Próximos pasos

Una vez completada la configuración para exportar la aplicación, puedes seguir leyendo Cargar aplicaciones remotas para aprender a cargar esta aplicación remota en una aplicación host.