核心、子系统与清单
选择可选入口,并在文件、宿主或应用模块中声明契约。
本页介绍 WU Framework 4.0.0。升级现有项目之前,请阅读 Framework 4.0 与 CLI 1.2 迁移指南。
选择运行时
wu-framework 在首次使用时加载可选子系统。wu-framework/core 要求宿主显式导入。CLI 1.0.0 在开发和生产环境中让宿主与应用共享核心入口。
import { wu } from 'wu-framework/core';
import 'wu-framework/timeline';
import 'wu-framework/ports';
await wu.init({ apps: [] });
const timeline = await wu.timelineReady();
| 功能 | 宿主导入 |
|---|---|
| AI | wu-framework/ai |
| Timeline | wu-framework/timeline |
| Devtools | wu-framework/devtools |
| MCP | wu-framework/mcp |
strict |
wu-framework/sandbox/iframe |
eval |
wu-framework/sandbox/html-parser + wu-framework/sandbox/iframe |
| Store sync | wu-framework/store-sync |
| Shadow | wu-framework/shadow |
| Windows | wu-framework/windows |
| Drag and drop | wu-framework/dnd |
| Ports / remote | wu-framework/ports |
.wuapp |
wu-framework/wuapp |
缺少导入时,WU_OPTIONAL_NOT_BUNDLED 会指出子系统及所需入口。在宿主中导入一次并重新构建。导入只注册子系统,不会授予应用权限。
三种清单来源
manifest: "fetch" 默认加载 wu.json。manifest 对象可在宿主中声明同样的信息。使用 manifest: "define" 时,模块调用 wu.declare 或向 wu.define 的第三个参数传入 { manifest };必须配置 entry,因为没有预先提供模块入口的文件。
// shell.js
import { wu } from 'wu-framework/core';
await wu.init({ apps: [{
name: 'greeting', url: '/apps/greeting/',
manifest: 'define', entry: 'entry.js', grants: [],
}] });
await wu.mount('greeting', '#greeting-slot');
// apps/greeting/entry.js
import { wu } from 'wu-framework/core';
wu.define('greeting', {
mount(container) { container.textContent = 'Hello from WU'; },
unmount(container) { container.replaceChildren(); },
}, { manifest: { wu: { permissions: [] } } });
宿主 HTML 必须包含 #greeting-slot;应用模块必须导入与宿主相同的 WU 实例。三种模式都验证清单并应用宿主授权。用 JavaScript 声明并不会使代码保密,也不会建立安全边界。
加载时的身份
definesAs 可为保留原始名称的模块注册另一实例。加载期间,WU 将 define 和 declare 重定向到新注册项。每个重定向名称只能有一个活动加载,否则返回 WU_DEFINE_REDIRECT_BUSY。名称错误时,WU_DEFINE_NAME_MISMATCH 会报告实际名称,而不会重复无效的超时重试。
在另一个 Shadow DOM 内挂载
mount(name, target) 接受选择器或 HTMLElement。当元素位于 Shadow DOM 内时,请直接传入元素:文档选择器不能跨越该边界。恢复和卸载使用同一个宿主;以元素挂载时,inspect() 返回 containerSelector: null。
// The shell has already registered and initialized the editor app.
const shell = document.querySelector('my-shell');
const slot = shell.shadowRoot.querySelector('[data-editor-slot]');
await runtime.mount('editor', slot);
// Later, when the shell releases this view:
await runtime.unmount('editor', { force: true });
实例拥有自己的资源
每个 new WuCore() 都有自己的 store、内存缓存、性能条目和预加载提示。destroy() 释放这些资源,同时保留其他实例的资源。通过 new WuCore({ cache }) 注入的缓存由调用方拥有,不会被自动清空。如需持久化,请创建具有明确存储方式和 namespace 的 WuCache,并决定何时清理它。
请在对应实例上通过 runtime.define(...) 注册生命周期。导入全局单例 wu 会在共享宿主上注册。独立实例在记录变更前应等待 runtime.timelineReady()。此模式用于在同一页面组合可信示例,不为任意代码建立安全边界。
参阅监督、恢复与 replay,了解 superviseApp、createReplaySession 和 scoped 方法 reportError、now、random。
destroy() 撤销 host 创建的 ports、将应用从分离窗口返回,并释放该实例的 drag and drop、shadow、health、replay 和 timeline 资源。应用 lease 撤销时,包括卸载或隔离,也会释放拖动 offers 和 targets。