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.