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.
El arquetipo — empieza por aquí
Sección titulada «El arquetipo — empieza por aquí»
cd archetypenpm install
npm run dev # shell de Vue + Pinia → :4300npm run dev -- --shell=react # shell de React → :4300npm run dev -- --shell=qwik # shell de Qwik → :4300Tres 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:
- Escribe
pagosen el buscador Qwik → la cola de React se filtra - 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.
La tienda — cuatro frameworks
Sección titulada «La tienda — cuatro frameworks»
cd examplesnpm installnpm run dev # levanta las cinco en paraleloAbre 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 suelta —npm 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.
Los ejemplos de servidor van aparte
Sección titulada «Los ejemplos de servidor van aparte»En el mismo monorepo hay dos que no comparten nada con la tienda:
ssr-storefront(:5010) — servidor propio, sin framework de shellshell-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.
Una trampa que solo aparece aquí
Sección titulada «Una trampa que solo aparece aquí»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.
