Urban Lifeline Web 微前端项目
基于 @module-federation/vite 的微前端架构,包含共享模块和多个业务应用。
✨ v2.0 升级:已从
@originjs/vite-plugin-federation迁移到官方维护的@module-federation/vite,获得更好的开发体验和稳定性!
📦 项目结构
urbanLifelineWeb/
├── packages/
│ ├── shared/ # 共享模块 (端口 5000)
│ ├── platform/ # 主平台应用 (端口 5001)
│ ├── bidding/ # 招标管理应用 (端口 5002)
│ └── workcase/ # 案例管理应用 (端口 5003)
└── package.json
🚀 快速开始
1. 安装依赖
# 使用 pnpm 安装(推荐)
pnpm install
# 或使用 install.bat 脚本
install.bat
2. 启动开发服务器
# 方式1: 使用启动脚本(Windows,推荐)
start-all.bat
# 方式2: 使用 pnpm 并行启动所有服务
pnpm run dev
# 方式3: 手动启动(需要两个终端)
# 终端1 - 启动 shared
cd packages/shared
pnpm run dev # http://localhost:7000
# 终端2 - 启动 platform
cd packages/platform
pnpm run dev # http://localhost:7001
3. 构建生产版本
# 构建所有应用
pnpm run build
# 或单独构建
cd packages/shared && pnpm run build
cd packages/platform && pnpm run build
cd packages/bidding && pnpm run build
cd packages/workcase && pnpm run build
🌐 端口分配
| 服务 | 端口 | 说明 |
|---|---|---|
| Shared | 5000 | 共享组件和工具库 |
| Platform | 5001 | 主平台应用 |
| Bidding | 5002 | 招标管理应用 |
| Workcase | 5003 | 案例管理应用 |
🔧 技术栈
- 框架: Vue 3.5 + TypeScript
- 构建工具: Vite 6.0
- UI 组件库: Element Plus 2.9
- 状态管理: Pinia 2.2
- 路由: Vue Router 4.5
- 工具库: VueUse
📝 Module Federation 配置
Shared 配置 (packages/shared/vite.config.ts)
import { federation } from '@module-federation/vite'
export default defineConfig({
plugins: [
federation({
name: 'shared',
filename: 'remoteEntry.js',
exposes: {
'./FileUpload': './src/components/fileupload/FileUpload.vue',
'./DynamicFormItem': './src/components/dynamicFormItem/DynamicFormItem.vue',
'./api': './src/api/index.ts',
'./authAPI': './src/api/auth/auth.ts',
'./fileAPI': './src/api/file/file.ts',
'./utils': './src/utils/index.ts',
'./types': './src/types/index.ts',
'./components': './src/components/index.ts'
},
shared: {
vue: {},
'vue-router': {},
'element-plus': {},
'@element-plus/icons-vue': {},
axios: {}
}
})
],
server: {
port: 7000,
strictPort: true, // 关键:锁定端口,避免漂移
host: true,
cors: true
}
})
Platform 配置 (packages/platform/vite.config.ts)
import { federation } from '@module-federation/vite'
export default defineConfig({
plugins: [
federation({
name: 'platform',
remotes: {
shared: {
type: 'module', // 关键:必须指定 ES module 类型
name: 'shared',
entry: 'http://localhost:7000/remoteEntry.js'
}
},
shared: {
vue: {},
'vue-router': {},
'element-plus': {},
axios: {}
}
})
]
})
使用示例
// 在 platform 中导入 shared 的组件
import FileUpload from 'shared/FileUpload'
import DynamicFormItem from 'shared/DynamicFormItem'
import { authAPI } from 'shared/authAPI'
import { getAesInstance } from 'shared/utils'
import type { LoginParam, SysUserVO } from 'shared/types'
// 在组件中使用
<template>
<FileUpload mode="cover" v-model:coverImg="image" />
<DynamicFormItem :config="config" v-model="value" />
</template>
<script setup lang="ts">
// 调用 API
const result = await authAPI.login(params)
</script>
优势
- ✅ 开发模式直接支持:无需构建,直接 dev 即可
- ✅ 完整的热更新:修改 shared 代码自动更新到 platform
- ✅ 自动路径处理:无需关心 shared 内部的
@/路径 - ✅ 依赖去重:vue、element-plus 等只加载一次
- ✅ 企业级稳定:官方维护,支持 Vite 6
🎯 开发工作流
日常开发
-
启动服务(每天开始)
# 使用脚本一键启动 start-all.bat # 或手动启动 cd packages/shared && pnpm run dev # 终端1 cd packages/platform && pnpm run dev # 终端2 -
修改代码
- 修改 shared 组件 → 保存 → 自动热更新 ✨
- 修改 platform 页面 → 保存 → 自动热更新 ✨
-
结束开发
- 按 Ctrl+C 停止所有服务
添加新的共享模块
-
在 shared 中创建组件
# 例如创建新组件 packages/shared/src/components/mynew/MyNewComponent.vue -
在 shared/vite.config.ts 中暴露
exposes: { './MyNewComponent': './src/components/mynew/MyNewComponent.vue' } -
在 platform 中使用
import MyNewComponent from 'shared/MyNewComponent'
API 代理
所有应用的 /api 请求会代理到后端服务 http://localhost:8080
跨域配置
开发环境下所有服务已启用 CORS,支持跨域访问。
🔥 注意事项
- 包管理器: 必须使用 pnpm(项目使用 pnpm workspace)
- 启动顺序: 必须先启动
shared服务(5000端口),再启动其他应用 - 端口占用: 确保 5000-5003 端口未被占用,shared 使用 strictPort 模式
- Node 版本: 建议使用 Node.js 18+
- Module Federation: remoteEntry.js 路径为
http://localhost:7000/remoteEntry.js(不是 /assets/)