Tu primera micro-app
Una micro-app de Wu es una app corriente más dos cosas:
- un manifiesto
wu.jsonservido en la raíz de la URL de la app, y - una llamada a
wu.define()(o alregister()de un adaptador) cuando se ejecuta su bundle.
Nada más cambia. Misma herramienta de build, mismo servidor de desarrollo, mismas dependencias.
Lo mínimo
Sección titulada «Lo mínimo»1. Registra un ciclo de vida
Sección titulada «1. Registra un ciclo de vida»La forma agnóstica al framework:
wu.define('cart', { mount(container) { container.innerHTML = '<h1>Carrito</h1>'; }, unmount(container) { container.innerHTML = ''; },});container es un <div> dentro de un shadow root que creó el shell por
ti. Renderiza dentro como prefieras.
Con un adaptador, lo mismo en una línea:
import { wuReact } from 'wu-framework/adapters/react';import App from './App.jsx';
wuReact.register('cart', App);// src/main.js (Vue)import { wuVue } from 'wu-framework/adapters/vue';import App from './App.vue';
wuVue.register('cart', App);El adaptador escribe la llamada a wu.define(), conecta el mount/unmount de tu
framework y añade los slots opcionales update y hydrate cuando el framework
puede soportarlos.
2. Sirve un manifiesto
Sección titulada «2. Sirve un manifiesto»{ "name": "cart", "entry": "src/main.jsx"}Debe ser accesible en <appUrl>/wu.json. En Vite, todo lo que hay en public/
se sirve desde la raíz, así que public/wu.json →
http://localhost:5173/wu.json.
Ese es todo el contrato de una micro-app. El shell obtiene wu.json, carga
entry, tu bundle llama a define() y el shell ejecuta el ciclo de vida.
Elegir entry
Sección titulada «Elegir entry»entry se resuelve de forma relativa a la URL de la app. Si empieza por un
prefijo de carpeta conocido — src/, dist/, public/, build/,
assets/, lib/ o es/ — Wu lo usa directamente:
{ "entry": "src/main.jsx" } // → <url>/src/main.jsx (desarrollo){ "entry": "assets/index-a1b2.js" }// → <url>/assets/index-a1b2.js (compilado)Cualquier otra cosa dispara un sondeo de 8 rutas: Wu lanza peticiones HEAD
en paralelo a src/, la raíz, dist/, public/, build/, assets/, lib/ y
es/, y se queda con la primera que responda con algo con pinta de JavaScript.
Funciona, pero cuesta ocho peticiones y es el origen del fallo en producción más
habitual — mira Errores comunes.
Publica siempre un entry con prefijo en producción. Para un build de Vite
eso significa apuntar al archivo con hash en dist/assets/, que puedes generar
durante el build:
// vite.config.js — escribe wu.json con el entry real tras cada buildimport { writeFileSync } from 'node:fs';
export default { plugins: [{ name: 'wu-manifest', writeBundle(_, bundle) { const entry = Object.values(bundle).find((c) => c.isEntry); writeFileSync('dist/wu.json', JSON.stringify({ name: 'cart', entry: `assets/${entry.fileName.split('/').pop()}`, styleMode: 'shared', }, null, 2)); }, }],};Sigue funcionando por su cuenta
Sección titulada «Sigue funcionando por su cuenta»Los adaptadores incluyen un respaldo standalone. Si el bundle se ejecuta en
una página donde no existe ningún runtime de Wu, register() espera un momento
(3 s por defecto), se rinde y monta el componente en #root:
wuReact.register('cart', App, { standalone: true, // por defecto standaloneContainer: '#root' // por defecto});Así http://localhost:5173 sigue funcionando como una app normal durante el
desarrollo, y el mismo bundle se convierte en micro-app cuando un shell lo
carga. Pon standalone: false si quieres que la app quede inerte fuera de un
shell.
Opciones de registro
Sección titulada «Opciones de registro»register(appName, Component, options) acepta:
| Opción | Por defecto | Significado |
|---|---|---|
props |
{} |
Props iniciales que se pasan al componente |
standalone |
true |
Monta en #root cuando no hay shell |
standaloneContainer |
'#root' |
Selector para el montaje standalone |
onMount |
null |
Callback (container) => void tras el montaje |
onUnmount |
null |
Callback (container) => void antes del desmontaje |
Las props se pueden enviar más tarde sin remontar mediante
wu.update() — el adaptador expone
un slot update cuando su framework puede volver a renderizar en el sitio.
Hablar con el resto de la página
Sección titulada «Hablar con el resto de la página»Dentro de la app, wu está disponible globalmente (y dentro de los sandboxes
strict/eval como una fachada restringida y congelada con la misma superficie
pública):
// publicarwu.emit('cart:item-added', { sku: 'SKU-42' });wu.store.set('cart.total', 142.5);
// suscribirsewu.on('user:logout', () => clearCart());wu.store.on('user.*', (value, path) => console.log(path, value));Mira Comunicación.
Lista de comprobación antes de darlo por terminado
Sección titulada «Lista de comprobación antes de darlo por terminado»-
wu.jsonse sirve en<appUrl>/wu.jsontambién en producción -
entryusa un prefijo de carpeta conocido - El servidor de la app envía
Access-Control-Allow-Originpara el origen del shell - El JavaScript se sirve con un content type de JavaScript (no
text/html) -
unmountrealmente desmonta — Wu limpia los temporizadores y listeners que puede rastrear, pero la raíz de tu framework es cosa tuya
Siguiente
Sección titulada «Siguiente»Añade un shell que la aloje.
