什么是 WU
了解 WU 解决的问题、应用与 shell 如何协作,以及何时适合使用。
版本、变更与要求见 Framework 3.2 与 CLI 1.0。
WU 可将独立 Web 应用汇集到同一页面。各应用保留自己的界面和框架,由 WU 协调何时显示、何时移除,以及如何相互通信。
该包包含 React、Vue、Angular、Svelte、Preact、Solid、Lit、Vanilla、Alpine、Qwik、Stencil、HTMX 和 Stimulus 的适配器。请在适配器参考中查看各自的契约。
对于其他技术,可以通过 wu.define 注册 mount 和 unmount,或使用 createWuAdapter 构建适配器。统一契约既能连接使用相同框架的应用,也能连接使用不同框架的应用。
它解决的问题
设想一个商店:商品目录用 React,购物车用 Vue。两个团队需要分别修改和发布各部分,但用户期待统一体验:在目录选择商品后,购物车立即显示它。
WU 加载两个应用,为各自提供容器,并提供共享数据的通道。商品目录可以通知选择结果,无需导入购物车组件或代码。两个应用也可以都使用 React:应用独立才是关键,混合框架只是可选能力。
理解三个组成部分
1. 应用提供一部分界面
商品目录和购物车是微应用,也称 microfrontends 或 MFE。各应用注册如何在容器中渲染,以及退出时如何释放自己创建的资源。在 WU 中,这些操作称为 mount 和 unmount,构成应用生命周期。
可以直接使用 JavaScript,也可以使用 adapter,将 React、Vue 等框架的生命周期连接到 WU。适配器避免在每个应用中重复编写连接代码。
2. Shell 决定各应用显示在哪里
shell 或 host 是汇集应用的页面,定义 URL、预留显示空间,并协调导航、权限和可见错误。可以使用 Astro、其他框架,或 HTML 与 JavaScript 构建。
在商店中,shell 可以为目录和购物车分别预留区域,无需了解它们的内部组件。
3. Runtime 在运行期间连接应用
runtime 是在页面中执行的 JavaScript 包 wu-framework,负责加载和挂载应用,并提供事件、共享状态和带响应的调用。
例如,目录选择商品后发出事件,购物车接收并更新界面。shell 授予各应用需要的权限。完成首次挂载后,可在应用间通信学习这些机制。
WU CLI 负责准备项目。 wu 命令在终端运行,生成文件、准备依赖、启动开发并汇总生产文件。运行时则在用户打开的应用中工作。如果用自己的工具准备文件,也可以不使用 CLI。了解 CLI 流程。
何时适合使用
- 不同团队需要分别维护和发布同一体验中的不同部分。
- 迁移期间,需要让新应用与现有应用并存。
- 需要组合界面,并明确应用间的样式边界和通信方式。
如果单一应用、路由和组件已满足需求,拆分微应用会增加配置、挂载和协调工作。使用 WU 不需要多个框架,仅仅使用多个组件也不意味着需要 WU。
WU 也不是执行恶意代码的安全边界。Shadow DOM 封装 DOM 和样式,但本身不阻止访问页面 JavaScript 上下文。选择第三方代码加载方式前,请参阅隔离和安全与权限。
从一个应用开始
按照第一个应用生成包含一个微应用的 shell,并在浏览器确认结果。然后可以添加另一个应用并准备生产版本。
流程使用 Astro 和 React 举例,你也可以选择其他 shell 和框架。
挂载应用时会发生什么
shell 声明应用 URL。该 URL 下的 manifest(wu.json)描述 WU 应加载的 JavaScript 文件,即 entry。这个文件注册生命周期;shell 请求挂载后,界面便出现。
查看最小 JavaScript 挂载示例
此示例展示涉及的文件,假设项目已通过 bundler 解析 import ... from 'wu-framework',并能提供应用文件;它不是安装教程。第一个应用会准备该环境。
shell HTML 包含 <div id="hello-slot"></div>,其客户端模块执行:
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:
{
"name": "hello",
"entry": "assets/hello.js",
"styleMode": "own-only",
"wu": { "permissions": [] }
}
bundle assets/hello.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 发布到静态服务器,不会自动使其成为可执行模块。
共享实例与应用权限
主导入创建或复用 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,则重新获得宿主权限。
进一步了解
| 想了解的内容 | 继续阅读 |
|---|---|
| 声明应用、URL、manifest 和权限 | 配置 |
| 挂载、卸载与资源清理 | 生命周期 |
| 向另一应用发送事件或请求响应 | 通信 |
| 共享可被界面观察的数据 | 共享状态 |
| 查找方法签名和约定 | API 参考 |
| 集成 Astro、Next 或服务器渲染 | 集成 |
查看技术边界与实现源码
软件包提供 ESM、CommonJS 和 UMD,工具要求 Node >=20.0.0。浏览器运行客户端 runtime;wu-framework/server 入口提供服务器渲染函数。每个适配器各有 renderer 和 hydration 要求。
WU 不要求 Astro 使用自身 islands 渲染 React/Vue 树,它可以在 shell 容器中挂载独立 bundle。
运行时范围
- core 没有解释 manifest 路由的通用路由器。
- Shadow DOM 封装 DOM/CSS,本身不阻止访问主窗口。
strict和eval使用同源 iframe,不构成抵御恶意代码的边界。- Store、历史和 timeline 存在于内存中,不提供数据库或持久审计。
- 应用在浏览器上下文执行;core 不包含执行任意任务的通用 driver、Worker 或 WASM 引擎。
实现参考
| 部分 | 职责 | 源码 |
|---|---|---|
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。
参阅监督、恢复与 replay,了解 superviseApp、createReplaySession 和 scoped 方法 reportError、now、random。