WU / 文档通用微前端
中文

核心、子系统与清单

选择可选入口,并在文件、宿主或应用模块中声明契约。

本页介绍 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。

一起完善 WU

发现了问题?有新的想法?

你的使用体验能让 WU 变得更好。告诉我们遇到的问题,或支持项目的持续开发。