WU / DOCSUNIVERSAL MICROFRONTENDS
EN

Loading, entries, and prefetching

From wu.json to the executed module: path resolution, strategy, caching, and network diagnostics.

From URL to lifecycle

The registered URL points to an application’s public directory. Registration requests <url>/wu.json. During mounting, if no definition exists yet, WU resolves the entry, executes it according to the sandbox mode, and waits for registration with wu.define.

Publish a manifest that names the actual file. A Vite build may emit hashes; the deployed manifest must be updated to point to the entry from that same build. The framework does not transform TypeScript or JSX on the client.

{
  "name": "reports",
  "entry": "assets/reports-C4z8m.js",
  "styleMode": "own-only"
}

Entry resolution

resolveModulePath uses the manifest entry, with an internal main.js fallback if it is absent. This differs from the manifest generated for a 404, whose entry is index.js.

  1. If the entry starts with src/, dist/, public/, build/, assets/, lib/, or es/, it is used directly with the base.
  2. Otherwise, the literally declared path is checked first.
  3. If it does not exist, those common directories are checked in parallel, retaining priority order when choosing a result.
  4. If none responds, the declared path is returned so the error names the file the author configured.

Checks use HEAD and distinguish JavaScript from an SPA HTML fallback through content type. If the server does not support HEAD and returns 405, a ranged GET is allowed. Successful resolution is cached by base and entry; there is no reason to depend on heuristics if you can emit the correct manifest.

Choose a strategy

strategy in host configuration Behavior
lazy No preloading; loads on mount
eager Runs import() during init
preload Inserts a link rel="prefetch" resource
speculate Delegates to the prefetcher
idle The strategy can queue a load; it has no shouldPreload, so declaring it does not automatically schedule it in the init preloader

To control loading from the shell, use lazy and call mount or prefetch as appropriate. manual appears in Astro types but is not a registered core strategy; an unknown strategy uses lazy and emits a warning.

Eager executes code, using a direct import in the host realm before mounting. It is not equivalent to downloading bytes or mounting with a strict sandbox. To prefetch a download, keep lazy and use prefetch APIs; check the project’s CSP policy and browser compatibility.

Explicit prefetch

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 returns a promise. hover, visible, and idle return a synchronous cancellation function. Do not indiscriminately turn all these return values into promises if you later want to call them for cleanup. Triggers install listeners, IntersectionObserver, or idle callbacks as appropriate.

The implementation detects Speculation Rules, modulepreload, and prefetch as alternatives. This is a request to the browser, not a guarantee of execution, speed, or offline availability.

Components exported by an app

Beyond the lifecycle entry, a manifest can declare shareable modules in wu.exports. A consuming app declares dependencies such as catalog.ProductCard in wu.imports; global preflight checks those names after all apps are registered.

{
  "name": "catalog",
  "entry": "assets/catalog.js",
  "wu": {
    "exports": { "ProductCard": "components/product-card.js" },
    "imports": []
  }
}
const ProductCard = await wu.use('catalog.ProductCard');

use requires exactly app.component, checks the app and export, and loads the module through the deferred loader. It returns module.default if present, or the module namespace otherwise. The file must be compatible with the consuming renderer; WU does not automatically convert a React component into Vue.

The method exists at runtime but is not listed in the public WuCore declaration; see the TypeScript notes when consuming it from typed code.

The loader confines the path beneath the app base, rejects traversal and absolute component URLs, and uses native import. This module exchange differs from the provide/consume contract: it does not itself include method versioning or the same scoped RPC model.

Dependencies and CORS

The browser must also resolve all transitive entry imports. If you keep bare imports such as react or vue in a published bundle, provide a consistent import map or bundle those dependencies. Also test dist served as static files to detect imports or paths that depended on Vite’s development server.

For cross-origin URLs, the manifest, entry, chunks, and styles must be accessible under CORS and CSP. An HTTP 200 with HTML is an incorrect route, even if the network tab looks green. Check content and MIME as well as status.

Implementation references

Resolver: src/core/wu-core.js; HEAD validation: src/core/wu-core.js; import: src/core/wu-core.js; components: src/core/wu-core.js and src/core/wu-loader.js; define wait: src/core/wu-core.js; strategies: src/core/wu-strategies.js; prefetch: src/core/wu-prefetch.js. Tests: 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.

BUILD WU WITH US

Found a bug? Have an idea?

Your experience improves WU. Tell us what went wrong or help support its development.