Vue 微前端实践项目
基于 Webpack Module Federation 的 Vue 微前端架构实践,实现独立开发、独立部署、模块共享的前端微服务方案。
项目简介
本项目通过 Webpack 5 的 Module Federation 特性实现了微前端架构,包含三个应用:
- 宿主应用(host-app):提供统一入口和导航,负责加载和管理微应用
- 用户模块(user-app):独立的用户管理模块,暴露用户列表和用户详情组件
- 订单模块(order-app):独立的订单管理模块,暴露订单列表组件
三个应用共享 Vue 和 Vue Router 依赖,避免重复加载,提升性能。
技术栈
- Vue 3
- Vue Router 4
- Webpack 5 (Module Federation)
- Vue CLI
项目结构
vue-module-federation/
├── host-app/ # 宿主应用
│ ├── src/ # 源代码
│ ├── package.json # 项目依赖
│ └── vue.config.js # Webpack 配置
├── user-app/ # 用户模块应用
│ ├── src/ # 源代码
│ ├── package.json # 项目依赖
│ └── vue.config.js # Webpack 配置
└── order-app/ # 订单模块应用
├── src/ # 源代码
├── package.json # 项目依赖
└── vue.config.js # Webpack 配置
快速开始
1. 安装依赖
需要分别为三个应用安装依赖:
# 安装宿主应用依赖
cd host-app
npm install
# 安装用户模块依赖
cd ../user-app
npm install
# 安装订单模块依赖
cd ../order-app
npm install
2. 启动应用
需要同时启动三个应用,它们将运行在不同的端口:
- 宿主应用:http://localhost:8080
- 用户模块:http://localhost:8081
- 订单模块:http://localhost:8082
方法一:使用多个终端分别启动
# 终端 1:启动宿主应用
cd host-app
npm run serve
# 终端 2:启动用户模块
cd user-app
npm run serve
# 终端 3:启动订单模块
cd order-app
npm run serve
方法二:使用根目录提供的并行启动脚本(推荐)
项目根目录已配置了便捷的脚本,可以一键安装所有依赖并启动所有应用:
# 在项目根目录执行
# 安装所有应用的依赖(仅第一次需要)
npm install
npm run install:all
# 同时启动所有三个应用
npm run serve:all
# 同时构建所有三个应用(用于生产环境)
npm run build:all
这些脚本使用了 concurrently 工具来并行启动多个服务,极大地简化了开发流程。
3. 访问应用
启动成功后,打开浏览器访问:http://localhost:8080
在首页可以看到系统介绍,点击顶部导航栏可以访问用户管理和订单管理模块,这些模块内容来自于远程应用。
构建部署
1. 构建应用
为每个应用执行构建命令:
# 构建宿主应用
cd host-app
npm run build
# 构建用户模块
cd ../user-app
npm run build
# 构建订单模块
cd ../order-app
npm run build
2. 部署配置
构建完成后,需要将各应用的构建产物部署到服务器或 CDN。部署时需要注意:
- 确保各应用的
publicPath配置正确(在 vue.config.js 中) - 确保宿主应用能够正确访问到远程应用的
remoteEntry.js文件 - 生产环境下,建议将共享依赖(如 Vue、Vue Router)抽离到 CDN,进一步减少重复加载
核心配置说明
宿主应用(host-app)配置
在 vue.config.js 中,通过 remotes 配置声明了要加载的远程应用:
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
userApp: 'userApp@http://localhost:8081/remoteEntry.js',
orderApp: 'orderApp@http://localhost:8082/remoteEntry.js'
},
shared: {
vue: { singleton: true, requiredVersion: require('./package.json').dependencies.vue },
'vue-router': { singleton: true, requiredVersion: require('./package.json').dependencies['vue-router'] }
}
})
远程应用(user-app/order-app)配置
在远程应用的 vue.config.js 中,通过 exposes 配置声明了要暴露的模块:
new ModuleFederationPlugin({
name: 'userApp',
filename: 'remoteEntry.js',
exposes: {
'./UserList': './src/components/UserList.vue',
'./UserDetail': './src/views/UserDetail.vue'
},
shared: {
vue: { singleton: true, requiredVersion: require('./package.json').dependencies.vue },
'vue-router': { singleton: true, requiredVersion: require('./package.json').dependencies['vue-router'] }
}
})
动态加载远程组件
在宿主应用的路由配置中,通过动态导入加载远程组件:
const UserList = () => import('userApp/UserList')
const OrderList = () => import('orderApp/OrderList')
注意事项
- 版本一致性:确保各应用使用的共享依赖版本兼容
- 跨域问题:开发环境下,需要在远程应用的
devServer中配置Access-Control-Allow-Origin: * - singleton 配置:Vue 等框架类依赖必须设置
singleton: true,确保全局只有一个实例 - 构建顺序:生产环境部署时,建议先部署远程应用,再部署宿主应用
- 热更新:Module Federation 与 HMR 结合使用时,可能需要额外配置以获得最佳开发体验
常见问题
Q: 远程组件加载失败怎么办?
A: 检查以下几点:
- 远程应用是否已启动
- 远程应用的端口和
publicPath是否配置正确 - 宿主应用的
remotes配置是否正确指向远程应用的remoteEntry.js - 检查浏览器控制台是否有跨域错误
Q: 为什么修改了远程应用的代码,宿主应用没有更新?
A: Module Federation 依赖远程应用的构建产物,修改代码后需要重新构建或启动开发服务器,才能在宿主应用中看到更新。