WU / DOCSUNIVERSAL MICROFRONTENDS
ES

Astro, React, Vue y adapters

Composición políglota con script cliente Astro, adapters reales y un bridge manual que conserva la facade scoped.

Un shell Astro con apps independientes

Astro puede servir el contenido editorial y los slots, mientras WU carga aplicaciones con su propio build Vite. El import del runtime que monta DOM debe estar en un <script> procesado por Astro, no ejecutarse como montaje en el frontmatter del servidor.

---
const title = 'Laboratorio políglota';
---
<html lang="es">
  <head><meta charset="utf-8" /><title>{title}</title></head>
  <body>
    <main>
      <div id="react-slot"></div>
      <div id="vue-slot"></div>
    </main>
    <script>
      import { wu } from 'wu-framework';
      await wu.init({
        apps: [
          { name: 'react-demo', url: '/apps/react-demo', framework: 'react' },
          { name: 'vue-demo', url: '/apps/vue-demo', framework: 'vue' },
        ],
      });
      await Promise.all([
        wu.mount('react-demo', '#react-slot'),
        wu.mount('vue-demo', '#vue-slot'),
      ]);
    </script>
  </body>
</html>

Los dos directorios públicos deben contener sus manifests y assets compilados. Para estado/eventos scoped agrega solicitudes en cada manifest y grants correspondientes en ambas configuraciones del host.

Entry React con adapter

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { register } from 'wu-framework/adapters/react';
import App from './App.jsx';

const registered = await register('react-demo', App, {
  runtime: { React, ReactDOM },
  standalone: false,
  strictMode: true,
  props: { label: 'React' },
});
if (!registered) throw new Error('No se pudo registrar react-demo');

La inyección runtime permite que el adapter utilice las mismas instancias que tu aplicación. Importa ReactDOM desde react-dom/client: el montaje requiere createRoot, aunque el rango del peer de React sea más amplio. Para hidratar, el runtime debe ofrecer también hydrateRoot.

El adapter conserva roots por nombre, implementa update fusionando props y ofrece hidratación mediante hydrateRoot cuando está disponible. standalone es true por defecto y busca #root si no encuentra WU; desactívalo para que un microfrontend integrado no se monte en otro lugar por accidente.

Entry Vue con adapter

import { register, wuVuePlugin } from 'wu-framework/adapters/vue';
import * as Vue from 'vue';
import App from './App.vue';

const registered = await register('vue-demo', App, {
  standalone: false,
  props: { label: 'Vue' },
  setup(app) {
    app.use(wuVuePlugin, { Vue });
  },
});
if (!registered) throw new Error('No se pudo registrar vue-demo');

register Vue resuelve su runtime por el mecanismo del adapter; no tiene la opción React runtime. setup recibe la app antes de montar para registrar plugins o router. El plugin acepta el namespace Vue para resolver helpers en contextos sin bare imports ni window.Vue; la entrega del namespace en setup no reemplaza por sí sola la resolución inicial de register.

La actualización usa root props reactivas cuando Vue ofrece reactive. La hidratación se anuncia cuando existe createSSRApp. standaloneContainer por defecto es #app.

Conservar la autoridad scoped

En 4.0, los adapters React/Vue transmiten la facade al árbol de componentes y sus hooks de eventos/store aplican los grants de la microapp. Declara las solicitudes del manifest y los grants del shell. El patrón manual siguiente sigue siendo útil para un renderer propio o una dependencia explícita appWu.

Para un renderer personalizado, registra un lifecycle explícito y entrega la facade como dependencia:

import { wu } from 'wu-framework';
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';

let root;
let appWu;
let props = {};
const render = () => root.render(React.createElement(App, { ...props, appWu }));

wu.define('react-demo', {
  mount(container, context) {
    appWu = context.wu;
    root = createRoot(container);
    render();
  },
  update(_container, nextProps) {
    props = { ...props, ...nextProps };
    render();
  },
  unmount() {
    root?.unmount();
    root = undefined;
    appWu = undefined;
  },
});

En Vue el mismo patrón usa createApp(App, { appWu: context.wu }), app.provide('appWu', context.wu) y app.unmount(). Si necesitas props vivas, conserva un objeto reactive y actualízalo en el slot update.

Integraciones incluidas en el paquete

Los siguientes subpaths forman parte del paquete:

Import Función
wu-framework/integrations/astro Factory para astro.config.mjs
wu-framework/integrations/astro/WuShell.astro Inicializa apps del shell
wu-framework/integrations/astro/WuApp.astro Slot de montaje, con lazy opcional
wu-framework/integrations/astro/WuAppSSR.astro Render de servidor y montaje/hidratación cliente
wu-framework/integrations/next Integración Next y componentes del paquete

Importa la integración y sus componentes desde wu-framework/integrations/astro. Los tipos del wrapper Astro exponen menos configuración que WuCore; un bootstrap cliente explícito permite controlar grants y orden de arranque cuando el shell necesita esa configuración adicional.

Hay adapters separados para React, Vue, Angular, Svelte, Preact, Solid, Lit, Vanilla, Alpine, Qwik, Stencil, HTMX y Stimulus. Selecciona el del renderer de tu aplicación y comprueba sus slots: montaje, props vivas, hidratación y transmisión del contexto tienen contratos específicos en cada adapter.

Referencia de implementación

Exports: package.json; React: src/adapters/react/index.js y src/adapters/react/index.js; Vue: src/adapters/vue/index.js y src/adapters/vue/index.js; Astro: integrations/astro/index.js, integrations/astro/WuShell.astro, integrations/astro/WuApp.astro. Pruebas: tests/unit/react-runtime-injection.test.js, tests/unit/adapter-conformance.test.js, tests/unit/adapter-slots.test.js, tests/unit/vue-slot-mount-target.test.js.

WU SE CONSTRUYE CONTIGO

¿Encontraste un bug? ¿Tienes una idea?

Tu experiencia mejora WU. Cuéntanos qué falla o ayuda a sostener su desarrollo.