@lvetechs/micro-app 1.1.0 → 1.1.3
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 +76 -2
- package/dist/components/MicroAppVue.vue +138 -0
- package/dist/functions/mountMicroApp.d.ts +91 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +12 -12
- package/dist/index.mjs +328 -283
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,43 @@ npm install @lvetechs/micro-app
|
|
|
26
26
|
|
|
27
27
|
## 在 React 项目中使用
|
|
28
28
|
|
|
29
|
-
###
|
|
29
|
+
### 方式一:mountMicroApp(推荐)
|
|
30
|
+
|
|
31
|
+
使用 `mountMicroApp` 简化微应用挂载,自动创建容器:
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { mountMicroApp } from '@lvetechs/micro-app'
|
|
35
|
+
import { useEffect, useRef } from 'react'
|
|
36
|
+
|
|
37
|
+
function App() {
|
|
38
|
+
const appRef = useRef<ReturnType<typeof mountMicroApp> | null>(null)
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
// 创建并挂载微应用
|
|
42
|
+
const result = mountMicroApp({
|
|
43
|
+
app: {
|
|
44
|
+
name: 'my-app',
|
|
45
|
+
entry: 'http://localhost:3001',
|
|
46
|
+
container: 'app-container', // 无需手动创建容器
|
|
47
|
+
},
|
|
48
|
+
onStatusChange: (status) => console.log('状态:', status),
|
|
49
|
+
onError: (error) => console.error('错误:', error),
|
|
50
|
+
onLoad: () => console.log('加载完成'),
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
result.mount()
|
|
54
|
+
appRef.current = result
|
|
55
|
+
|
|
56
|
+
return () => {
|
|
57
|
+
result.destroy()
|
|
58
|
+
}
|
|
59
|
+
}, [])
|
|
60
|
+
|
|
61
|
+
return <div id="app-container" />
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 方式二:createMicroApp
|
|
30
66
|
|
|
31
67
|
```tsx
|
|
32
68
|
import { createMicroApp } from '@lvetechs/micro-app'
|
|
@@ -231,7 +267,45 @@ function App() {
|
|
|
231
267
|
|
|
232
268
|
## 在 Vue 项目中使用
|
|
233
269
|
|
|
234
|
-
###
|
|
270
|
+
### 方式一:mountMicroApp(推荐)
|
|
271
|
+
|
|
272
|
+
使用 `mountMicroApp` 简化微应用挂载,自动创建容器:
|
|
273
|
+
|
|
274
|
+
```vue
|
|
275
|
+
<script setup lang="ts">
|
|
276
|
+
import { onMounted, onUnmounted, ref } from 'vue'
|
|
277
|
+
import { mountMicroApp } from '@lvetechs/micro-app'
|
|
278
|
+
|
|
279
|
+
const appRef = ref<ReturnType<typeof mountMicroApp> | null>(null)
|
|
280
|
+
|
|
281
|
+
onMounted(() => {
|
|
282
|
+
// 创建并挂载微应用
|
|
283
|
+
const result = mountMicroApp({
|
|
284
|
+
app: {
|
|
285
|
+
name: 'my-app',
|
|
286
|
+
entry: 'http://localhost:3001',
|
|
287
|
+
container: 'app-container', // 无需手动创建容器
|
|
288
|
+
},
|
|
289
|
+
onStatusChange: (status) => console.log('状态:', status),
|
|
290
|
+
onError: (error) => console.error('错误:', error),
|
|
291
|
+
onLoad: () => console.log('加载完成'),
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
result.mount()
|
|
295
|
+
appRef.value = result
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
onUnmounted(() => {
|
|
299
|
+
appRef.value?.destroy()
|
|
300
|
+
})
|
|
301
|
+
</script>
|
|
302
|
+
|
|
303
|
+
<template>
|
|
304
|
+
<div id="app-container" />
|
|
305
|
+
</template>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### 方式二:createMicroApp
|
|
235
309
|
|
|
236
310
|
与 React 项目相同,使用 `createMicroApp` 函数:
|
|
237
311
|
|
|
@@ -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>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { SubAppConfig, MicroAppStatus, MicroAppService } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 简化的微应用配置
|
|
5
|
+
*/
|
|
6
|
+
export interface SimpleSubAppConfig {
|
|
7
|
+
/** 应用名称 */
|
|
8
|
+
name: string;
|
|
9
|
+
/** 应用入口 URL */
|
|
10
|
+
entry: string;
|
|
11
|
+
/** 挂载容器选择器 */
|
|
12
|
+
container: string;
|
|
13
|
+
/** 路由规则 */
|
|
14
|
+
activeRule?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* mountMicroApp 配置
|
|
18
|
+
*/
|
|
19
|
+
export interface MountMicroAppOptions {
|
|
20
|
+
/** 子应用配置 */
|
|
21
|
+
app: SimpleSubAppConfig;
|
|
22
|
+
/** 错误回调 */
|
|
23
|
+
onError?: (error: Error) => void;
|
|
24
|
+
/** 状态变化回调 */
|
|
25
|
+
onStatusChange?: (status: MicroAppStatus) => void;
|
|
26
|
+
/** 加载完成回调 */
|
|
27
|
+
onLoad?: () => void;
|
|
28
|
+
/** 加载模式 */
|
|
29
|
+
mode?: 'iframe' | 'dynamic';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* mountMicroApp 返回值
|
|
33
|
+
*/
|
|
34
|
+
export interface MountResult {
|
|
35
|
+
/** 启动应用 */
|
|
36
|
+
mount: () => void;
|
|
37
|
+
/** 卸载应用 */
|
|
38
|
+
unmount: () => void;
|
|
39
|
+
/** 重新加载 */
|
|
40
|
+
reload: () => void;
|
|
41
|
+
/** 销毁 */
|
|
42
|
+
destroy: () => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 创建并挂载微应用的简化函数
|
|
46
|
+
*
|
|
47
|
+
* @param options 配置项
|
|
48
|
+
* @returns 控制函数
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // React 使用
|
|
52
|
+
* useEffect(() => {
|
|
53
|
+
* const { mount } = mountMicroApp({
|
|
54
|
+
* app: { name: 'my-app', entry: 'http://localhost:3001', container: '#app' }
|
|
55
|
+
* })
|
|
56
|
+
* mount()
|
|
57
|
+
* return () => destroy()
|
|
58
|
+
* }, [])
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // Vue 使用
|
|
62
|
+
* onMounted(() => {
|
|
63
|
+
* const { mount } = mountMicroApp({
|
|
64
|
+
* app: { name: 'my-app', entry: 'http://localhost:3001', container: '#app' }
|
|
65
|
+
* })
|
|
66
|
+
* mount()
|
|
67
|
+
* })
|
|
68
|
+
*
|
|
69
|
+
* onUnmounted(() => {
|
|
70
|
+
* result?.destroy()
|
|
71
|
+
* })
|
|
72
|
+
*/
|
|
73
|
+
export declare function mountMicroApp(options: MountMicroAppOptions): MountResult;
|
|
74
|
+
/**
|
|
75
|
+
* 批量挂载多个微应用
|
|
76
|
+
*
|
|
77
|
+
* @param apps 子应用配置数组
|
|
78
|
+
* @param options 全局配置
|
|
79
|
+
* @returns 应用名称到控制函数的映射
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const apps = mountMicroApps([
|
|
83
|
+
* { name: 'app1', entry: 'http://localhost:3001', container: '#app1' },
|
|
84
|
+
* { name: 'app2', entry: 'http://localhost:3002', container: '#app2' },
|
|
85
|
+
* ])
|
|
86
|
+
*
|
|
87
|
+
* // 启动所有
|
|
88
|
+
* Object.values(apps).forEach(app => app.mount())
|
|
89
|
+
*/
|
|
90
|
+
export declare function mountMicroApps(apps: SimpleSubAppConfig[], options?: Omit<MountMicroAppOptions, 'app'>): Record<string, MountResult>;
|
|
91
|
+
export type { MicroAppService, MicroAppStatus, SubAppConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
* 同时支持 React 和 Vue
|
|
9
9
|
*
|
|
10
10
|
* 使用方式:
|
|
11
|
-
* - React: import { MicroApp, createMicroApp } from '@lvetechs/micro-app'
|
|
12
|
-
* - Vue: import { createMicroApp } from '@lvetechs/micro-app'
|
|
13
|
-
* 并使用 src/components/MicroAppVue.vue 组件
|
|
11
|
+
* - React: import { MicroApp, createMicroApp, mountMicroApp } from '@lvetechs/micro-app'
|
|
12
|
+
* - Vue: import { createMicroApp, mountMicroApp } from '@lvetechs/micro-app'
|
|
14
13
|
*/
|
|
15
14
|
export type { MicroAppStatus, LoadMode, SubAppConfig, MicroAppInfo, MicroAppInstance, MicroAppOptions, MicroAppService, } from './types';
|
|
16
15
|
export { createMicroApp } from './core/MicroAppManager';
|
|
16
|
+
export { mountMicroApp, mountMicroApps } from './functions/mountMicroApp';
|
|
17
|
+
export type { MountMicroAppOptions, MountResult, SimpleSubAppConfig } from './functions/mountMicroApp';
|
|
17
18
|
export { MicroApp } from './components/MicroApp';
|
|
18
19
|
export type { MicroAppProps } from './components/MicroApp';
|
|
19
20
|
export { ErrorBoundary } from './components/ErrorBoundary';
|