好,这题如果你只说“基于 single-spa”是不够的,面试官更想听的是:它到底怎么做到子应用加载、隔离、通信的?
我给你一套可以直接“面试复述”的结构 👇
一、先一句话总结(开场用)
qiankun 是基于 single-spa 的微前端框架,通过路由劫持 + 资源加载 + 沙箱隔离 + 生命周期管理,实现多个子应用的独立运行与组合。
二、整体架构(核心流程)
qiankun 做的事情可以拆成 4 步:
注册子应用 → 监听路由 → 加载资源 → 挂载/卸载
三、核心原理拆解(重点)
1️⃣ 路由劫持(应用切换的入口)
👉 原理:
- 劫持浏览器 API:
window.history.pushState
window.history.replaceState
window.addEventListener('popstate')
👉 当 URL 变化:
匹配子应用 → 决定 mount / unmount
👉 举例:
registerMicroApps([
{
name: 'app1',
activeRule: '/app1',
}
])
访问 /app1:
👉 qiankun 会激活 app1
2️⃣ 资源加载(核心能力)
👉 子应用不是直接跑的,而是:
HTML → 解析 → JS/CSS 执行
qiankun 做了什么?
✔ HTML 入口解析
importHTML(url)
👉 做了三件事:
- 请求 HTML
- 提取
<script>/<link> - 转成可执行函数
✔ JS 执行控制
👉 不直接执行:
eval(script)
而是包装成:
function(window, self) { ... }
👉 为后面的“沙箱”做准备
3️⃣ 沙箱隔离(最核心)
👉 面试重点!!!
❓问题:多个子应用共用 window,会污染
window.name = 'app1'
👉 app2 也能读到 ❌
qiankun 解决方案:JS 沙箱
✔ Proxy 沙箱(主流)
const proxy = new Proxy(window, {
get(target, key) {},
set(target, key, value) {}
})
👉 子应用运行在:
(proxyWindow)
👉 实现效果:
proxy.name = 'app1'
只影响当前子应用 ✅
✔ 快照沙箱(兼容旧浏览器)
原理:
激活前:记录 window
卸载时:还原 window
👉 总结:
qiankun 通过 Proxy 模拟了一个“假的 window”
4️⃣ 样式隔离
👉 问题:
div { color: red }
👉 会污染全局 ❌
✔ 解决方案:
1. Shadow DOM(严格隔离)
element.attachShadow()
👉 样式完全隔离
2. Scoped CSS(常用)
👉 给子应用加前缀:
[data-qiankun-app] div {}
5️⃣ 生命周期管理
每个子应用必须导出:
export async function bootstrap() {}
export async function mount() {}
export async function unmount() {}
👉 执行流程:
bootstrap(初始化)
→ mount(渲染)
→ unmount(卸载)
👉 qiankun 会在路由切换时调用
四、通信机制(常问)
1️⃣ props 传参
registerMicroApps([
{
props: { user: 'xxx' }
}
])
2️⃣ 全局状态(推荐)
const { setGlobalState, onGlobalStateChange } = initGlobalState()
3️⃣ 自定义方式
- localStorage
- EventBus
五、总结(面试背诵版)
你可以直接这样说👇:
qiankun 的核心原理是通过劫持路由变化来感知子应用切换,然后通过 importHTML 动态加载子应用资源,并在执行时通过 Proxy 构建 JS 沙箱隔离全局变量,同时结合样式隔离避免 CSS 污染,最后通过生命周期函数控制子应用的挂载与卸载。
六、面试加分点(一定要说)
👉 如果你再补一句,基本稳了:
qiankun 本质上解决的是“多应用共存”的问题,重点在于隔离(JS + CSS)和调度(生命周期 + 路由)。
七、如果面试官继续深挖(我帮你准备好)
可能会问:
❓qiankun 有什么缺点?
👉 你可以答:
- 首屏加载慢(多应用)
- 子应用改造成本
- 样式隔离不绝对
- 调试复杂
如果你想,我可以下一步帮你补👇:
🔥 “qiankun 实战踩坑(面试最爱问)”
比如:
- 子应用 publicPath 问题
- 路由冲突
- JS 污染问题
- 样式穿透
这些是“用过”和“没用过”的分水岭 😄