诊断与测试
按阶段调查故障,识别真实错误码,并在浏览器验证挂载、通信和清理。
版本、变更与要求见 Framework 3.2 与 CLI 1.0。
从失败阶段开始
console.log(wu.version);
console.log(wu.getStats());
console.log(wu.getAppInfo('catalog'));
console.log(wu.getSandboxInfo('catalog'));
console.table(wu.getManifestDiagnostics());
console.log(wu.inspect({ events: 20 }));
注册、加载、挂载、更新和拆卸的故障原因不同。保存应用名称、URL、解析后的 entry、选择器、实际模式和原始错误。空白截图无法区分加载失败与挂载根节点随后被 shell renderer 删除。
症状表
| 现象 | 具体检查 | 解决方法 |
|---|---|---|
| 应用未注册 | init 已完成;shell/manifest/define 名称一致 |
等待 init 并修正身份 |
WU_MANIFEST_LOAD_FAILED |
状态、CORS、/wu.json 响应 |
从注册的 base 提供真实 JSON |
WU_MANIFEST_NAME_MISMATCH |
下载的名称与配置名称 | 发布该应用的 manifest |
WU_MANIFEST_INVALID |
字段、JSON、entry 和权限 | 修正 manifest;不要用默认值隐藏故障 |
WU_PERMISSION_REQUIRED |
必需请求未被覆盖 | 明确调整请求或宿主 grant |
WU_CAPABILITY_DENIED |
scoped 操作与有效资源 | 使用获授权的路径/通道 |
emit 返回 false |
身份、grants 与命名空间 | 检查回调/scoped facade,不要假定会抛异常 |
WU_APP_SCOPE_REVOKED |
unmount 后仍保留 API | 取消工作,挂载时获取新上下文 |
Container not found |
选择器从 document 解析 |
mount 前已存在的 light DOM slot |
| Failed dynamically imported module | Entry、chunks、MIME 和 CORS | 使 manifest 与真实 build 一致 |
| 应用空白且无错误 | 宿主协调了 slot 子节点 | 将挂载节点与 loading 指示器分开 |
| 无效 React hook | 两份 React 或不匹配的 ReactDOM | 向 adapter 注入一致的运行时 |
| Vue 状态不刷新 | 创建 ref 时 Vue 运行时不可用 | 安装插件/命名空间并连接订阅 |
| RPC 报错,没有 handler | 提供方尚未挂载 | 安排生命周期顺序或使用等待状态 |
解决身份与启动冲突
WU_APP_EXISTS 表示注册试图占用已有名称。查询 wu.getAppInfo(name) 并检查哪个 bootstrap 注册了该身份。已有应用配置保留宿主 grants;创建其他 wrapper 不能替换它们。
要分别验证配置和挂载,请显式启动:
import { wu } from 'wu-framework';
await wu.init({ apps: [{ name: 'catalog', url: '/apps/catalog' }] });
console.log(wu.getAppInfo('catalog'));
try {
await wu.mount('catalog', '#catalog-slot');
} catch (error) {
console.error('No se pudo montar catalog', error);
console.log(wu.getSandboxInfo('catalog'));
throw error;
}
whenReady() 等待已经开始的启动,不会启动运行时。在父子 effects 的集成中,应先协调初始化,再挂载。wu.app() 在挂载时延迟注册,并在同一 wrapper 的并发 mounts 间共享注册;其引用与清理契约见生命周期。
不要通过 WuApp.destroy() 再创建同名应用来更新配置:该方法不会清理全部关联注册。常规转换时卸载 renderer;shell 需要替换整体组合时,重新初始化整个 core。
挂载恢复
error boundary 提供网络、脚本加载、挂载、超时及通用回退 handlers。core 解释重试请求,清理后重新执行挂载;它会保留定义,因为已缓存的 ESM 模块不会因再次 import 而重新求值。
core 在重试路径中识别 retry 和 retry-with-longer-timeout。handler 返回的 action 名称本身不会改变 URL 或超时:应配置并验证 core 实际采用的行为。分类也使用错误名称和消息片段;保留完整错误,以便诊断。
默认 handlers 最后注册的通用函数接受所有错误。register() 添加到末尾,因此后来加入的 handler 可能排在通用 handler 之后,无法按预期执行。在依赖扩展机制实现业务恢复前,先检查顺序。
仓库测试
测试套件区分运行时单元、子系统集成与安全边界。选择与你修改的契约对应的层级:
npm run test:unit
npm run test:integration
npm run test:security
npm run test:coverage
test:package 编译并执行发行包契约。test:mcp 测试独立 MCP 包。导入 src 的套件不能单独证明 dist 包提供了正确 exports/chunks。
注册回归测试应运行 WuCore 及其真实验证。可以替换 manifest 下载和 renderer 来控制场景,但完整 mock core 无法验证身份、grants 或 cleanup。测试并发时,延迟 manifest 响应,在解析它之前发起两次挂载;同时检查唯一注册和挂载引用。
发布运行时变更前,对将要发行的 build 运行相关套件和包测试。
浏览器验收
有效的多技术栈系统测试应至少挂载两个 renderers,修改共享状态并验证两者都展示该值。随后卸载其中一个,再次发射事件并确认其回调不再执行。最后重新挂载,验证没有重复监听器。
CSS 故障应比较 styleMode、ShadowRoot 样式表和所有权。HMR 或生产问题应同时测试 Vite 服务器和编译资源。SSR 应确认首个响应已有内容,且水合保留该 DOM 而不重复生成。
实现参考
检查:src/core/wu-core.js;恢复:src/core/wu-core.js;error boundary:src/core/wu-error-boundary.js 和 src/core/wu-error-boundary.js;wrapper:src/core/wu-app.js;重复检测:src/core/wu-core.js;脚本:package.json。测试:tests/unit/final-hardening-regressions.test.js、tests/unit/shared-container-navigation.test.js、tests/unit/props-channel.test.js、tests/integration/multi-app-isolation.test.js。
升级到 4.0 时,请比较 error.code 而非消息文本:core 错误使用 WU_APP_NOT_REGISTERED、WU_CONTAINER_NOT_FOUND、WU_APP_NOT_DEFINED、WU_DEFINE_TIMEOUT 和 WU_CONTAINER_OCCUPIED 等代码。合同使用 WU_CAPABILITY_*。错误边界将不可恢复故障直接交给 fallback,不再通过查找消息中的词决定重试。