# 什么是 WU

了解 WU 解决的问题、应用与 shell 如何协作，以及何时适合使用。

版本、变更与要求见 [Framework 3.2 与 CLI 1.0](/zh-cn/docs/guides/releases/)。


WU 可将独立 Web 应用汇集到同一页面。各应用保留自己的界面和框架，由 WU 协调何时显示、何时移除，以及如何相互通信。

该包包含 **React、Vue、Angular、Svelte、Preact、Solid、Lit、Vanilla、Alpine、Qwik、Stencil、HTMX 和 Stimulus** 的适配器。请在[适配器参考](/zh-cn/docs/framework/api-adapters/)中查看各自的契约。

对于其他技术，可以通过 `wu.define` 注册 `mount` 和 `unmount`，或使用 [`createWuAdapter`](/zh-cn/docs/framework/api-adapters/#createwuadapter) 构建适配器。统一契约既能连接使用相同框架的应用，也能连接使用不同框架的应用。

<span id="el-problema-que-resuelve"></span>

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

## 它解决的问题

设想一个商店：商品目录用 React，购物车用 Vue。两个团队需要分别修改和发布各部分，但用户期待统一体验：在目录选择商品后，购物车立即显示它。

WU 加载两个应用，为各自提供容器，并提供共享数据的通道。商品目录可以通知选择结果，无需导入购物车组件或代码。两个应用也可以都使用 React：**应用独立才是关键，混合框架只是可选能力**。

<span id="tres-piezas-para-entenderlo"></span>

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

## 理解三个组成部分

<span id="1-la-app-aporta-una-parte-de-la-interfaz"></span>

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

### 1. 应用提供一部分界面

商品目录和购物车是**微应用**，也称 microfrontends 或 MFE。各应用注册如何在容器中渲染，以及退出时如何释放自己创建的资源。在 WU 中，这些操作称为 `mount` 和 `unmount`，构成应用生命周期。

可以直接使用 JavaScript，也可以使用 **adapter**，将 React、Vue 等框架的生命周期连接到 WU。[适配器](/zh-cn/docs/framework/api-adapters/)避免在每个应用中重复编写连接代码。

<span id="2-el-shell-decide-dónde-aparece-cada-app"></span>

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

### 2. Shell 决定各应用显示在哪里

**shell** 或 **host** 是汇集应用的页面，定义 URL、预留显示空间，并协调导航、权限和可见错误。可以使用 Astro、其他框架，或 HTML 与 JavaScript 构建。

在商店中，shell 可以为目录和购物车分别预留区域，无需了解它们的内部组件。

<span id="3-el-runtime-las-conecta-durante-la-ejecución"></span>

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

### 3. Runtime 在运行期间连接应用

**runtime** 是在页面中执行的 JavaScript 包 `wu-framework`，负责加载和挂载应用，并提供事件、共享状态和带响应的调用。

例如，目录选择商品后发出事件，购物车接收并更新界面。shell 授予各应用需要的权限。完成首次挂载后，可在[应用间通信](/zh-cn/docs/framework/communication/)学习这些机制。

**WU CLI 负责准备项目。** `wu` 命令在终端运行，生成文件、准备依赖、启动开发并汇总生产文件。运行时则在用户打开的应用中工作。如果用自己的工具准备文件，也可以不使用 CLI。[了解 CLI 流程](/zh-cn/docs/cli/overview/)。

<span id="cuándo-tiene-sentido"></span>

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

## 何时适合使用

- 不同团队需要分别维护和发布同一体验中的不同部分。
- 迁移期间，需要让新应用与现有应用并存。
- 需要组合界面，并明确应用间的样式边界和通信方式。

如果单一应用、路由和组件已满足需求，拆分微应用会增加配置、挂载和协调工作。使用 WU 不需要多个框架，仅仅使用多个组件也不意味着需要 WU。

WU 也不是执行恶意代码的安全边界。Shadow DOM 封装 DOM 和样式，但本身不阻止访问页面 JavaScript 上下文。选择第三方代码加载方式前，请参阅[隔离](/zh-cn/docs/framework/sandbox/)和[安全与权限](/zh-cn/docs/framework/security/)。

<span id="empieza-con-una-app"></span>

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

## 从一个应用开始

按照[第一个应用](/zh-cn/docs/guides/quickstart/)生成包含一个微应用的 shell，并在浏览器确认结果。然后可以[添加另一个应用](/zh-cn/docs/guides/add-an-app/)并[准备生产版本](/zh-cn/docs/guides/production/)。

流程使用 Astro 和 React 举例，你也可以选择其他 shell 和框架。

<span id="qué-sucede-al-montar-una-app"></span>

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

## 挂载应用时会发生什么

shell 声明应用 URL。该 URL 下的 **manifest**（`wu.json`）描述 WU 应加载的 JavaScript 文件，即 **entry**。这个文件注册生命周期；shell 请求挂载后，界面便出现。

<details>
<summary>查看最小 JavaScript 挂载示例</summary>

此示例展示涉及的文件，假设项目已通过 bundler 解析 `import ... from 'wu-framework'`，并能提供应用文件；它不是安装教程。[第一个应用](/zh-cn/docs/guides/quickstart/)会准备该环境。

shell HTML 包含 `<div id="hello-slot"></div>`，其**客户端**模块执行：

```js
import { wu } from 'wu-framework';

await wu.init({
  apps: [{ name: 'hello', url: '/apps/hello' }],
  sandbox: 'module',
});

await wu.mount('hello', '#hello-slot');
```

该 URL 提供文件 `/apps/hello/wu.json`：

```json
{
  "name": "hello",
  "entry": "assets/hello.js",
  "styleMode": "own-only",
  "wu": { "permissions": [] }
}
```

bundle `assets/hello.js` 在求值时注册应用：

```js
import { wu } from 'wu-framework';

wu.define('hello', {
  mount(container) {
    const heading = document.createElement('h2');
    heading.textContent = 'Hola desde WU';
    container.append(heading);
  },
  unmount(container) {
    container.replaceChildren();
  },
});
```

`wu.mount` 完成后，容器显示 **Hola desde WU**。`wu.define` 注册如何渲染，`wu.mount` 让界面出现。目录注册、manifest 和 `define` 的名称必须一致。入口必须是浏览器可执行的 JavaScript；把原始 JSX/TSX 发布到静态服务器，不会自动使其成为可执行模块。

<span id="una-instancia-compartida-y-permisos-por-app"></span>

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

### 共享实例与应用权限

主导入创建或复用 `window.wu`，并暴露 `Symbol.for('wu-framework')`。同一页面的模块必须一致地解析运行时，复制软件包不会自动产生隔离实例。在 Node 中，导入的 `wu` 仍是进程共享的模块实例；SSR 应使用 `wu-framework/server` 和每请求数据。

shell 导入的 `wu` 具有宿主权限。应用 `mount(container, context)` 回调的第二个参数包含 `context.wu`，这是 **facade**，即受该应用权限限制的 WU 访问入口，卸载时会撤销。请使用此参数保留权限约定。与 shell 共享 JavaScript 上下文的微前端若取得 `window.wu`，则重新获得宿主权限。

</details>

<span id="si-necesitas-profundizar"></span>

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

## 进一步了解

| 想了解的内容 | 继续阅读 |
| --- | --- |
| 声明应用、URL、manifest 和权限 | [配置](/zh-cn/docs/framework/configuration/) |
| 挂载、卸载与资源清理 | [生命周期](/zh-cn/docs/framework/lifecycle/) |
| 向另一应用发送事件或请求响应 | [通信](/zh-cn/docs/framework/communication/) |
| 共享可被界面观察的数据 | [共享状态](/zh-cn/docs/framework/state/) |
| 查找方法签名和约定 | [API 参考](/zh-cn/docs/framework/api-reference/) |
| 集成 Astro、Next 或服务器渲染 | [集成](/zh-cn/docs/framework/integrations/) |

<details>
<summary>查看技术边界与实现源码</summary>

软件包提供 ESM、CommonJS 和 UMD，工具要求 Node `>=20.0.0`。浏览器运行客户端 runtime；`wu-framework/server` 入口提供服务器渲染函数。每个适配器各有 renderer 和 hydration 要求。

WU 不要求 Astro 使用自身 islands 渲染 React/Vue 树，它可以在 shell 容器中挂载独立 bundle。

<span id="alcance-del-runtime"></span>

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

### 运行时范围

- core 没有解释 manifest 路由的通用路由器。
- Shadow DOM 封装 DOM/CSS，本身不阻止访问主窗口。
- `strict` 和 `eval` 使用同源 iframe，不构成抵御恶意代码的边界。
- Store、历史和 timeline 存在于内存中，不提供数据库或持久审计。
- 应用在浏览器上下文执行；core 不包含执行任意任务的通用 driver、Worker 或 WASM 引擎。

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

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

### 实现参考

| 部分 | 职责 | 源码 |
| --- | --- | --- |
| `WuCore` | 注册、初始化、挂载、卸载和容器所有权 | `src/core/wu-core.js` |
| Manifest `wu.json` | 入口、exports、声明式依赖和权限申请 | `src/core/wu-manifest.js` |
| 应用生命周期 | 将 renderer 接入所提供容器并从中移除 | `src/index.d.ts` |
| Sandbox 与 style bridge | DOM 边界、样式分发和副作用跟踪 | `src/core/wu-sandbox.js` |
| 事件总线与 RPC | 带身份的事件，以及具有响应、版本和取消能力的请求 | `src/core/wu-event-bus.js` |
| Store | 共享数据、独立快照和通知 | `src/core/wu-store.js` |
| Shell | URL、grants、导航、组合和可见错误处理 | `src/core/wu-core.js` |

Exports 约定位于 `package.json`；singleton 和全局访问位于 `src/index.js`；scoped context 位于 `src/core/wu-core.js` 和 `src/core/wu-core.js`。相关测试包括 `tests/unit/package-exports.test.js`、`tests/unit/core-store-isolation.test.js` 和 `tests/unit/capability-security-v3.test.js`。

</details>

参阅[监督、恢复与 replay](/zh-cn/docs/framework/runtime-reliability/)，了解 `superviseApp`、`createReplaySession` 和 scoped 方法 `reportError`、`now`、`random`。