跳转到主要内容
Zhou.

搜索文章

输入关键词搜索文章标题、标签和正文。
Menu
← 返回项目
前端核心开发 / 架构方案推动2021–2025

企业平台微前端架构改造

从单体前端逐步演进到业务子应用自治的微前端架构实践,重点解决团队协作、发布耦合与平台公共能力复用问题。

  • Vue
  • qiankun
  • Micro Frontend
  • Vite
  • Webpack

背景

随着平台业务持续增长,不同团队开始在同一个前端项目中维护越来越多的业务模块。

早期这种模式足够简单,但随着模块和团队数量增加,几个问题开始逐渐出现:

  • 不同业务之间的代码边界越来越模糊
  • 一个模块发布可能影响其他业务
  • 公共依赖持续增长,构建体积不断增加
  • 外部系统接入时缺少独立开发和发布能力

这时问题已经不再只是“项目越来越大”,而是原有前端架构开始限制团队之间的协作方式。

核心问题

我把问题主要拆成三个维度。

1. 发布耦合

多个业务模块共享同一个发布流程。

即使一次修改只涉及一个局部业务,也需要重新构建和发布整个应用。

2. 团队边界不清晰

不同团队长期修改同一个代码仓库后,公共模块、业务模块和平台能力之间逐渐产生大量隐式依赖。

3. 平台能力与业务能力混合

权限、菜单、字典、审批等平台能力,与具体业务页面之间缺少明确边界。

随着业务增加,新模块的接入成本也在持续增长。

为什么选择微前端

我们的目标并不是“使用 qiankun”。

真正需要解决的是:

如何让不同业务模块拥有独立的开发和发布能力,同时仍然保持平台体验的一致性。

最终采用:

主应用
├── 权限
├── 菜单
├── 字典
├── 公共能力
└── 应用生命周期

业务子应用
├── 独立业务代码
├── 独立开发
├── 独立构建
└── 独立发布

主应用继续作为统一的平台入口,而业务模块逐步拆分为可以自治的子应用。

架构设计

主应用主要负责平台级能力:

  • 用户和权限上下文
  • 菜单与动态路由
  • 公共字典
  • 微前端生命周期管理
  • 跨应用公共能力

业务子应用则只关注自己的业务领域。

这种划分的核心不是物理拆仓,而是建立:

Platform concerns

Main Application

Business concerns

Micro Applications

从 registerMicroApps 到 loadMicroApp

早期使用固定注册方式管理子应用。

随着应用数量和业务菜单不断变化,这种模式逐渐不能很好地匹配动态权限菜单。

后续将加载逻辑调整为基于组件封装的 loadMicroApp 模式,使主应用能够根据后端返回的菜单动态决定需要加载的业务应用。

这让:

权限菜单

动态路由

微应用生命周期

能够进入同一套平台控制流程。

一个实际难点:子应用加载性能

架构拆分之后,一个新的问题出现了:

应用独立以后,并不意味着加载一定更快。

部分子应用仍然包含较大的 UI 组件库和公共依赖,如果不继续优化,首次进入业务模块仍然需要下载大量资源。

因此后续继续从几个方向优化:

  • 页面级异步加载
  • 合理拆分稳定依赖和高频业务代码
  • 减少不必要的公共依赖
  • 调整资源加载时机
  • 分析子应用真正的首屏关键资源

这里让我更加明确:

架构拆分解决的是系统边界问题,性能优化仍然需要单独衡量。

Trade-offs

微前端并不是免费的。

它同时带来了新的复杂度:

  • 主子应用通信需要明确协议
  • 不同技术栈之间可能存在样式和运行时差异
  • 本地联调链路更加复杂
  • 公共依赖到底共享还是隔离需要权衡
  • 子应用生命周期需要平台统一管理

因此我并不认为:

大型项目
=
一定需要微前端

更准确的判断应该是:

团队和业务边界
+
独立发布需求
+
平台统一能力
+
长期维护成本

是否已经超过单体应用继续演进的收益。

最终收益

这次改造最大的价值并不是引入了一个新的框架。

真正的变化是:

业务模块可以独立演进

不同团队能够更加独立地开发和发布自己的业务模块,降低发布之间的相互影响。

平台职责更加清晰

权限、菜单、字典以及公共能力逐步收敛到主应用统一管理。

后续平台能力更容易复用

建立清晰的主子应用边界以后,审批等平台能力也可以继续抽象成统一能力,而不需要每个业务重新接入。

我从这个项目中学到什么

这次实践让我对“架构”有了更明确的理解:

架构的价值不是把系统变得更复杂,而是把已经存在的复杂度放到更合理的位置。

微前端只是最终选择的技术手段。

真正需要设计的是:

团队边界
业务边界
运行时边界
发布边界

当这些边界足够清晰以后,具体框架反而只是实现的一部分。