Skip to content
目录

08 · 关键设计决策、依据与技术债

下列条目均可在仓库内通过注释或 FIXME/TODO 溯源。

1. 基于 single-spa 做应用调度,而不是自研路由内核

现象registerApplicationmountRootParcelParcelConfigObject 贯穿 registerMicroApps / loadMicroApp

原因:微前端「何时挂载/卸载」与路由、URL、应用状态机强相关;single-spa 提供了成熟语义与生态,Qiankun 专注 加载与隔离

2. HTML 入口 + 流式 writable-dom

原因:降低 TTFB 到首屏可解析内容的间隔;阻塞资源窗口内做 preload。

代价:字符串级 <head> 替换对 chunk 切分敏感(TagTransformStream FIXME)。

3. Head 虚拟化为自定义标签

原因:隔离子应用 head 元数据,配合 document patch 把 document.head 映射到容器子树。

依据qiankunHeadTagName 常量(packages/sandbox/src/consts.ts)与 loader 替换表一致。

4. 沙箱用 Proxy 膜 + with(this),而非 iframe

收益:DOM 集成简单、实例成本相对低、与主应用共享同一渲染管道。

代价:无法像 iframe 那样进程级隔离;存在 白名单写回真实 window(SystemJS)、间接 eval 等逃逸面;依赖团队对子应用代码约束。

5. 入口脚本必须唯一且带 entry

原因:明确 loadEntry Promise 的 settle 条件,并与 latestSetProp 配对。

依据:Loader 抛错与 AGENTS.md ANTI-PATTERN。

6. Blob 执行后还原 script.src

原因:在保持沙箱执行的前提下,让 document.currentScript、错误栈中的 URL 等更接近原生。

依据script.ts 内注释与 revokeObjectURL 配套。

7. preload as=fetch 修正

原因:手动 fetch 执行脚本时,与 as=script 的 preload 缓存不对齐。

依据link.ts 注释中的 StackOverflow / MDN 链接。

8. 冻结属性直出(issue #2015)

Membrane get trap 对 frozen 属性直接返回值、跳过重绑定,注释指向 https://github.com/umijs/qiankun/issues/2015,避免破坏不可变全局对象的语义。


技术债与 FIXME/TODO 汇总(源码检索)

位置摘要
loadApp.tsbeforeLoadloadEntry 异步插入/同步脚本执行顺序难以严格协调
loader/index.ts非沙箱模式 resolve 占位、body 替换未做
TagTransformStream.ts非标准 HTML chunk、缺 <head> 时需补全策略
membrane/index.tsSystemJS 间接 eval → 白名单逃逸
forStandardSandbox.ts不应依赖全局 __currentLockingSandbox__getCurrentRunningApp 不可靠(PR #2415)
dynamicAppend/common.tsdetached 容器需挂回真实 document 才能触发样式/脚本行为
sandbox/index.ts / types.tssnapshot 沙箱、GC 未实现
historyListener.tsumi unmount 相关 FIXME
assets-transpilers/index.tsscript 文本场景待处理

简明表述建议:Qiankun 3 明确把部分问题标为 FIXME,说明维护者承认 时序、逃逸面、保活/快照 等仍是开放题;社区关于「子应用保活」的讨论可参考 Issue #3057 等,与框架无关的保活方案(不卸载 DOM、由框架层缓存 vnode 等)需自行权衡。

下一节

09-常见问题.md

MIT License.