1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
| // router/integration.ts
import { createBrowserRouter, Navigate } from 'react-router-dom';
// 微应用路由配置
interface MicroRoute {
path: string;
microApp: string;
module: string;
fallback?: React.ComponentType;
}
const microRoutes: MicroRoute[] = [
{
path: '/products/*',
microApp: 'product',
module: './ProductRouter',
},
{
path: '/checkout/*',
microApp: 'checkout',
module: './CheckoutRouter',
},
{
path: '/user/*',
microApp: 'user',
module: './UserRouter',
},
];
// 创建统一路由
const router = createBrowserRouter([
{
path: '/',
element: <MainLayout />,
children: [
{
index: true,
element: <Navigate to="/products" replace />,
},
// 基础路由
{
path: '/home',
element: <HomePage />,
},
// 微应用路由
...microRoutes.map(route => ({
path: route.path,
element: (
<MicroAppLoader
scope={route.microApp}
module={route.module}
fallback={route.fallback}
/>
),
})),
// 404 页面
{
path: '*',
element: <NotFoundPage />,
},
],
},
]);
// 微应用加载器组件
function MicroAppLoader({
scope,
module,
fallback: Fallback,
}: {
scope: string;
module: string;
fallback?: React.ComponentType;
}) {
const url = `https://${scope}.example.com/remoteEntry.js`;
const { module: Component, error, isLoading } = useRemoteModule({
url,
scope,
module,
});
if (isLoading) {
return Fallback ? <Fallback /> : <PageLoading />;
}
if (error) {
return <ErrorFallback error={error} />;
}
if (!Component) {
return null;
}
return <Component />;
}
// 微应用内部路由
// product/src/router.tsx
import { Routes, Route, Navigate } from 'react-router-dom';
export function ProductRouter() {
return (
<Routes>
<Route path="/" element={<ProductList />} />
<Route path="/list" element={<ProductList />} />
<Route path="/:id" element={<ProductDetail />} />
<Route path="/search" element={<ProductSearch />} />
<Route path="*" element={<Navigate to="/list" replace />} />
</Routes>
);
}
|