Carga, entries y precarga
Del wu.json al módulo ejecutado: resolución de rutas, estrategia, caché y diagnóstico de red.
De la URL al lifecycle
La URL registrada apunta al directorio público de una aplicación. El registro solicita <url>/wu.json. Durante el montaje, si aún no existe una definición, WU resuelve el entry, lo ejecuta conforme al modo de sandbox y espera el registro con wu.define.
Publica un manifest que nombre el archivo real. Un build Vite puede emitir hashes; el manifest desplegado debe actualizarse para apuntar al entry de esa misma compilación. El framework no transforma TypeScript ni JSX en el cliente.
{
"name": "reports",
"entry": "assets/reports-C4z8m.js",
"styleMode": "own-only"
}
Resolución del entry
resolveModulePath utiliza el entry del manifest, con fallback interno main.js si no existe. Esto es distinto del manifest generado ante 404, cuyo entry es index.js.
- Si el entry empieza por
src/,dist/,public/,build/,assets/,lib/oes/, se usa directamente junto a la base. - En otros casos se comprueba primero la ruta literalmente declarada.
- Si no existe, se prueban en paralelo esos directorios comunes, manteniendo el orden de prioridad al elegir un resultado.
- Si ninguno responde, se devuelve la ruta declarada para que el error mencione el archivo que el autor configuró.
Las comprobaciones emplean HEAD y distinguen JavaScript de un fallback HTML de SPA mediante el content type. Si el servidor no admite HEAD y responde 405, se permite un GET con rango. La resolución exitosa se conserva por base y entry; no hay motivo para depender de las heurísticas si puedes emitir el manifest correcto.
Elegir una estrategia
strategy en config host |
Comportamiento |
|---|---|
lazy |
No precarga; se carga al montar |
eager |
Ejecuta import() durante init |
preload |
Inserta un recurso link rel="prefetch" |
speculate |
Delega al prefetcher |
idle |
La estrategia puede encolar una carga; no tiene shouldPreload, así que declararla no la agenda automáticamente en el preloader de init |
Para controlar la carga desde el shell usa lazy y llama a mount o prefetch cuando corresponda. manual aparece en los tipos de Astro, pero no es una estrategia registrada del core; una estrategia desconocida utiliza lazy y emite una advertencia.
Eager ejecuta código, y lo hace mediante un import directo en el realm del host, antes del montaje. No es equivalente a descargar bytes ni a montar con sandbox strict. Para anticipar una descarga conserva lazy y usa las APIs de prefetch; comprueba la política CSP y la compatibilidad del navegador del proyecto.
Prefetch explícito
await wu.prefetch(['reports', 'catalog']);
const cancelHover = wu.prefetch('reports', {
on: 'hover',
target: '#reports-link',
});
const cancelVisible = wu.prefetch('catalog', {
on: 'visible',
target: '#catalog-slot',
});
// Cuando esos elementos abandonen el shell:
cancelHover();
cancelVisible();
immediate devuelve una promesa. hover, visible e idle devuelven una función de cancelación síncrona. No conviertas indiscriminadamente todos esos retornos en promesas si luego quieres invocarlos como cleanup. Los disparadores instalan listeners, IntersectionObserver o callbacks idle según el caso.
La implementación detecta Speculation Rules, modulepreload y prefetch como alternativas. Es una petición al navegador, no garantía de ejecución, velocidad ni disponibilidad offline.
Componentes exportados por una app
Además del entry de lifecycle, un manifest puede declarar módulos compartibles en wu.exports. Una app consumidora declara dependencias como catalog.ProductCard en wu.imports; el preflight global comprueba esos nombres una vez registradas todas las apps.
{
"name": "catalog",
"entry": "assets/catalog.js",
"wu": {
"exports": { "ProductCard": "components/product-card.js" },
"imports": []
}
}
const ProductCard = await wu.use('catalog.ProductCard');
use exige exactamente app.component, comprueba la app y la exportación y carga el módulo mediante el loader diferido. Devuelve module.default si existe o el namespace del módulo en caso contrario. El archivo debe ser compatible con el renderer consumidor; WU no convierte automáticamente un componente React en Vue.
El método existe en el runtime, pero no está enumerado en la declaración pública de WuCore; consulta las notas de TypeScript al consumirlo desde código tipado.
El loader confina la ruta bajo la base de la app, rechaza traversal y URLs absolutas de componente y utiliza import nativo. Ese intercambio de módulos es distinto del contrato provide/consume: no incorpora por sí mismo versionado de métodos ni el mismo modelo scoped de RPC.
Dependencias y CORS
El navegador necesita resolver también todos los imports transitivos del entry. Si mantienes bare imports como react o vue en un bundle publicado, proporciona un import map coherente o empaqueta esas dependencias. Prueba también dist servido como archivos estáticos para detectar imports o rutas que dependían del servidor de desarrollo de Vite.
Para URLs de distinto origen, el manifest, entry, chunks y estilos deben estar accesibles según CORS y CSP. Un HTTP 200 con HTML es una ruta errónea, aunque la pestaña de red parezca verde. Verifica contenido y MIME, además del status.
Referencia de implementación
Resolver: src/core/wu-core.js; validación HEAD: src/core/wu-core.js; import: src/core/wu-core.js; componentes: src/core/wu-core.js y src/core/wu-loader.js; espera de define: src/core/wu-core.js; estrategias: src/core/wu-strategies.js; prefetch: src/core/wu-prefetch.js. Pruebas: tests/unit/entry-path-resolution.test.js, tests/unit/prefetch.test.js, tests/unit/dist-bundler-directives.test.js, tests/unit/abort-timeout.test.js.