@lvetechs/micro-app 1.0.3 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,16 +16,17 @@ npm install @lvetechs/micro-app
16
16
  {
17
17
  "peerDependencies": {
18
18
  "react": ">=16.8.0",
19
- "react-dom": ">=16.8.0"
19
+ "react-dom": ">=16.8.0",
20
+ "vue": ">=3.0.0"
20
21
  }
21
22
  }
22
23
  ```
23
24
 
24
- ## 两种使用模式
25
+ > **注意**:Vue 是可选依赖。如果在 Vue 项目中使用,需要安装 Vue;如果在 React 项目中使用,需要安装 React。
25
26
 
26
- ### 模式一:函数式实例化
27
+ ## 在 React 项目中使用
27
28
 
28
- 使用 `createMicroApp` 函数创建微应用服务实例,通过返回的实例方法控制应用。
29
+ ### 方式一:函数式实例化
29
30
 
30
31
  ```tsx
31
32
  import { createMicroApp } from '@lvetechs/micro-app'
@@ -228,6 +229,84 @@ function App() {
228
229
  <!-- 组件式会自动创建,但容器选择器需要匹配配置 -->
229
230
  ```
230
231
 
232
+ ## 在 Vue 项目中使用
233
+
234
+ ### 方式一:函数式实例化
235
+
236
+ 与 React 项目相同,使用 `createMicroApp` 函数:
237
+
238
+ ```vue
239
+ <script setup lang="ts">
240
+ import { createMicroApp } from '@lvetechs/micro-app'
241
+
242
+ const microApp = createMicroApp({
243
+ apps: [
244
+ {
245
+ name: 'react-app',
246
+ entry: 'http://localhost:3001',
247
+ container: '#react-app-container',
248
+ mode: 'iframe',
249
+ },
250
+ ],
251
+ onStatusChange: (name, status) => {
252
+ console.log(`[${name}] 状态变化: ${status}`)
253
+ },
254
+ })
255
+
256
+ // 启动应用
257
+ microApp.startApp('react-app')
258
+ </script>
259
+
260
+ <template>
261
+ <div id="react-app-container"></div>
262
+ </template>
263
+ ```
264
+
265
+ ### 方式二:使用 Vue 组件
266
+
267
+ 在 Vue 3 项目中可以使用 `MicroAppVue.vue` 组件:
268
+
269
+ ```vue
270
+ <script setup lang="ts">
271
+ import { ref } from 'vue'
272
+ import MicroAppVue from '@lvetechs/micro-app/dist/components/MicroAppVue.vue'
273
+
274
+ const apps = [
275
+ {
276
+ name: 'react-app',
277
+ entry: 'http://localhost:3001',
278
+ container: '#vue-app-container',
279
+ active_rule: '/app/react',
280
+ },
281
+ {
282
+ name: 'vue-app',
283
+ entry: 'http://localhost:3002',
284
+ container: '#vue-app-container',
285
+ active_rule: '/app/vue',
286
+ },
287
+ ]
288
+
289
+ const activeApp = ref(apps[0].name)
290
+ </script>
291
+
292
+ <template>
293
+ <div>
294
+ <!-- 切换按钮 -->
295
+ <button @click="activeApp = 'react-app'">React App</button>
296
+ <button @click="activeApp = 'vue-app'">Vue App</button>
297
+
298
+ <!-- 微应用组件 -->
299
+ <MicroAppVue
300
+ :apps="apps"
301
+ :active-app="activeApp"
302
+ @status-change="(name, status) => console.log(name, status)"
303
+ />
304
+ </div>
305
+ </template>
306
+ ```
307
+
308
+ > **注意**:使用 Vue 组件时,需要在项目中安装 `@vitejs/plugin-vue`。
309
+
231
310
  ## 打包
232
311
 
233
312
  ```bash
@@ -0,0 +1,138 @@
1
+ /**
2
+ * ============================================
3
+ * 微应用组件 - Vue 版本
4
+ * ============================================
5
+ *
6
+ * 轻量级微前端框架 - Vue 集成
7
+ */
8
+
9
+ <script setup lang="ts">
10
+ import { ref, onMounted, onUnmounted, computed, watch, nextTick } from 'vue'
11
+ import { createMicroApp } from '../core/MicroAppManager'
12
+ import type { SubAppConfig, MicroAppStatus, MicroAppService } from '../types'
13
+
14
+ // Props 定义
15
+ interface Props {
16
+ /** 子应用配置数组 */
17
+ apps: SubAppConfig[]
18
+ /** 当前激活的应用名称(只渲染一个应用) */
19
+ activeApp?: string
20
+ /** 错误回调 */
21
+ onError?: (error: Error, appName?: string) => void
22
+ /** 状态变化回调 */
23
+ onStatusChange?: (name: string, status: MicroAppStatus) => void
24
+ /** 加载完成回调 */
25
+ onLoad?: (appName: string) => void
26
+ /** 自定义加载中 UI */
27
+ loading?: any
28
+ /** 自定义错误 UI */
29
+ errorFallback?: any
30
+ }
31
+
32
+ const props = withDefaults(defineProps<Props>(), {
33
+ activeApp: '',
34
+ })
35
+
36
+ // 记录当前已启动的应用
37
+ const startedAppsRef = ref<Set<string>>(new Set())
38
+
39
+ // 微应用服务实例
40
+ let service: MicroAppService | null = null
41
+
42
+ // 初始化微应用服务
43
+ onMounted(() => {
44
+ service = createMicroApp({
45
+ apps: props.apps,
46
+ onError: props.onError,
47
+ onStatusChange: (name, status) => {
48
+ props.onStatusChange?.(name, status)
49
+ },
50
+ onLoad: props.onLoad,
51
+ })
52
+
53
+ // 初始启动 activeApp
54
+ if (props.activeApp) {
55
+ startApp(props.activeApp)
56
+ }
57
+ })
58
+
59
+ // 清理
60
+ onUnmounted(() => {
61
+ // 停止所有已启动的应用
62
+ startedAppsRef.value.forEach(appName => {
63
+ service?.stopApp(appName)
64
+ })
65
+ })
66
+
67
+ // 监听 activeApp 变化
68
+ watch(() => props.activeApp, async (newApp, oldApp) => {
69
+ if (!service) return
70
+
71
+ // 停止旧应用
72
+ if (oldApp && oldApp !== newApp && startedAppsRef.value.has(oldApp)) {
73
+ service.stopApp(oldApp)
74
+ startedAppsRef.value.delete(oldApp)
75
+ }
76
+
77
+ // 启动新应用
78
+ if (newApp && newApp !== oldApp) {
79
+ await startApp(newApp)
80
+ }
81
+ })
82
+
83
+ // 启动应用(等待 DOM 就绪)
84
+ async function startApp(appName: string) {
85
+ if (!service) return
86
+
87
+ const appConfig = props.apps.find(app => app.name === appName)
88
+ if (!appConfig) return
89
+
90
+ // 等待 DOM 渲染完成
91
+ await nextTick()
92
+
93
+ const tryStartApp = () => {
94
+ const containerElement = document.querySelector(appConfig.container)
95
+ if (!containerElement) {
96
+ requestAnimationFrame(tryStartApp)
97
+ return
98
+ }
99
+
100
+ if (!startedAppsRef.value.has(appName)) {
101
+ service?.startApp(appName)
102
+ startedAppsRef.value.add(appName)
103
+ }
104
+ }
105
+
106
+ requestAnimationFrame(tryStartApp)
107
+ }
108
+
109
+ // 获取当前激活的应用配置
110
+ const activeAppConfig = computed(() => {
111
+ if (!props.activeApp) return null
112
+ return props.apps.find(app => app.name === props.activeApp)
113
+ })
114
+ </script>
115
+
116
+ <template>
117
+ <div class="micro-app-wrapper">
118
+ <!-- 渲染激活的应用容器 -->
119
+ <div
120
+ v-if="activeAppConfig"
121
+ :id="activeAppConfig.container.replace('#', '')"
122
+ class="micro-app-container"
123
+ :data-micro-app="activeAppConfig.name"
124
+ />
125
+ </div>
126
+ </template>
127
+
128
+ <style scoped>
129
+ .micro-app-wrapper {
130
+ width: 100%;
131
+ height: 100%;
132
+ }
133
+
134
+ .micro-app-container {
135
+ width: 100%;
136
+ height: 100%;
137
+ }
138
+ </style>
package/dist/index.d.ts CHANGED
@@ -5,6 +5,12 @@
5
5
  *
6
6
  * 轻量级微前端框架
7
7
  * 支持函数式实例化和组件式实例化两种模式
8
+ * 同时支持 React 和 Vue
9
+ *
10
+ * 使用方式:
11
+ * - React: import { MicroApp, createMicroApp } from '@lvetechs/micro-app'
12
+ * - Vue: import { createMicroApp } from '@lvetechs/micro-app'
13
+ * 并使用 src/components/MicroAppVue.vue 组件
8
14
  */
9
15
  export type { MicroAppStatus, LoadMode, SubAppConfig, MicroAppInfo, MicroAppInstance, MicroAppOptions, MicroAppService, } from './types';
10
16
  export { createMicroApp } from './core/MicroAppManager';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvetechs/micro-app",
3
- "version": "1.0.3",
3
+ "version": "1.1.2",
4
4
  "description": "轻量级微前端框架 - 支持函数式和组件式实例化",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,19 @@
22
22
  "peerDependencies": {
23
23
  "react": "^18.2.0",
24
24
  "react-dom": "^18.2.0",
25
- "react-router-dom": "^6.30.3"
25
+ "react-router-dom": "^6.30.3",
26
+ "vue": "^3.4.0"
27
+ },
28
+ "peerDependenciesMeta": {
29
+ "react": {
30
+ "optional": true
31
+ },
32
+ "react-dom": {
33
+ "optional": true
34
+ },
35
+ "vue": {
36
+ "optional": true
37
+ }
26
38
  },
27
39
  "devDependencies": {
28
40
  "@types/react": "^18.2.66",
@@ -30,6 +42,7 @@
30
42
  "@typescript-eslint/eslint-plugin": "^7.2.0",
31
43
  "@typescript-eslint/parser": "^7.2.0",
32
44
  "@vitejs/plugin-react": "^4.2.1",
45
+ "@vitejs/plugin-vue": "^5.0.0",
33
46
  "autoprefixer": "^10.4.19",
34
47
  "eslint": "^8.57.0",
35
48
  "eslint-plugin-react-hooks": "^4.6.0",
@@ -38,7 +51,8 @@
38
51
  "tailwindcss": "^3.4.3",
39
52
  "typescript": "^5.2.2",
40
53
  "vite": "^5.2.0",
41
- "vite-plugin-dts": "^3.9.1"
54
+ "vite-plugin-dts": "^3.9.1",
55
+ "vue": "^3.4.0"
42
56
  },
43
57
  "keywords": [
44
58
  "micro-frontend",
@@ -50,7 +64,7 @@
50
64
  "license": "MIT",
51
65
  "scripts": {
52
66
  "dev": "vite",
53
- "build": "tsc && vite build",
67
+ "build": "tsc && vite build && node scripts/postbuild.mjs",
54
68
  "preview": "vite preview",
55
69
  "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
56
70
  }