generator-mico-cli 0.1.21 → 0.1.22
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/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +7 -2
- package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +26 -2
- package/generators/subapp-react/templates/homepage/src/app.tsx +28 -0
- package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +3 -1
- package/package.json +1 -1
package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx
CHANGED
|
@@ -17,6 +17,8 @@ interface MicroAppLoaderProps {
|
|
|
17
17
|
entry: string;
|
|
18
18
|
name: string;
|
|
19
19
|
displayName?: string;
|
|
20
|
+
/** 当前路由路径,用于通知子应用进行内部路由切换 */
|
|
21
|
+
routePath?: string;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
const sanitizeId = (path: string): string => {
|
|
@@ -33,6 +35,7 @@ const MicroAppLoader: React.FC<MicroAppLoaderProps> = ({
|
|
|
33
35
|
entry,
|
|
34
36
|
name,
|
|
35
37
|
displayName,
|
|
38
|
+
routePath,
|
|
36
39
|
}) => {
|
|
37
40
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
38
41
|
const mountIdRef = useRef(0);
|
|
@@ -63,16 +66,18 @@ const MicroAppLoader: React.FC<MicroAppLoaderProps> = ({
|
|
|
63
66
|
uid: authInfo.uid,
|
|
64
67
|
avatar: authInfo.avatar,
|
|
65
68
|
nickname: authInfo.nickname,
|
|
69
|
+
// 传递当前路由路径,让子应用进行内部路由切换
|
|
70
|
+
routePath,
|
|
66
71
|
};
|
|
67
72
|
};
|
|
68
73
|
|
|
69
|
-
//
|
|
74
|
+
// 当路由等"无需重载"的状态更新时,通过 update() 通知子应用
|
|
70
75
|
useEffect(() => {
|
|
71
76
|
if (!isMountedRef.current) return;
|
|
72
77
|
|
|
73
78
|
const microApp = getMicroApp(appName);
|
|
74
79
|
microApp?.update?.(buildPropsRef.current());
|
|
75
|
-
}, [appName]);
|
|
80
|
+
}, [appName, routePath]);
|
|
76
81
|
|
|
77
82
|
useEffect(() => {
|
|
78
83
|
const wrapper = wrapperRef.current;
|
|
@@ -11,6 +11,26 @@ import './index.less';
|
|
|
11
11
|
|
|
12
12
|
const { Content } = Layout;
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* 从 entry URL 中提取微应用标识
|
|
16
|
+
* 同一个 entry 的所有路由使用相同的标识,避免频繁卸载/重载微应用
|
|
17
|
+
*
|
|
18
|
+
* 注意:使用完整的 origin + pathname 作为标识,避免同一 host 上多个子应用冲突
|
|
19
|
+
* 例如:http://localhost:8010/app1/ 和 http://localhost:8010/app2/ 会有不同的标识
|
|
20
|
+
*/
|
|
21
|
+
const getAppNameFromEntry = (entry: string): string => {
|
|
22
|
+
try {
|
|
23
|
+
const url = new URL(entry, window.location.href);
|
|
24
|
+
// 使用 origin + pathname 作为标识,确保不同路径的子应用有不同标识
|
|
25
|
+
// 如 "localhost-8010" 或 "localhost-8010-app1"
|
|
26
|
+
const identifier = url.host + url.pathname;
|
|
27
|
+
return identifier.replace(/[^a-zA-Z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
|
|
28
|
+
} catch {
|
|
29
|
+
// fallback:使用 entry 的 hash
|
|
30
|
+
return entry.replace(/[^a-zA-Z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
14
34
|
/**
|
|
15
35
|
* 主布局组件
|
|
16
36
|
* 注意:Umi Max 使用 React Router 6,应该使用 <Outlet /> 渲染子路由,而不是 children
|
|
@@ -43,13 +63,17 @@ const BasicLayout: React.FC = () => {
|
|
|
43
63
|
// 如果有匹配的动态路由配置且需要加载微应用
|
|
44
64
|
if (currentRoute?.loadType === 'microapp' && currentRoute.entry) {
|
|
45
65
|
layoutLogger.log('Loading microapp:', currentRoute);
|
|
66
|
+
// 使用 entry 的 origin 作为微应用标识,同一个 entry 的所有路由共用一个实例
|
|
67
|
+
const appName = getAppNameFromEntry(currentRoute.entry);
|
|
46
68
|
return (
|
|
47
69
|
<MicroAppLoader
|
|
48
70
|
entry={currentRoute.entry}
|
|
49
|
-
// 使用
|
|
50
|
-
name={
|
|
71
|
+
// 使用 entry 生成的标识,而不是 path
|
|
72
|
+
name={appName}
|
|
51
73
|
// 显示名称用于 loading 提示
|
|
52
74
|
displayName={currentRoute.name}
|
|
75
|
+
// 传递当前路由路径,让子应用进行内部路由切换
|
|
76
|
+
routePath={currentRoute.path}
|
|
53
77
|
/>
|
|
54
78
|
);
|
|
55
79
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* 自定义函数请放在 @/common/mainApp.ts 中
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { history } from '@umijs/max';
|
|
10
11
|
import { appLogger } from './common/logger';
|
|
11
12
|
import { type IMicroAppProps, setMainAppProps } from './common/mainApp';
|
|
12
13
|
|
|
@@ -48,6 +49,22 @@ export const qiankun = {
|
|
|
48
49
|
appLogger.log('mount', props);
|
|
49
50
|
// 保存主应用传递的 props,包括 request 实例
|
|
50
51
|
setMainAppProps(props);
|
|
52
|
+
|
|
53
|
+
// 初始路由同步:确保子应用加载后跳转到主应用指定的路由
|
|
54
|
+
// 使用 requestAnimationFrame 延迟执行,确保 React 组件已完成初始化
|
|
55
|
+
if (props.routePath) {
|
|
56
|
+
requestAnimationFrame(() => {
|
|
57
|
+
if (!history) return;
|
|
58
|
+
const currentPath = history.location.pathname;
|
|
59
|
+
if (currentPath !== props.routePath) {
|
|
60
|
+
appLogger.log('initial route sync:', {
|
|
61
|
+
from: currentPath,
|
|
62
|
+
to: props.routePath,
|
|
63
|
+
});
|
|
64
|
+
history.push(props.routePath);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
51
68
|
},
|
|
52
69
|
|
|
53
70
|
/**
|
|
@@ -61,9 +78,20 @@ export const qiankun = {
|
|
|
61
78
|
|
|
62
79
|
/**
|
|
63
80
|
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
|
|
81
|
+
* 当主应用传递的 props 变化时调用(如路由变化、时区变化等)
|
|
64
82
|
*/
|
|
65
83
|
async update(props: IMicroAppProps) {
|
|
66
84
|
appLogger.log('update', props);
|
|
85
|
+
|
|
86
|
+
// 处理路由变化:主应用路由切换时,子应用进行内部路由同步
|
|
87
|
+
if (props.routePath && history) {
|
|
88
|
+
const currentPath = history.location.pathname;
|
|
89
|
+
if (currentPath !== props.routePath) {
|
|
90
|
+
appLogger.log('route sync:', { from: currentPath, to: props.routePath });
|
|
91
|
+
history.push(props.routePath);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
67
95
|
// 更新 props
|
|
68
96
|
setMainAppProps(props);
|
|
69
97
|
},
|
|
@@ -10,7 +10,9 @@ export interface IMicroAppProps {
|
|
|
10
10
|
/** 主应用标识 */
|
|
11
11
|
mainApp: string;
|
|
12
12
|
/** 主应用共享的 request 实例 */
|
|
13
|
-
request
|
|
13
|
+
request?: <T = any>(url: string, options?: any) => Promise<T>;
|
|
14
|
+
/** 当前路由路径(由主应用传递,用于子应用内部路由切换) */
|
|
15
|
+
routePath?: string;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
/** 存储主应用传递的 props */
|