Appearance
微前端架构:巨石应用的拆分之道
最后更新:2026-08-19
本主题要回答的问题
- 微前端解决什么问题?"一个大前端应用"为什么会失控?
- iframe → single-spa → qiankun → 模块联邦,每一代解决了什么?
- 微前端的技术难点到底在哪(为什么不能直接拆几个子应用拼起来)?
一、问题:前端巨石(Monolith)
一个大型后台(如内部管理系统)在单体 SPA 时代会遇到:
| 问题 | 表现 |
|---|---|
| 构建爆炸 | 一个 bundle 几 MB,构建 10 分钟 |
| 团队耦合 | 几十人改同一仓库,发布互相阻塞 |
| 技术栈锁死 | 团队 A 想用 Vue,全仓 React 不允许 |
| 发布粒度粗 | 改一行也要全量发布 |
微前端的思路:把大应用拆成多个可独立开发、独立部署、独立运行的小应用(子应用),再在主应用(基座)里组合呈现——对应后端微服务的"拆服务"。
二、四代方案演进
1. iframe:最朴素(2010s 常见)
每个子应用一个 <iframe>,天然隔离(样式/JS 全隔离)。致命伤:
| iframe 问题 | 表现 |
|---|---|
| 通信难 | 跨域 postMessage 繁琐 |
| 体验割裂 | 弹窗/路由/焦点/滚动全被 iframe 边界限制 |
| SEO 与首屏 | 多 iframe 加载慢、爬虫不友好 |
iframe 的教训:物理隔离换来的是集成能力的丢失。
2. single-spa(2018):注册表与生命周期
single-spa 定义了一套应用注册 + 生命周期契约(bootstrap/mount/unmount),基座根据路由加载对应子应用,子应用可以是任意框架。

突破:技术上做到"多框架共存、按路由切换"。遗留问题:JS 隔离(子应用之间变量污染)、样式隔离、公共依赖管理,single-spa 都不负责,要自己补。
3. qiankun(2019):开箱即用的隔离
qiankun 在 single-spa 之上补齐了工程化痛点:
| 能力 | 实现 |
|---|---|
| JS 沙箱 | 每个子应用运行在独立沙箱(Proxy 隔离 window) |
| 样式隔离 | 样式前缀 + 运行时样式补丁 |
| 通信 | 全局状态 + props 传递 |
| 按需加载 | 路由触发时动态拉取子应用 |
代价:沙箱有性能开销;子应用改造(生命周期、独立路由)有侵入性。
4. 模块联邦 Module Federation(Webpack 5,2020):构建期联邦
模块联邦换了一个思路:不在运行时隔离,而在构建期共享——每个应用把自己的某些模块"暴露"出去,其他应用构建时直接引用,运行时通过共享 chunk 按需加载。
| 对比项 | qiankun(运行时沙箱) | Module Federation(构建期联邦) |
|---|---|---|
| 隔离机制 | 运行时 JS 沙箱 | 模块级作用域天然隔离 |
| 共享依赖 | 配置 shared | 构建期自动去重共享 |
| 动态加载 | 路由级 | 模块级 |
| 侵入性 | 需要生命周期改造 | Webpack 配置即可 |
三、微前端的本质难点
无论哪代方案,微前端都要回答三个底层问题:
| 难点 | 问题本质 | 常见对策 |
|---|---|---|
| 应用隔离 | 子应用之间 JS/CSS 互相污染 | 沙箱 / 构建期模块作用域 |
| 应用通信 | 跨应用的全局状态怎么同步 | 事件总线 / 全局 store / props |
| 集成体验 | 路由、弹窗、样式在拼接后是否一致 | 统一基座样式规范 + 微应用协议 |
四、何时不该用微前端
| 场景 | 建议 |
|---|---|
| 应用 < 50 人团队、单仓库可控 | 不要用,单仓多包/Monorepo 更划算 |
| 团队边界清晰、发布频繁冲突 | 值得考虑 |
| 历史系统要渐进迁移(React 老应用 + Vue 新模块) | 微前端最典型的收益场景 |
一句话总结
微前端是对"应用级拆分"的工程实践:iframe 提供了隔离却丢了集成,single-spa 建立了生命周期契约,qiankun 补齐了隔离与通信,模块联邦则把问题从运行时挪到构建期——它的本质难点始终是"既要应用间的隔离,又要用户视角的统一",而这只有在应用足够大、团队足够多时才值得付出复杂度。