news 2026/1/31 3:16:25

记录一次微前端改造:把 10+ 个独立 Vue 项目整合到一起

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
记录一次微前端改造:把 10+ 个独立 Vue 项目整合到一起

记录一次微前端改造:把 10+ 个独立 Vue 项目整合到一起

最近主导了公司前端项目的微前端化改造,踩了不少坑,也有一些收获。趁着记忆还新鲜,把过程记录下来,希望能给有类似需求的同学一些参考。

声明:我也是第一次做微前端,很多地方可能不够规范,欢迎大家指正。

一、背景:我们遇到了什么问题?

1.1 项目现状

公司的前端项目经过几年发展,变成了这样:

  • 10+ 个独立的 Vue 项目:认证系统、主业务平台、教育模块、社区模块、H5 移动端等
  • 每个项目都是独立的 Git 仓库,有自己的 CI/CD 流程,独立部署
  • 技术栈不太统一:有的是 Vue 2 + Vue CLI,有的是 Vue 3 + Vite
  • 用户体验比较割裂:在不同系统间跳转时,要重新加载整个页面

1.2 想解决的问题

问题具体表现
体验不连贯系统间跳转白屏时间长,感觉像在用不同的网站
登录状态虽然用 Cookie 共享了 token,但体验还是不够好
重复建设每个项目都有一套类似的基础代码

说实话,一开始我对微前端也没什么概念,是领导提出想把这些系统整合成一个统一入口,我才开始研究这个方向。

二、技术选型:为什么选 micro-app?

2.1 调研过的方案

方案我的理解为什么没选/选了
iframe最简单,天然隔离体验不好,通信麻烦
qiankun最成熟,基于 single-spa配置比较复杂,子应用改造成本高
micro-app京东出的,基于 Web Components接入简单,改造成本低 ✅
Module FederationWebpack 5 的功能我们有的项目还在用 Vue CLI 4

2.2 选择 micro-app 的原因

说实话,主要是因为简单

看了官方文档后,发现子应用几乎不需要怎么改,基座应用也就几行代码:

// 基座应用启动importmicroAppfrom'@micro-zoe/micro-app'microApp.start()// 加载子应用就一个标签<micro-app name="app1"url="http://localhost:8081/"></micro-app>

对于我这种微前端新手来说,能快速跑起来比什么都重要。

三、项目结构

3.1 实际情况

需要说明的是,我们的项目结构是这样的:

# 这些都是独立的 Git 仓库,我只是在本地建了个文件夹把它们放一起方便开发 project/ # 本地文件夹(不是 Git 仓库) ├── project-base/ # 基座应用 - 独立 Git 仓库 ├── project-main/ # 主业务 - 独立 Git 仓库 ├── project-auth/ # 认证系统 - 独立 Git 仓库 ├── project-edu/ # 教育模块 - 独立 Git 仓库 ├── project-community/ # 社区模块 - 独立 Git 仓库 └── ...

每个项目都是独立部署的,有自己的 Docker 镜像和部署流程。微前端改造并没有改变这一点,只是加了一个基座应用来统一加载它们。

3.2 端口规划

本地开发时,我给每个应用分配了不同的端口:

应用端口路由前缀
project-base8080/
project-main8081/main
project-auth8082/auth
project-community8083/communities
project-edu8085/edu

四、具体怎么做的

4.1 基座应用

基座应用是新建的,用的 Vite + Vue 3。

1. 安装和初始化 micro-app

// project-base/src/main.tsimportmicroAppfrom"@micro-zoe/micro-app";microApp.start({plugins:{modules:{},},});

2. Vite 需要配置一下,不然会报错

// project-base/vite.config.tsvue({template:{compilerOptions:{// 告诉 Vue:micro-app 是自定义元素,别当组件解析isCustomElement:(tag)=>/^micro-app/.test(tag),},},});

3. 路由配置

// 用通配符匹配子应用的所有路由constroutes=[{path:"/main/:page*",component:()=>import("@/views/main.vue"),},{path:"/auth/:page*",component:()=>import("@/views/auth.vue"),},// ...];

4. 子应用挂载组件

<!-- project-base/src/views/main.vue --> <template> <micro-app name="project-main" :url="url" baseroute="/main" /> </template> <script setup> const url = "http://localhost:8081/child/main/"; </script>

4.2 子应用改造

子应用的改造确实不多,主要是这几步:

1. 新建 public-path.ts

// src/public-path.tsif(window.__MICRO_APP_ENVIRONMENT__){__webpack_public_path__=window.__MICRO_APP_PUBLIC_PATH__;}

2. 改造入口文件

// src/main.tsimport"./public-path";// 必须放最前面letapp=null;letrouter=null;lethistory=null;functionmount(){history=createWebHistory(window.__MICRO_APP_BASE_ROUTE__||process.env.BASE_URL);router=createRouter({history,routes});app=createApp(App);app.use(router);app.mount("#app");}functionunmount(){app?.unmount();history?.destroy();app=null;router=null;history=null;}// 判断运行环境if(window.__MICRO_APP_ENVIRONMENT__){// 微前端环境window[`micro-app-${window.__MICRO_APP_NAME__}`]={mount,unmount};}else{// 独立运行mount();}

3. 配置跨域(开发环境)

// vue.config.jsmodule.exports={devServer:{headers:{"Access-Control-Allow-Origin":"*",},},};

4.3 状态共享

这块我承认做得不太规范。

按理说应该用 micro-app 提供的通信机制,但我们之前的项目已经有一套基于 localStorage + Cookie 的方案在用了,而且子应用还需要支持独立运行,所以就没改。

