Skip to content
目录

09 · 常见问题

架构与职责

Q:Qiankun 和 single-spa 各自做什么?

  • single-spa:应用注册、路由活跃规则、生命周期状态机、Parcel。
  • Qiankun:HTML 入口流式加载、JS 沙箱、资源转译(Blob/依赖)、fetch 增强、与上述生命周期对象拼装。

Q:为什么拆成 loader / sandbox / shared?

边界清晰、可测、可复用;门面包 qiankun 只做编排(见 02-Monorepo包职责与数据流.md)。


加载与入口

Q:子应用入口为什么规定只能有一个带 entry 的 script?

loadEntry 需要唯一确定「何时算加载完成」以及 latestSetProp 对应哪次导出;多入口会破坏完成语义,直接抛 QiankunError

Q:流式加载比一次性 innerHTML 好在哪?

更快见到 DOM;阻塞脚本/样式窗口内可 preload 后续资源;代价是 chunk 边界与 head 替换要实现稳健(参见 TagTransformStream FIXME)。

Q:<head> 为什么要改成 <qiankun-head>

避免子应用 head 与宿主 document.head 混用;配合 sandbox 对 document.head 的 patch,把操作重定向到容器子树。


沙箱

Q:Qiankun 3 沙箱大致怎么实现?

  • Membrane(Proxy):写副本、读合并、原生 API 重绑定防 Illegal invocation
  • Compartmentwith(this) + bind 到唯一 window.__compartment_globalThis__*
  • Patcher:动态插入、定时器、监听等在 unmount 时 free()

Q:沙箱能 100% 防逃逸吗?

不能。例如 SystemJS 间接 eval 需要把 System 写回真实 window(源码 FIXME + 白名单)。应强调 威胁模型:防日常全局污染为主,不等价于安全沙箱。

Q:latestSetProp 是什么?

Membrane 记录伪全局上最后一次成功 set 的属性名,Loader 用它取入口 bundle 挂上去的导出对象。


脚本执行与调试

Q:为什么要 fetch 脚本再包一层 Blob 执行?

浏览器原生 script[src] 无法在 Qiankun 的 with(伪全局) 中执行;必须先取源码再用 makeEvaluateFactory 包装。

Q:为什么执行时要把 Blob URL 换回真实 URL?

让运行时代码里依赖「当前脚本 URL」的逻辑更接近生产;同时 revokeObjectURL 释放内存(见 script.ts 注释)。


依赖与样式

Q:如何实现与主应用共享 React/Vue 等依赖?

构建侧产出 script[type=dependencymap] JSON;运行时 moduleResolver 按包名 + semver range + peerDeps 顺序匹配主应用已声明依赖,命中则复用 URL(可能经 ObjectURL 映射)。

Q:Qiankun 默认解决 CSS 冲突吗?

默认仍是全局样式表;隔离需工程手段(前缀、CSS Modules、微应用规范)。源码里 dynamicAppend 对 styled-components 等有特殊处理,且有「挂到真实 document」类 FIXME,说明样式仍是难点。


生命周期与边界情况

Q:beforeLoad 一定在子应用 DOM 插入前执行吗?

不一定。loadApp 内 FIXME 指出:loadEntry 异步与 appendChild/内联脚本同步执行交织,beforeLoad 可能需要 transformer 协调。

Q:同一容器多次 loadMicroApp 会怎样?

通过 XPath 记忆 loadApp 结果,避免重复执行入口;mount 前会等待同容器上前序实例 unmount,避免并发问题。

Q:同屏两个同名子应用要注意什么?

genInstanceId 递增;removeWebpackChunkCacheWhenAppHaveMultiInstance 去掉 data-webpack,否则 webpack runtime 可能认为脚本已加载而跳过执行。


性能

Q:有哪些内置优化?

Fetch LRU(50)+ clone、重试、throw;流式阻塞窗口 preload;依赖复用;同步脚本 fetchPriority;v3 弃用手动 prefetchApps 而强调 loader 侧自动 preload。


与 Umi

Q:Umi 的 qiankun 插件和本仓库是什么关系?

Umi 解决工程化(构建、publicPath、生命周期导出模板等);Qiankun 解决运行时加载与隔离。排查问题时先分清是 构建配置 还是 运行时 行为。


开放话题(可结合 Issue)

  • 子应用 保活/缓存(如 Issue #3057):框架保持agnostic,常由业务与具体 UI 框架方案承接。
  • v3 文档与 demo 类任务(如 #2683、#2684):以仓库最新状态为准。

返回总目录:readme.md

MIT License.