日期:2026-09-10 | 分支:
fix-subapp-loading(基于 masterb5a6721d)| 范围:仅 mky-vent-base 依据:docs/17 §8 实测("风量监测"新开标签页永久加载)、docs/16 基座审核 #6、docs/15。 原则:小步修改,不改业务逻辑与子应用通信协议;每处带[fix-subapp-loading]注释;可单项 revert。
用户典型路径(首页点"风量监测"→新开标签页)出现永久"正在加载":基座的两层加载遮罩(启动屏 + ventModal 挂载遮罩)的收起条件完全依赖"三维子应用就绪",而生产所部署的子应用构建存在绘制链停摆缺陷 → 遮罩永挂、整页不可用。本分支让基座在该场景下超时放行,并修复子应用卸载竞态。
| 文件 | 改动 |
|---|---|
src/utils/domUtils.ts |
resetMicroContentWH(domId, callBack, maxWaitMs = 60000):新增 maxWaitMs 参数(默认 60s,向后兼容)。原实现每秒无限轮询等待 #容器 出现首个子节点——微应用挂载失败时容器永远为空,遮罩永久转圈。现超时后强制执行 callBack()(隐藏遮罩、放行页面)并停止轮询(原实现还有轮询本身永不停止的小泄漏)。超时时输出 console.error 便于定位。 |
src/components/vent/micro/ventModal.vue(3D 容器) |
onMounted 中 mountMicroApp(...) 包 try,resetMicroContentWH(...) 移入 finally——若 mount 同步抛错,就绪等待仍然启动,遮罩不会因"抛错跳过收起逻辑"而永久卡死。 |
ventModal2D.vue / needAir.vue / ventDoc.vue |
同款 try/finally(分别对应 2D / 需风量 / 内业三个子应用容器)。 |
为什么是 60 秒:正常暖缓存挂载 ≤10s(实测 8.6~10.6s),冷缓存 40~60s;60s 仍未见容器内容基本可判定子应用挂载失败。超时放行后的表现:页面可见、三维区可能空白(用户可刷新重试),远好于无限转圈。参数可按现场调整(调大调小只改默认值)。
src/qiankun/index.ts 卸载竞态修复unmountMicroApps 原实现两个 bug:
multipleApp.filter(async (name) => { await …unmount() }) —— filter 的 async 回调使 await 不被任何方等待,卸载是"发射后不管";调用方 onBeforeUnmount(async () => { await unmountMicroApps(...) }) 以为在等,实际拿到的是 filter 的新数组(立即返回)。旧实例的卸载与新实例的挂载并发竞争容器。multipleApp.some 是函数引用(恒真),属笔误;且卸载后不清理 activeApps 注册表。修复:改为 for…of Object.keys(activeApps) 顺序 await 卸载,try/catch 单个失败不阻断其余,卸载成功后 delete activeApps[key];入参空数组直接返回。匹配语义保持原样(name.includes(key))。
| 场景 | 改前 | 改后 |
|---|---|---|
| 子应用挂载失败/停摆 | 整页"正在加载"永久转圈 | 最多 60s 后放行页面(附 console.error 定位信息) |
| 门户在两个子应用宿主路由间切换 | 旧实例卸载与新挂载竞态,实例泄漏/争抢 | 卸载完成后再挂载,注册表干净 |
| 子应用正常挂载 | 正常 | 正常(无行为变化) |
git revert 对应 commit 即可,两组改动相互独立。pnpm install && pnpm build 验证后再合并。VentModelWeb 侧的修复分支 perf-load-v5(Gogs 同服务 msx/VentModelWeb)解决三维子应用自身的切页重建/泄漏/绘制停摆;本分支不替代它,二者建议都合——本分支是基座侧的防御性兜底:即使未来子应用再出挂载问题,门户也不会整页永久卡死。