返回笔记首页

微前端改造与Monorepo架构 - 简历撰写指南

主题配置

一、微前端项目改造

版本1:技术主导型(适合技术岗)

markdown
【核心业务系统微前端拆分改造】2025.03 - 2025.10

项目背景:
公司主站是个单体应用,6个业务线都在里面。每次改个小功能都要构建15分钟,测试回归要2天,上线还得半夜发布,怕影响其他模块。几个团队在一个仓库里协作,经常代码冲突,改来改去最后也不知道谁改的。

我负责什么:
带着3个人把这个单体应用拆成了微前端架构。我主要做技术方案和核心模块的改造。

具体做了啥:
1. 技术选型和架构设计
   对比了qiankun、Wujie、Module Federation三个方案。最后选了qiankun,主要是因为社区活跃,遇到问题好解决,而且我们用Vue,qiankun对Vue支持比较好。

   拆分策略是按业务线拆:用户中心、订单系统、商品管理、营销活动各自独立。主应用就保留导航、权限、布局这些公共的东西。

2. 主应用架构实现
   主应用用Vue3重写,做了统一的Layout、菜单配置、权限控制。用initGlobalState做全局状态管理,把用户信息、权限数据这些共享给子应用。

   路由这块比较麻烦,主应用是hash模式,子应用有的是history模式。最后统一改成了history,nginx配了个fallback,解决了刷新404的问题。

3. 子应用改造
   最麻烦的是订单系统,代码耦合特别严重。我花了一周时间梳理依赖关系,把它从主应用里抽出来。

   改造步骤:先在main.js导出生命周期函数(bootstrap、mount、unmount),然后改webpack配置(library、libraryTarget、publicPath),最后处理全局变量和事件监听的清理。

   有个坑是publicPath问题,打包后图片、字体这些静态资源都404。后来加了个public-path.js,动态设置__webpack_public_path__,才解决。

4. 关键问题处理
   - JS沙箱:开了Proxy沙箱,但发现有的老代码直接操作window,还是会污染。后来在子应用unmount时手动清理全局变量。

   - 样式隔离:用了experimentalStyleIsolation,但antd的Modal会挂到body上,在shadow DOM里找不到样式。改了getContainer,让它挂到子应用容器里。

   - 全局状态:一开始用的props传递,后来发现不够用。封装了个EventBus,支持跨应用通信。重要的状态还是走initGlobalState。

   - 性能优化:配了prefetch预加载,常用的子应用提前加载资源。首屏从8秒降到3秒。

5. 灰度发布
   不敢一次性全上,先灰度了10%的用户。用的是nginx根据cookie分流,灰度用户走新架构,其他用户还是老的。观察了一周没问题,才全量上线。

遇到的坑:
- 子应用之间通信一开始没设计好,后来加了个EventBus才解决
- 构建速度还是慢,后来用了webpack5的持久化缓存,快了一半
- 有个子应用用了jQuery插件,各种全局变量,清理了好几天

最终效果:
- 构建时间:从15分钟降到单个应用3分钟
- 发布频率:从月发布变成周发布,每个业务线独立发版
- 协作效率:代码冲突减少90%,各团队独立开发互不影响
- 故障影响:某个子应用挂了不影响其他模块,故障面缩小80%
- 上线风险:不用半夜发布了,白天也能发,回滚也快

技术栈:qiankun、Vue3、React、Vite、Webpack5、Nginx

版本2:业务导向型

markdown
【主站架构升级 - 单体应用拆分改造】2025.03 - 2025.10

为什么要做这个事:
我们主站越来越庞大,6个业务团队都在一个项目里开发,经常互相影响。最痛苦的是发布,每次要半夜操作,而且经常因为一个小功能上线,导致其他功能出问题。老板要求提升发布效率,降低故障率。

我的角色:
负责整个改造项目的技术方案和落地实施,带了3个前端。

做了什么事:
第一步,把大项目按业务拆成了5个小项目:
- 用户中心(登录注册、个人信息)
- 订单系统(下单、支付、物流)
- 商品管理(上架、库存)
- 营销活动(优惠券、秒杀)
- 主应用(导航、布局、权限)

每个小项目可以独立开发、独立上线。

第二步,解决拆分后的协作问题:
- 统一登录:主应用登录后,把token通过props传给各个子系统
- 统一导航:主应用做菜单,根据权限动态显示
- 数据共享:用户信息、购物车数量这些公共数据,通过全局状态管理

第三步,保证用户体验:
- 切换子系统要快:配了预加载,常用的提前加载
- 不能有白屏:做了loading动画和骨架屏
- 路由要对:配置了路由映射,保证刷新不会404

