# 加载、entries 与预加载

从 wu.json 到模块执行：路径解析、策略、缓存与网络诊断。

<span id="de-la-url-al-lifecycle"></span>

<span class="section-anchor" id="section-1"></span>

## 从 URL 到生命周期

注册的 URL 指向应用的公共目录。注册时请求 `<url>/wu.json`。挂载期间，如果尚无定义，WU 会解析 `entry`，按照 sandbox 模式执行它，并等待通过 `wu.define` 完成注册。

发布指向真实文件的 manifest。Vite 构建可能生成带哈希的文件；部署的 manifest 必须更新为指向同一次构建的 entry。框架不会在客户端转换 TypeScript 或 JSX。

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

<span id="resolución-del-entry"></span>

<span class="section-anchor" id="section-2"></span>

## entry 解析

`resolveModulePath` 使用 manifest 的 entry，缺失时内部回退到 `main.js`。这与遇到 404 时生成的 manifest 不同，后者的 entry 为 `index.js`。

1. 如果 entry 以 `src/`、`dist/`、`public/`、`build/`、`assets/`、`lib/` 或 `es/` 开头，则直接与 base 拼接使用。
2. 其他情况下，先检查声明的原始路径。
3. 如果不存在，则并行尝试这些常见目录，选择结果时保留优先顺序。
4. 如果全部没有响应，返回声明路径，使错误指向作者配置的文件。

检查使用 `HEAD`，并通过 content type 区分 JavaScript 与 SPA 的 HTML 回退页面。如果服务器不支持 HEAD 并返回 405，则允许带范围的 GET。成功的解析按 base 和 entry 缓存；能够生成正确 manifest 时，无需依赖这些启发式查找。

<span id="elegir-una-estrategia"></span>

<span class="section-anchor" id="section-3"></span>

## 选择策略

| 宿主配置中的 `strategy` | 行为 |
| --- | --- |
| `lazy` | 不预加载；挂载时加载 |
| `eager` | init 期间执行 `import()` |
| `preload` | 插入 `link rel="prefetch"` 资源 |
| `speculate` | 委托给 prefetcher |
| `idle` | 策略可将加载入队；没有 `shouldPreload`，因此仅声明它不会自动让 init 的 preloader 调度它 |

要从 shell 控制加载，请使用 `lazy`，并在适当时机调用 `mount` 或 `prefetch`。Astro 类型中有 `manual`，但它不是 core 注册的策略；未知策略会使用 lazy 并发出警告。

**Eager 会执行代码**，并且在挂载前通过宿主 realm 中的直接 import 执行。它不等同于下载字节，也不等同于使用 strict sandbox 挂载。要提前下载，保留 lazy 并使用 prefetch API；检查项目的 CSP 策略和浏览器兼容性。

<span id="prefetch-explícito"></span>

<span class="section-anchor" id="section-4"></span>

## 显式 prefetch

```js
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` 返回 Promise。`hover`、`visible` 和 `idle` 同步返回取消函数。如果之后要将它们作为 cleanup 调用，不要将所有返回值一律转为 Promise。触发器会按情况安装监听器、IntersectionObserver 或 idle 回调。

实现会检测 Speculation Rules、modulepreload 和 prefetch 作为备选。这是向浏览器提出请求，不保证执行、速度或离线可用性。

<span id="componentes-exportados-por-una-app"></span>

<span class="section-anchor" id="section-5"></span>

## 应用导出的组件

除生命周期 entry 外，manifest 还可在 `wu.exports` 中声明可共享模块。使用方应用在 `wu.imports` 中声明 `catalog.ProductCard` 等依赖；所有应用注册完成后，全局预检验证这些名称。

```json
{
  "name": "catalog",
  "entry": "assets/catalog.js",
  "wu": {
    "exports": { "ProductCard": "components/product-card.js" },
    "imports": []
  }
}
```

```js
const ProductCard = await wu.use('catalog.ProductCard');
```

`use` 严格要求 `app.component` 格式，检查应用和导出项，并通过延迟 loader 加载模块。如果存在 `module.default` 则返回它，否则返回模块命名空间。文件必须兼容使用方 renderer；WU 不会自动将 React 组件转换为 Vue 组件。

此方法存在于运行时中，但未列入 `WuCore` 的公开声明；在类型化代码中使用时，参阅 [TypeScript 说明](/zh-cn/docs/framework/api-reference/#compatibilidad-de-las-declaraciones-typescript)。

loader 将路径限制在应用 base 下，拒绝路径穿越和组件绝对 URL，并使用原生 import。这种模块共享不同于 `provide/consume` 契约：它本身不包含方法版本管理，也没有与 RPC 相同的作用域模型。

<span id="dependencias-y-cors"></span>

<span class="section-anchor" id="section-6"></span>

## 依赖与 CORS

浏览器还需要解析 entry 的全部传递性 imports。如果发布的 bundle 保留 `react` 或 `vue` 这样的 bare imports，请提供一致的 import map，或将这些依赖打包。也应将 `dist` 作为静态文件提供并测试，以发现依赖 Vite 开发服务器的 imports 或路径。

对于跨源 URL，manifest、entry、chunks 和样式都必须符合 CORS 与 CSP 的访问要求。返回 HTML 的 HTTP 200 仍然是错误路径，即使网络面板显示绿色也一样。除 status 外，还要验证内容和 MIME。

<span id="referencia-de-implementación"></span>

<span class="section-anchor" id="section-7"></span>

## 实现参考

解析器：`src/core/wu-core.js`；HEAD 验证：`src/core/wu-core.js`；import：`src/core/wu-core.js`；组件：`src/core/wu-core.js` 和 `src/core/wu-loader.js`；等待 define：`src/core/wu-core.js`；策略：`src/core/wu-strategies.js`；prefetch：`src/core/wu-prefetch.js`。测试：`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`。