// 公共组件库里的 storeexportdefault{set(key,data){localStorage.setItem(key,JSON.stringify({data}));},get(key){constcache=localStorage.getItem(key);returncache?JSON.parse(cache).data:null;},// token 用 cookie 存,这样可以跨子域共享set_cookie(name,value){document.cookie=`${name}=${value}; path=/; max-age=${30*24*60*60}`;},};

这个方案的问题

  • 不够实时,一个应用改了数据,另一个应用需要刷新才能看到
  • 没有利用 micro-app 的能力

但也有好处

  • 简单,团队都能理解
  • 子应用可以独立运行
  • 刷新页面不丢数据

后续有时间可能会改成用 micro-app 的setGlobalData,但目前这样也能用。

五、部署

每个应用还是独立部署,只是 Nginx 配置需要调整一下。

基座应用

server { listen 80; location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } }

子应用

server { listen 80; location /child/main { root /usr/share/nginx/html; try_files $uri $uri/ /child/main/index.html; } }

六、踩过的坑

6.1 静态资源 404

子应用的图片加载不出来,因为路径变了。

解决:确保public-path.ts配置正确,而且要放在入口文件最前面 import。

6.2 路由跳转 URL 不变

子应用内部跳转后,浏览器地址栏没变化。

解决:路由的 base 要用window.__MICRO_APP_BASE_ROUTE__

6.3 热更新有问题

开发时子应用热更新会导致页面白屏。

解决:子应用关闭热更新hot: false。有点麻烦,但暂时没找到更好的办法。

6.4 样式偶尔会串

虽然 micro-app 有样式隔离,但有些全局样式还是会影响。

解决:尽量用 scoped 样式,避免写太通用的选择器。

七、目前的效果

改造完成后:

  • ✅ 用户可以在一个页面里切换不同的系统,不用重新加载
  • ✅ 各个子应用还是可以独立开发、独立部署
  • ✅ 子应用也可以单独访问(方便开发调试)

还存在的问题:

  • ⚠️ 状态共享方案不够优雅
  • ⚠️ 没有用到 micro-app 的很多高级功能(预加载、keep-alive 等)
  • ⚠️ 首次加载子应用还是有点慢

八、后续想做的

  1. 研究一下预加载:micro-app 支持 preFetch,应该能提升切换速度
  2. 优化状态共享:看看能不能用 micro-app 的全局数据机制
  3. 统一技术栈:慢慢把 Vue 2 的项目升级到 Vue 3

九、一些想法

做完这次改造,有几点感受:

  1. 微前端不是银弹。如果项目本身就不大,或者团队就几个人,可能真没必要搞这么复杂。

  2. 先跑起来再说。一开始不要想着做到完美,能用就行,后面再慢慢优化。

  3. 保持子应用的独立性。我觉得这点很重要,子应用能独立运行,开发调试都方便很多。

  4. 文档很重要。我们内部写了一份接入文档,新同事照着做基本都能跑起来。

十、参考资料

  • micro-app 官方文档
  • micro-app GitHub

以上就是这次微前端改造的记录。如有错误或者更好的方案,欢迎评论区交流~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 23:43:44

ResCLIP

ResCLIP动机 现有方法&#xff08;如SCLIP、NACLIP&#xff09;通过将最后一层的标准交叉相关自注意力&#xff08;C2SAC^2SAC2SA, Query-Key&#xff09;替换为自相关自注意力&#xff08;SCSA, Query-Query或Key-Key&#xff09;来解决空间不变性问题 。然而&#xff0c;这些…

作者头像 李华
网站建设 2026/1/26 6:58:30

红黑树入门指南(C语言版)

红黑树入门指南&#xff08;C语言版&#xff09; 文章目录红黑树入门指南&#xff08;C语言版&#xff09;前言一、红黑树的基本概念1.1 核心定义1.2 关键特性二、红黑树的操作2.1 旋转&#xff08;Rotation&#xff09;左旋&#xff08;Left Rotation&#xff09;右旋&#xf…

作者头像 李华
网站建设 2026/1/30 10:46:13

K-Diffusion终极指南:从零掌握扩散模型图像生成

K-Diffusion终极指南&#xff1a;从零掌握扩散模型图像生成 【免费下载链接】k-diffusion Karras et al. (2022) diffusion models for PyTorch 项目地址: https://gitcode.com/gh_mirrors/kd/k-diffusion K-Diffusion是基于PyTorch实现的先进扩散模型库&#xff0c;专门…

作者头像 李华
网站建设 2026/1/30 8:24:26

基于SpringBoot的职工健康监护管理系统-计算机毕业设计源码+LW文档

摘 要 随着企业对于员工健康管理的日益重视&#xff0c;开发一套高效、便捷的职工健康监护管理系统显得尤为重要。本系统基于Spring Boot框架进行开发&#xff0c;旨在为企业提供一套全面的职工健康管理解决方案系统实现了职工健康信息的录入、查询、统计与分析等功能。用户…

作者头像 李华
网站建设 2026/1/30 1:19:31

终极日语学习方案:Memento播放器如何让看剧效率翻倍300%

终极日语学习方案&#xff1a;Memento播放器如何让看剧效率翻倍300% 【免费下载链接】Memento An mpv-based video player for studying Japanese 项目地址: https://gitcode.com/gh_mirrors/meme/Memento 你是否曾在看日剧时因为频繁暂停查单词而失去观影乐趣&#xff…

作者头像 李华