遇到的难题:
1. 订单系统依赖特别复杂,花了一周才理清楚,改造了两周
2. 老代码质量参差不齐,有很多全局变量,改起来特别麻烦
3. 测试资源有限,只能分批上线,先灰度10%用户验证

业务价值:
- 发布效率:原来一个月发一次版本,现在一周一次,快速响应业务需求
- 故障率降低:原来每月平均2次故障,现在3个月才1次
- 团队效率:6个团队可以并行开发,不用等其他团队
- 上线时间:不用半夜操作了,工作时间就能发布
- 新人上手:以前要2周熟悉所有代码,现在只需要了解自己负责的模块,3天就能开始干活

技术方面:
用的是qiankun微前端框架,Vue3重构的主应用,Webpack5打包。

个人收获:
这个项目让我对大型项目的架构设计有了更深的理解,特别是如何平衡技术方案和业务需求。也锻炼了带团队的能力,遇到问题怎么拆解、分工、推进。

版本3:实战角度

markdown
【解决主站构建慢、发布难的架构改造】2025.03 - 2025.10

遇到的问题:
主站单体应用,开发的时候本地启动要5分钟,热更新也慢。打包要15分钟,每次改个小功能都要等很久。更难受的是发布,6个业务团队都在一个仓库,经常代码冲突,上线得半夜操作,怕影响用户。有一次因为一个小改动导致整个站点崩溃,老板特别不满。

解决思路:
把单体应用拆成微前端架构。每个业务线独立一个项目,可以独立开发、独立上线。主应用负责整体框架和公共功能。

具体实施:
1. 技术方案
   调研了qiankun、Wujie、Module Federation。选了qiankun,理由是:
   - 阿里开源的,用的人多,遇到问题容易找答案
   - 文档比较全,有现成的最佳实践
   - 对Vue支持好,我们技术栈是Vue

