Ir al contenido

Ejemplos

Hay dos monorepos ejecutables en el repositorio. No son fragmentos: son aplicaciones que arrancan, se comunican y se pueden abrir cada una por su cuenta.

Descargá el código: wu-store-example.zip (la tienda, ~70 KB) · wu-archetype-example.zip (el arquetipo, ~40 KB). Ambos son monorepos con npm workspaces + lerna: descomprimí, npm install en la raíz, y los comandos de cada sección de abajo funcionan tal cual.

Si solo vas a mirar uno, mira el arquetipo.

Mesa de incidencias: buscador Qwik, cola React y actividad Svelte dentro de un shell Vue
Ventana de terminal
cd archetype
npm install
npm run dev # shell de Vue + Pinia → :4300
npm run dev -- --shell=react # shell de React → :4300
npm run dev -- --shell=qwik # shell de Qwik → :4300

Tres micro-apps —Qwik, React y Svelte— y tres shells que las componen. Cambias de shell con una bandera; las micro-apps ni se enteran.

Los tres escuchan en el mismo puerto, a propósito: deja la pestaña abierta, para, arranca con otra bandera y recarga. La cabecera cambia; lo de dentro de los huecos, no.

Es la mejor demostración de la propuesta porque la puedes falsar en un minuto:

  1. Escribe pagos en el buscador Qwik → la cola de React se filtra
  2. Pulsa resolver → la actividad de Svelte registra la entrada y la cabecera del shell Vue actualiza los contadores

Cuatro frameworks reaccionando a un clic, y ninguno importa código de otro. Todo pasa por el bus y el store.

Wu Store: catálogo Vue, carrito React y pedidos Svelte dentro de un shell Angular
Ventana de terminal
cd examples
npm install
npm run dev # levanta las cinco en paralelo

Abre http://localhost:4200: shell de Angular con el catálogo de Vue, el carrito de React y los pedidos de Svelte.

El flujo que demuestra: el catálogo emite por el bus sin saber quién escucha, el carrito lo recoge y escribe en el store, y el shell y los pedidos leen ese store. Apaga una app y las demás siguen.

Paquete Lo que enseña
shell-angular Componer apps ajenas: wu.init(), wu.mount(), createWuService()
app-vue-catalog Emitir por el bus sin conocer al receptor
app-react-cart Escuchar el bus y publicar en el store compartido
app-svelte-orders Suscribirse al store, y own-only + tagStyleAsApp() para estilos

Cada app corre también sueltanpm run dev dentro de su carpeta— porque los adapters caen a modo standalone si no encuentran shell. El mismo bundle sirve para las dos cosas.

En el mismo monorepo hay dos que no comparten nada con la tienda:

  • ssr-storefront (:5010) — servidor propio, sin framework de shell
  • shell-next (:3000) — Next.js como shell, desde un Server Component

Míralos después, cuando la tienda ya te resulte obvia. Ver Renderizado en servidor.

Las micro-apps de React que se sirven desde su propio servidor de Vite y se cargan dentro de un shell ajeno necesitan una línea extra en su punto de entrada:

if (import.meta.hot && !window.__vite_plugin_react_preamble_installed__) {
const RefreshRuntime = await import('/@react-refresh');
RefreshRuntime.injectIntoGlobalHook(window);
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;
window.__vite_plugin_react_preamble_installed__ = true;
}

@vitejs/plugin-react inyecta ese preamble en el index.html que él sirve, y el código que compila comprueba que exista. Con un shell de otro framework ese HTML no interviene, así que el módulo muere con «can’t detect preamble».

Cargada en solitario la app funciona, porque entonces sí sirve su propio HTML. Por eso es fácil que pase desapercibido: falla exactamente en el caso que un repositorio de microfrontends existe para demostrar.

No afecta a producción — Fast Refresh no existe en el build — ni a wu-cli, donde el servidor de desarrollo compila el JSX él mismo y no hay preamble que perder.