2. 主应用开发(
   Vue3重构,做了这些事:
   - 统一Layout和导航
   - 权限控制(菜单权限、按钮权限)
   - 全局状态管理(用户信息、token)
   - 子应用注册和生命周期管理

3. 子应用改造(8周)
   最耗时的环节。订单系统改了2周,因为耦合太严重。改造步骤:
   - 导出生命周期函数(bootstrap、mount、unmount)
   - 改webpack配置(library、libraryTarget、publicPath)
   - 清理全局变量和事件监听
   - 处理静态资源路径

4. 踩过的坑:
   - publicPath问题:打包后静态资源404,加了public-path.js解决
   - 样式冲突:antd的Modal弹窗样式丢失,改了getContainer
   - 路由问题:刷新404,nginx配了fallback
   - 全局变量污染:有些老代码直接操作window,unmount时要清理

5. 灰度上线
   不敢一次性全上,分三批:
   - 第一批:内部员工试用,发现了几个小问题,赶紧修复
   - 第二批:10%用户灰度,观察一周,监控指标正常
   - 第三批:全量上线,逐步切换流量

改造成果:
- 开发效率:本地启动从5分钟降到30秒,热更新秒级响应
- 构建速度:单个应用3分钟,之前要15分钟
- 发布频率:从月发布到周发布,业务迭代快了很多
- 代码冲突:几乎没有了,各团队独立仓库
- 故障影响:某个模块出问题不影响其他,故障率降低80%
- 上线时间:不用半夜操作,白天也能发

技术栈:qiankun、Vue3、Webpack5、Nginx

个人成长:
这个项目最大的收获是学会了权衡。技术方案要考虑团队能力、时间成本、风险控制。不能追求完美,要找到当前最合适的方案。还有就是沟通能力,要说服老板投入资源,要协调6个团队配合改造。

二、Monorepo多包架构升级

版本1:技术主导型

markdown
【组件库Monorepo架构升级改造】2024.01 - 2024.06

项目背景:
公司有个组件库,最初是单仓库结构,所有组件、工具函数、类型定义都在一个包里。随着业务扩展,组件越来越多,现在有80+个组件。问题很明显:
- 发布慢:改一个Button组件,整个包都要重新发布,业务系统要更新整个组件库
- 版本混乱:不同组件有不同的迭代速度,但版本号只有一个
- 构建慢:每次构建要打包所有组件,要10分钟

我负责把它改造成Monorepo架构,实现按需发布、独立版本管理。

技术选型:
对比了Lerna、Nx、pnpm workspace、Turborepo。最后选了pnpm workspace + Turborepo:
- pnpm workspace:包管理,依赖提升,节省磁盘空间
- Turborepo:任务编排,增量构建,缓存机制
- Changesets:版本管理,自动生成changelog

架构设计:
component-library/
├── packages/
│   ├── button/           # 按钮组件
│   ├── form/             # 表单组件
│   ├── table/            # 表格组件
│   ├── utils/            # 工具函数
│   ├── types/            # 类型定义
│   └── icons/            # 图标
├── apps/
│   ├── docs/             # 文档站点
│   └── playground/       # 组件演示
├── pnpm-workspace.yaml
├── turbo.json
└── package.json
markdown

实施步骤:
1. 迁移准备
   - 梳理组件依赖关系:Button依赖Icon,Form依赖Button
   - 设计包拆分策略:按功能模块拆,相关的组件放一起
   - 制定命名规范:@mylib/button、@mylib/form

2. 仓库结构调整
   - 创建packages目录,把每个组件拆成独立包
   - 配置pnpm workspace,设置依赖提升规则
   - 每个包独立的package.json、tsconfig.json、README.md

3. 构建系统改造
   - 配置Turborepo的pipeline,定义构建、测试、lint的依赖关系
   - 设置缓存策略:本地缓存 + 远程缓存(Vercel)
   - 实现增量构建:只构建变更的包

4. 版本管理
   - 引入Changesets,开发时写changeset文件
   - 配置CI/CD,自动生成changelog和版本号
   - 设置发布流程:preview -> release

5. 开发体验优化
   - 配置VSCode workspace,多包联调
   - 写脚本工具:快速创建新包、批量更新依赖
   - 完善文档:Monorepo开发指南、发布流程

遇到的坑:
1. 循环依赖:Button引用了Utils,Utils又引用了Button的类型定义
   解决办法:抽出一个独立的types包

2. peer dependencies:组件库依赖Vue,但不能打包进去
   解决办法:设置peerDependencies,让使用方提供

3. 构建顺序:Form依赖Button,要先构建Button
   解决办法:Turborepo的dependsOn配置

4. 发布权限:80个包要单独设置npm权限
   解决办法:写了个脚本批量设置

改造成果:
- 发布效率:改一个组件,只发布这一个包,不影响其他
- 构建速度:增量构建+缓存,从10分钟降到2分钟(初次)、30秒(缓存命中)
- 版本管理:每个包独立版本,可以单独升级
- 按需引入:业务系统按需安装需要的包,包体积减少60%
- 开发体验:本地启动快,热更新快,多包联调方便

技术栈:pnpm、Turborepo、Changesets、Vue3、Vite

经验总结:
Monorepo不是银弹,要根据项目规模选择。我们组件库有80+个包,适合Monorepo。如果只有几个包,单仓库反而更简单。

关键是构建工具的选择,Turborepo的增量构建和缓存真的很强,大幅提升了构建速度。

版本2:业务导向型

markdown
【组件库架构升级 - 提升发布效率和使用体验】2024.01 - 2024.06

为什么要做:
公司组件库维护了3年,已经有80多个组件。所有组件都在一个npm包里,导致几个问题:
- 业务系统只用了5个组件,但要安装整个组件库,包体积很大
- 改个小组件,整个组件库都要重新发布,业务系统要全量更新
- 不同组件的需求优先级不一样,但版本号只有一个,发布很纠结

老板要求优化,目标是提升发布效率、降低业务系统的包体积。

解决方案:
把一个大包拆成多个小包,每个组件单独发布。业务系统按需安装需要的组件。

具体实施:
1. 包拆分策略
   - 基础组件:Button、Input、Select 等,单独发包
   - 复杂组件:Table、Form、Upload 等,单独发包
   - 工具函数:独立一个包
   - 图标:独立一个包

2. 技术架构
   - 用pnpm管理多个包,共享依赖节省空间
   - 用Turborepo管理构建任务,增量构建节省时间
   - 用Changesets管理版本,自动发布

3. 开发流程
   - 开发新功能:写代码 -> 写changeset -> 提PR
   - 发布流程:合并PR -> CI自动构建 -> 自动发布到npm

4. 迁移过程
   - 第一阶段:新组件直接按新架构开发
   - 第二阶段:老组件逐步迁移(按使用频率优先级)
   - 第三阶段:废弃老包,全部切换到新架构

业务价值:
- 发布频率:从双周发布变成每日多次发布,快速响应业务需求
- 包体积:业务系统按需安装,包体积减少60%,页面加载快了
- 使用体验:不用等整个组件库发版,需要哪个组件就装哪个
- 维护成本:各个组件独立迭代,互不影响,维护更清晰

数据对比:
- 发布时间:从30分钟(构建+测试+发布)降到5分钟
- 构建时间:增量构建,只构建变更的包,平均2分钟
- 包体积:业务系统从3MB降到1.2MB
- 更新频率:组件库发布从月2次到周5次

技术要点:
用了pnpm workspace管理多包,Turborepo做增量构建,Changesets管理版本。

团队反馈:
开发说开发体验好了很多,不用等整个组件库构建完。业务团队说按需安装很方便,包也小了。

版本3:实战型(适合实际面试)

markdown
【组件库Monorepo改造 - 从单包到多包架构】2024.01 - 2024.06

背景:
组件库3年积累了80+组件,都在一个npm包里。每次发布要重新打包所有组件,业务系统要全量更新。改一个小组件也得等整个组件库发版,效率很低。

目标:
拆成多个独立的包,每个组件独立发布、独立版本。业务系统按需安装。

选型过程:
调研了Lerna、Nx、pnpm、Turborepo。对比下来:
- Lerna:老牌工具,但性能一般
- Nx:功能强大,但学习成本高
- pnpm workspace:包管理快,依赖提升好
- Turborepo:增量构建强,缓存机制好

最终选择:pnpm + Turborepo + Changesets
- pnpm管包
- Turborepo管构建
- Changesets管版本

实施过程:

第一步,梳理依赖关系(1周)
画了个依赖图,发现Button被20+个组件依赖,Form依赖Button和Input。要先拆基础组件,再拆复杂组件。

第二步,配置Monorepo(1周)
- 创建pnpm-workspace.yaml,配置packages目录
- 每个组件独立package.json,设置name、version、dependencies
- 配置turbo.json,定义build、test、lint任务的依赖关系

第三步,迁移组件(4周)
不敢一次性全迁移,分批进行:
- 第一批:工具函数、类型定义(无依赖)
- 第二批:基础组件(Button、Icon、Input)
- 第三批:复杂组件(Form、Table、Upload)
- 第四批:业务组件

每迁移一批,都要测试,确保没问题才继续。

第四步,优化构建(2周)
- 配置Turborepo的缓存:本地缓存 + 云端缓存
- 设置增量构建:只构建变更的包
- 并行构建:多个包同时构建

第五步,版本管理(1周)
- 引入Changesets:开发时写变更说明
- 配置CI/CD:自动生成版本号、changelog
- 设置发布流程:测试通过自动发布

遇到的问题:

问题1:循环依赖
Button引用了Utils的某个函数,Utils又引用了Button的类型。导致构建失败。
解决:抽出独立的types包,专门放类型定义。

问题2:构建顺序
Form依赖Button,要先构建Button才能构建Form。手动控制太麻烦。
解决:Turborepo的dependsOn自动处理依赖顺序。

问题3:发布权限
80个包要分别设置npm发布权限,太繁琐。
解决:写了个脚本批量设置。

问题4:业务系统迁移
30+个业务系统在用老的组件库,怎么平滑迁移?
解决:老包保留,标记为deprecated。提供迁移脚本,批量替换import路径。

最终效果:
- 构建时间:10分钟降到2分钟(初次),30秒(缓存命中)
- 发布效率:改一个组件,1分钟发布。之前要30分钟
- 包体积:业务系统按需安装,从3MB降到1.2MB
- 开发体验:多包联调方便,热更新快
- 版本管理:每个包独立版本,灵活发布

技术栈:
pnpm、Turborepo、Changesets、Vue3、Vite

经验教训:
1. Monorepo不是越细越好,要平衡粒度。我们按功能模块拆,太细了反而难管理
2. 缓存很重要,Turborepo的远程缓存能节省80%构建时间
3. 迁移要分批,不能一次性全改,风险太大
4. 文档很重要,团队成员要知道怎么开发、怎么发布

三、面试应答技巧

面试官:你们为什么选择微前端?

"主要是被逼的。我们主站代码太多了,30万行,6个团队在一个仓库里开发,经常冲突。最痛苦的是发布,每次都要半夜操作,还经常出问题。

老板要求必须提升发布效率。我们调研了几个方案,重构成本太高,拆成多个独立项目又要解决通信问题。最后觉得微前端比较合适,能独立开发独立上线,风险可控。"

面试官:微前端改造遇到过什么困难?

应该这样说(具体)

"困难挺多的。

第一个是技术方案,我对比了qiankun、Wujie、Module Federation,每个都试了一遍。qiankun上手快但有些坑,Wujie隔离好但性能稍差,Module Federation强大但学习成本高。最后选了qiankun,主要是因为用的人多,遇到问题能找到解决办法。

第二个是改造成本,订单系统依赖特别复杂,我花了一周梳理,发现它和主应用有100多处耦合。最后硬着头皮一点点改,改了两周才把它抽出来。

第三个是团队协调,6个团队都要配合改造,有的团队支持,有的团队觉得麻烦。我只能一个个去沟通,解释改造的好处,最后才推动下去。

还有就是上线风险,不敢一次性全切,先灰度了10%用户,观察了一周才全量。中间发现了几个小问题,好在及时修复了。"

面试官:Monorepo带来了什么收益?

应该这样说(有数据)

"最直观的是构建快了。以前要10分钟,现在增量构建只要2分钟,缓存命中的话30秒就完事了。

发布也灵活多了。以前改个Button,整个组件库都要重新发,业务系统也要全量更新。现在只发Button这一个包,其他不受影响。

还有就是包体积小了。业务系统以前要装整个组件库3MB,现在按需装,平均1.2MB,减少了60%。页面加载快了不少。

对开发来说,多包联调方便了。以前要npm link来link去,现在直接引用本地包,改了立马生效。

不过也有代价,配置复杂了,新人上手成本高了点。但我觉得值得,长期收益大于短期成本。"


四、关键话术模板

项目背景描述

plain
我们公司主站是个[X年]的老项目,代码量[X万]行,[X个]团队在一起开发。
主要问题是:
1. 构建慢:每次要[X分钟]
2. 发布难:[具体困难]
3. 协作乱:[具体问题]

老板要求[具体目标],所以启动了这个改造项目。

技术选型描述

plain
对比了[方案A]、[方案B]、[方案C]。

[方案A]的优点是[X],但[缺点]。
[方案B]的优点是[Y],但[缺点]。

最后选了[方案C],主要考虑:
1. [理由1]
2. [理由2]
3. [理由3]

当然也有trade-off,[缺点],但我们能接受。

实施过程描述

plain
整个改造分了[X]个阶段:

第一阶段([X周]):[做什么]
具体步骤是[1、2、3]

第二阶段([X周]):[做什么]
遇到的坑是[具体问题],解决办法是[具体方案]

第三阶段([X周]):[做什么]
...

整个过程花了[X个月],比预期[多/少]了[X周],主要是因为[原因]。

成果数据描述

plain
改造完成后,主要指标:

开发侧:
- 构建时间:[原来X] → [现在Y](提升Z%)
- 启动时间:[原来X] → [现在Y]
- 代码冲突:[原来X次/月] → [现在Y次/月]

业务侧:
- 发布频率:[原来X] → [现在Y]
- 上线时间:[原来X] → [现在Y]
- 故障率:[原来X] → [现在Y]

用户侧:
- 加载速度:[原来X秒] → [现在Y秒]
- 包体积:[原来X] → [现在Y](减少Z%)

个人成长描述

plain
这个项目让我最大的收获是[X]。

技术上,我学会了[具体技术],特别是[某个难点]的处理。

非技术上,我锻炼了[能力]。比如[具体例子]。

如果再做一次,我会[改进点],因为[原因]。

五、面试常见问题及回答

Q1: 为什么不用Module Federation?

回答

"我们确实考虑过Module Federation。它的优势是Webpack5原生支持,共享依赖做得很好,构建时优化也强。

但有几个问题:

  1. 学习成本高,团队之前没用过,上手慢
  2. 需要Webpack5,我们有几个老项目还在用Webpack4,升级成本大
  3. 粒度是模块级的,我们需求是应用级的,Module Federation有点过度了

所以最后选了qiankun,社区大,文档全,遇到问题好解决。"

Q2: Monorepo会不会越来越慢?

回答

"这个担心是对的,如果不优化,包多了肯定慢。

我们做了几个优化:

  1. 增量构建:只构建变更的包,Turborepo自动处理依赖
  2. 缓存机制:本地缓存 + 云端缓存,缓存命中率80%+
  3. 并行构建:多个包同时构建,充分利用CPU

实测下来,80个包全量构建10分钟,增量构建2分钟,缓存命中30秒。还能接受。

如果以后包更多,可以考虑拆成多个Monorepo,或者用Nx这种更强的工具。"

Q3: 灰度发布怎么做的?

回答

"我们用的是Nginx分流 + cookie标识。

具体流程:

  1. 在Nginx配置根据cookie分流
  2. 灰度用户访问时,后端设置特殊cookie
  3. Nginx检测到cookie,转发到新版本的服务器
  4. 其他用户还是走老版本

代码大概是这样:

nginx
if ($http_cookie ~* "beta_user=true") {
    proxy_pass http://new_server;
}
proxy_pass http://old_server;

先灰度10%用户,观察一周,看监控指标、用户反馈。没问题再逐步扩大到50%、100%。

中间发现过几个小问题,好在能快速回滚,风险可控。"