@ice/mf-runtime 1.0.3-beta.2 → 1.0.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 +1 -221
- package/es2017/RemoteModule.js +21 -73
- package/es2017/index.d.ts +0 -2
- package/es2017/index.js +3 -5
- package/es2017/runtime-plugin.js +27 -29
- package/es2017/types.d.ts +0 -67
- package/es2017/types.js +1 -18
- package/esm/RemoteModule.js +30 -73
- package/esm/index.d.ts +0 -2
- package/esm/index.js +3 -5
- package/esm/runtime-plugin.js +37 -33
- package/esm/types.d.ts +0 -67
- package/esm/types.js +1 -20
- package/package.json +3 -14
- package/docs/PLUGIN_SYSTEM_GUIDE.md +0 -294
- package/es2017/__tests__/plugin-manager.test.d.ts +0 -1
- package/es2017/__tests__/plugin-manager.test.js +0 -291
- package/es2017/__tests__/setup.d.ts +0 -1
- package/es2017/__tests__/setup.js +0 -28
- package/es2017/plugin-manager.d.ts +0 -74
- package/es2017/plugin-manager.js +0 -128
- package/esm/__tests__/plugin-manager.test.d.ts +0 -1
- package/esm/__tests__/plugin-manager.test.js +0 -343
- package/esm/__tests__/setup.d.ts +0 -1
- package/esm/__tests__/setup.js +0 -43
- package/esm/plugin-manager.d.ts +0 -74
- package/esm/plugin-manager.js +0 -201
package/README.md
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
# @ice/mf-runtime
|
|
2
2
|
|
|
3
|
-
基于 Module Federation 的运行时工具,用于在 ice.js 应用中加载和管理远程模块。支持跨版本 React
|
|
3
|
+
基于 Module Federation 的运行时工具,用于在 ice.js 应用中加载和管理远程模块。支持跨版本 React 组件加载
|
|
4
4
|
|
|
5
5
|
## 特性
|
|
6
6
|
|
|
7
7
|
- 基于 [Module Federation 2.0](https://module-federation.io/index.html)
|
|
8
8
|
- 支持跨版本 React 组件加载
|
|
9
9
|
- 内置冲突检测和降级渲染
|
|
10
|
-
- 🔌 **增强插件机制**: 完全兼容标准 MF 运行时插件
|
|
11
|
-
- 🎯 **组件增强**: 支持 HOC、Props 注入等组件扩展机制
|
|
12
|
-
- 🛡️ **错误边界**: 内置错误处理和恢复机制
|
|
13
|
-
- 📊 **性能监控**: 支持组件加载和渲染性能追踪
|
|
14
|
-
- 🔄 **热插拔**: 运行时动态注册和移除插件
|
|
15
|
-
- 📝 **TypeScript**: 完整的类型定义支持
|
|
16
10
|
|
|
17
11
|
## 安装
|
|
18
12
|
|
|
@@ -20,220 +14,6 @@
|
|
|
20
14
|
$ npm i @ice/mf-runtime --save
|
|
21
15
|
```
|
|
22
16
|
|
|
23
|
-
## 插件机制
|
|
24
|
-
|
|
25
|
-
从 v1.0.1 开始,`@ice/mf-runtime` 支持强大的插件机制,允许在运行时动态扩展微前端功能。
|
|
26
|
-
|
|
27
|
-
### 插件类型
|
|
28
|
-
|
|
29
|
-
#### 1. 标准 MF 插件 (FederationRuntimePlugin)
|
|
30
|
-
标准 MF 插件使用原生的 `@module-federation/runtime` API 进行管理:
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
import { registerPlugins } from '@module-federation/runtime';
|
|
34
|
-
import type { FederationRuntimePlugin } from '@ice/mf-runtime';
|
|
35
|
-
|
|
36
|
-
const mfPlugin: FederationRuntimePlugin = {
|
|
37
|
-
name: 'my-mf-plugin',
|
|
38
|
-
beforeRequest: (args) => {
|
|
39
|
-
console.log('模块请求前:', args);
|
|
40
|
-
return args;
|
|
41
|
-
},
|
|
42
|
-
onLoad: (args) => {
|
|
43
|
-
console.log('模块加载后:', args);
|
|
44
|
-
return args;
|
|
45
|
-
},
|
|
46
|
-
afterResolve: (args) => {
|
|
47
|
-
console.log('模块解析后:', args);
|
|
48
|
-
return args;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// 使用原生 API 注册标准 MF 插件
|
|
53
|
-
registerPlugins([mfPlugin]);
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
#### 2. 增强插件 (EnhancedRuntimePlugin)
|
|
57
|
-
增强插件使用新的 API 进行管理,提供组件级别的扩展能力:
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import { registerEnhancedPlugins } from '@ice/mf-runtime';
|
|
61
|
-
import type { EnhancedRuntimePlugin } from '@ice/mf-runtime';
|
|
62
|
-
|
|
63
|
-
const enhancedPlugin: EnhancedRuntimePlugin = {
|
|
64
|
-
name: 'my-enhanced-plugin',
|
|
65
|
-
|
|
66
|
-
// 组件包装器 - 支持 HOC 模式
|
|
67
|
-
wrapComponent: (WrappedComponent, context) => {
|
|
68
|
-
return function Enhanced(props) {
|
|
69
|
-
console.log(`渲染组件: ${context.remoteName}/${context.moduleName}`);
|
|
70
|
-
return <WrappedComponent {...props} />;
|
|
71
|
-
};
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
// 属性注入器
|
|
75
|
-
injectProps: (props, context) => {
|
|
76
|
-
return {
|
|
77
|
-
...props,
|
|
78
|
-
injectedProp: `来自 ${context.remoteName} 的数据`
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// 使用新的 API 注册增强插件
|
|
84
|
-
registerEnhancedPlugins([enhancedPlugin]);
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### 注册和使用插件
|
|
88
|
-
|
|
89
|
-
#### 基本用法
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
import { init, registerEnhancedPlugins, RemoteModule } from '@ice/mf-runtime';
|
|
93
|
-
import { registerPlugins } from '@module-federation/runtime';
|
|
94
|
-
|
|
95
|
-
// 注册标准 MF 插件
|
|
96
|
-
registerPlugins([mfPlugin]);
|
|
97
|
-
|
|
98
|
-
// 注册增强插件
|
|
99
|
-
registerEnhancedPlugins([enhancedPlugin]);
|
|
100
|
-
|
|
101
|
-
// 初始化运行时
|
|
102
|
-
init({
|
|
103
|
-
remotes: [
|
|
104
|
-
{
|
|
105
|
-
name: 'remote-app',
|
|
106
|
-
entry: 'http://localhost:3001/remoteEntry.js'
|
|
107
|
-
}
|
|
108
|
-
]
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// 使用远程模块(插件会自动应用)
|
|
112
|
-
function App() {
|
|
113
|
-
return (
|
|
114
|
-
<RemoteModule
|
|
115
|
-
scope="remote-app"
|
|
116
|
-
module="Button"
|
|
117
|
-
componentProps={{ text: '点击我' }}
|
|
118
|
-
/>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
#### 使用示例插件包
|
|
124
|
-
|
|
125
|
-
我们提供了一个示例插件包 `@ice/mf-plugin-example`,包含常用的插件:
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
npm install @ice/mf-plugin-example
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
```typescript
|
|
132
|
-
import { registerPlugins } from '@module-federation/runtime';
|
|
133
|
-
import { registerEnhancedPlugins } from '@ice/mf-runtime';
|
|
134
|
-
import {
|
|
135
|
-
errorBoundaryPlugin,
|
|
136
|
-
commonPropsPlugin,
|
|
137
|
-
developmentMFLoggingPlugin,
|
|
138
|
-
developmentEnhancedLoggingPlugin
|
|
139
|
-
} from '@ice/mf-plugin-example';
|
|
140
|
-
|
|
141
|
-
// 注册标准 MF 插件
|
|
142
|
-
registerPlugins([
|
|
143
|
-
developmentMFLoggingPlugin // MF 日志插件
|
|
144
|
-
]);
|
|
145
|
-
|
|
146
|
-
// 注册增强插件
|
|
147
|
-
registerEnhancedPlugins([
|
|
148
|
-
developmentEnhancedLoggingPlugin, // 增强日志插件
|
|
149
|
-
errorBoundaryPlugin, // 错误边界插件
|
|
150
|
-
commonPropsPlugin // 通用属性注入插件
|
|
151
|
-
]);
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### 插件开发指南
|
|
155
|
-
|
|
156
|
-
#### 错误边界插件示例
|
|
157
|
-
|
|
158
|
-
```typescript
|
|
159
|
-
import { ErrorBoundary } from 'react-error-boundary';
|
|
160
|
-
|
|
161
|
-
const errorBoundaryPlugin: EnhancedRuntimePlugin = {
|
|
162
|
-
name: 'error-boundary',
|
|
163
|
-
wrapComponent: (WrappedComponent, context) => {
|
|
164
|
-
return function ErrorBoundaryWrapper(props) {
|
|
165
|
-
return (
|
|
166
|
-
<ErrorBoundary
|
|
167
|
-
fallback={<div>组件 {context.remoteName} 加载失败</div>}
|
|
168
|
-
onError={(error) => {
|
|
169
|
-
console.error(`组件错误:`, error);
|
|
170
|
-
}}
|
|
171
|
-
>
|
|
172
|
-
<WrappedComponent {...props} />
|
|
173
|
-
</ErrorBoundary>
|
|
174
|
-
);
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### 属性注入插件示例
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
const themePlugin: EnhancedRuntimePlugin = {
|
|
184
|
-
name: 'theme-injector',
|
|
185
|
-
injectProps: (props, context) => {
|
|
186
|
-
return {
|
|
187
|
-
...props,
|
|
188
|
-
theme: {
|
|
189
|
-
mode: 'light',
|
|
190
|
-
primaryColor: '#1890ff'
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### 插件 API
|
|
198
|
-
|
|
199
|
-
#### EnhancedPluginManager
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
import { getEnhancedPluginManager } from '@ice/mf-runtime';
|
|
203
|
-
|
|
204
|
-
const manager = getEnhancedPluginManager();
|
|
205
|
-
|
|
206
|
-
// 注册增强插件
|
|
207
|
-
manager.register(enhancedPlugin);
|
|
208
|
-
|
|
209
|
-
// 获取插件信息
|
|
210
|
-
const info = manager.getPluginInfo();
|
|
211
|
-
// 返回: [{ name: 'plugin-name', hasWrapper: true, hasInjector: false }]
|
|
212
|
-
|
|
213
|
-
// 移除插件
|
|
214
|
-
manager.removePlugin('plugin-name');
|
|
215
|
-
|
|
216
|
-
// 清空所有插件
|
|
217
|
-
manager.clear();
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
#### React Hook
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
import { useEnhancedPluginManager } from '@ice/mf-runtime';
|
|
224
|
-
|
|
225
|
-
function MyComponent() {
|
|
226
|
-
const enhancedPluginManager = useEnhancedPluginManager();
|
|
227
|
-
|
|
228
|
-
// 动态操作插件
|
|
229
|
-
const handleAddPlugin = () => {
|
|
230
|
-
enhancedPluginManager.register(newEnhancedPlugin);
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
return <div>...</div>;
|
|
234
|
-
}
|
|
235
|
-
```
|
|
236
|
-
|
|
237
17
|
## 使用
|
|
238
18
|
|
|
239
19
|
### 1. 初始化配置
|
package/es2017/RemoteModule.js
CHANGED
|
@@ -2,13 +2,10 @@ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
|
|
|
2
2
|
import { loadRemote } from '@module-federation/runtime';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { useMemo, useState, useLayoutEffect, forwardRef } from 'react';
|
|
5
|
-
import * as ReactDOM from 'react-dom';
|
|
6
5
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
7
6
|
import { FallBack } from './FallBack';
|
|
8
7
|
import { setFederatedModulePublicPath } from './set-public-path';
|
|
9
8
|
import { getMicroMod } from './mf-global-store';
|
|
10
|
-
import { useEnhancedPluginManager } from './plugin-manager';
|
|
11
|
-
import { isRuntimePluginWrapper } from './types';
|
|
12
9
|
const useMountNode = (mountNodeConfig)=>{
|
|
13
10
|
const [resolvedNode, setResolvedNode] = useState(undefined);
|
|
14
11
|
// 解析各种类型的 mountNode
|
|
@@ -38,7 +35,6 @@ const RemoteModuleInner = ({ module, scope, runtime, publicPath, LoadingComponen
|
|
|
38
35
|
var _microMod, _runtime, _runtime1;
|
|
39
36
|
const microMod = getMicroMod(scope);
|
|
40
37
|
const resolvedMountNode = useMountNode(mountNode);
|
|
41
|
-
const enhancedPluginManager = useEnhancedPluginManager();
|
|
42
38
|
if ((_microMod = microMod) === null || _microMod === void 0 ? void 0 : _microMod.publicPath) {
|
|
43
39
|
setFederatedModulePublicPath(microMod.moduleFederatedName, microMod.publicPath);
|
|
44
40
|
}
|
|
@@ -49,76 +45,35 @@ const RemoteModuleInner = ({ module, scope, runtime, publicPath, LoadingComponen
|
|
|
49
45
|
if (!module || !scope) return null;
|
|
50
46
|
return /*#__PURE__*/ React.lazy(async ()=>{
|
|
51
47
|
var _typedRemoteModule;
|
|
52
|
-
// 使用标准 MF 加载逻辑,MF 插件自动执行
|
|
53
48
|
const remoteModule = await loadRemote(`${scope}/${module}`);
|
|
54
|
-
//
|
|
55
|
-
if (
|
|
56
|
-
//
|
|
57
|
-
const
|
|
58
|
-
const remoteReact = reactInstances.react;
|
|
59
|
-
const remoteReactDOM = reactInstances.reactDOM;
|
|
60
|
-
// 🔑 正确的 HOC 层级顺序:
|
|
61
|
-
// 1. 先应用增强插件(与其他情况保持一致)
|
|
62
|
-
const PluginWrappedComponent = enhancedPluginManager.wrapComponent(originalComponent, {
|
|
63
|
-
remoteName: scope,
|
|
64
|
-
moduleName: module,
|
|
65
|
-
props: componentProps || {},
|
|
66
|
-
React: remoteReact,
|
|
67
|
-
ReactDOM: remoteReactDOM
|
|
68
|
-
});
|
|
69
|
-
// 2. 再应用 FallBack(处理不同 React 版本和 mountNode)
|
|
70
|
-
const FinalComponent = FallBack({
|
|
71
|
-
Original: PluginWrappedComponent,
|
|
72
|
-
remoteVersion: runtimeInfo.remoteVersion ? ()=>runtimeInfo.remoteVersion : undefined,
|
|
73
|
-
hostVersion: runtimeInfo.hostVersion ? ()=>runtimeInfo.hostVersion : undefined,
|
|
74
|
-
remoteReactDOM: runtimeInfo.remoteReactDOM,
|
|
75
|
-
remoteReact: runtimeInfo.remoteReact,
|
|
76
|
-
mountNode: resolvedMountNode,
|
|
77
|
-
containerClassName: fallbackContainerClassName
|
|
78
|
-
});
|
|
49
|
+
// 检查是否是来自 runtime plugin 的包装函数(通过标记识别)
|
|
50
|
+
if (typeof remoteModule === 'function' && remoteModule.__ICE_MF_RUNTIME_WRAPPER__) {
|
|
51
|
+
// 调用包装函数并传入 mountNode 和 containerClassName
|
|
52
|
+
const ComponentFromPlugin = remoteModule(resolvedMountNode, fallbackContainerClassName);
|
|
79
53
|
return {
|
|
80
|
-
default:
|
|
54
|
+
default: ComponentFromPlugin
|
|
81
55
|
};
|
|
82
56
|
}
|
|
83
57
|
const typedRemoteModule = remoteModule;
|
|
84
|
-
let BaseComponent;
|
|
85
58
|
if (!((_typedRemoteModule = typedRemoteModule) === null || _typedRemoteModule === void 0 ? void 0 : _typedRemoteModule.default)) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
59
|
+
return {
|
|
60
|
+
default: remoteModule
|
|
61
|
+
};
|
|
89
62
|
}
|
|
90
|
-
let FinalComponent;
|
|
91
|
-
// 如果需要 runtime 处理(不同 React 版本或 mountNode)
|
|
92
63
|
if (runtime) {
|
|
93
64
|
const { react, reactDOM } = runtime;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
Original: PluginWrappedComponent,
|
|
104
|
-
remoteReact: ()=>react,
|
|
105
|
-
remoteReactDOM: ()=>reactDOM,
|
|
106
|
-
mountNode: resolvedMountNode,
|
|
107
|
-
containerClassName: fallbackContainerClassName
|
|
108
|
-
});
|
|
109
|
-
} else {
|
|
110
|
-
// 没有 runtime 需求时,直接应用插件包装器
|
|
111
|
-
FinalComponent = enhancedPluginManager.wrapComponent(BaseComponent, {
|
|
112
|
-
remoteName: scope,
|
|
113
|
-
moduleName: module,
|
|
114
|
-
props: componentProps || {},
|
|
115
|
-
React: React,
|
|
116
|
-
ReactDOM: ReactDOM
|
|
117
|
-
});
|
|
65
|
+
return {
|
|
66
|
+
default: FallBack({
|
|
67
|
+
Original: typedRemoteModule.default,
|
|
68
|
+
remoteReact: ()=>react,
|
|
69
|
+
remoteReactDOM: ()=>reactDOM,
|
|
70
|
+
mountNode: resolvedMountNode,
|
|
71
|
+
containerClassName: fallbackContainerClassName
|
|
72
|
+
})
|
|
73
|
+
};
|
|
118
74
|
}
|
|
119
|
-
console.log('FinalComponent', FinalComponent);
|
|
120
75
|
return {
|
|
121
|
-
default:
|
|
76
|
+
default: typedRemoteModule.default
|
|
122
77
|
};
|
|
123
78
|
});
|
|
124
79
|
}, [
|
|
@@ -127,18 +82,11 @@ const RemoteModuleInner = ({ module, scope, runtime, publicPath, LoadingComponen
|
|
|
127
82
|
(_runtime = runtime) === null || _runtime === void 0 ? void 0 : _runtime.react,
|
|
128
83
|
(_runtime1 = runtime) === null || _runtime1 === void 0 ? void 0 : _runtime1.reactDOM,
|
|
129
84
|
resolvedMountNode,
|
|
130
|
-
fallbackContainerClassName
|
|
131
|
-
enhancedPluginManager,
|
|
132
|
-
componentProps
|
|
85
|
+
fallbackContainerClassName
|
|
133
86
|
]);
|
|
134
87
|
const Loading = LoadingComponent || /*#__PURE__*/ React.createElement("div", null, "Loading...");
|
|
135
88
|
const ErrorFallback = ({ error })=>ErrorComponent || /*#__PURE__*/ React.createElement("div", null, "远程模块加载失败: ", error.message);
|
|
136
89
|
if (!Component) return Loading;
|
|
137
|
-
// 应用增强插件的属性注入
|
|
138
|
-
const injectedProps = enhancedPluginManager.injectProps(componentProps || {}, {
|
|
139
|
-
remoteName: scope,
|
|
140
|
-
moduleName: module
|
|
141
|
-
});
|
|
142
90
|
return /*#__PURE__*/ React.createElement(ErrorBoundary, {
|
|
143
91
|
resetKeys: [
|
|
144
92
|
module,
|
|
@@ -150,8 +98,8 @@ const RemoteModuleInner = ({ module, scope, runtime, publicPath, LoadingComponen
|
|
|
150
98
|
}, /*#__PURE__*/ React.createElement(React.Suspense, {
|
|
151
99
|
fallback: Loading
|
|
152
100
|
}, /*#__PURE__*/ React.createElement(Component, _object_spread({
|
|
153
|
-
ref
|
|
154
|
-
},
|
|
101
|
+
ref: ref
|
|
102
|
+
}, componentProps), children)));
|
|
155
103
|
};
|
|
156
104
|
// 使用 forwardRef 包装组件以支持 ref
|
|
157
105
|
export const RemoteModule = /*#__PURE__*/ forwardRef(RemoteModuleInner);
|
package/es2017/index.d.ts
CHANGED
|
@@ -2,7 +2,5 @@ import type { ExtendedUserOptions, MicroMod } from './types';
|
|
|
2
2
|
export { loadRemote, registerPlugins } from '@module-federation/runtime';
|
|
3
3
|
export * from './FallBack';
|
|
4
4
|
export * from './RemoteModule';
|
|
5
|
-
export * from './types';
|
|
6
|
-
export * from './plugin-manager';
|
|
7
5
|
export declare function init(options: ExtendedUserOptions, microMods?: MicroMod[]): void;
|
|
8
6
|
export declare function initByMicroMods(microMods: MicroMod[], hostName?: string): void;
|
package/es2017/index.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { getBasename } from '@ice/stark-app';
|
|
2
|
-
import { registerPlugins
|
|
2
|
+
import { registerPlugins, init as mfInit } from '@module-federation/runtime';
|
|
3
3
|
import { runtimePlugin } from './runtime-plugin';
|
|
4
4
|
import { initGlobalStore } from './mf-global-store';
|
|
5
5
|
export { loadRemote, registerPlugins } from '@module-federation/runtime';
|
|
6
6
|
export * from './FallBack';
|
|
7
7
|
export * from './RemoteModule';
|
|
8
|
-
export * from './types';
|
|
9
|
-
export * from './plugin-manager';
|
|
10
8
|
export function init(options, microMods) {
|
|
11
9
|
initGlobalStore(options, microMods);
|
|
12
10
|
mfInit(options);
|
|
13
|
-
|
|
11
|
+
registerPlugins([
|
|
14
12
|
runtimePlugin()
|
|
15
13
|
]);
|
|
16
14
|
}
|
|
@@ -36,6 +34,6 @@ export function initByMicroMods(microMods, hostName) {
|
|
|
36
34
|
});
|
|
37
35
|
init({
|
|
38
36
|
remotes,
|
|
39
|
-
name: generateUniqueId()
|
|
37
|
+
name: hostName || generateUniqueId()
|
|
40
38
|
}, microMods);
|
|
41
39
|
}
|
package/es2017/runtime-plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { getExtraInfo, getRemoteInfoFromStore, hasConflict } from './mf-global-store';
|
|
3
|
-
import {
|
|
3
|
+
import { FallBack } from './FallBack';
|
|
4
4
|
const loadRemotePackagedReactAndRender = async (args)=>{
|
|
5
5
|
var _args_origin_options_shared_reactdom_, _args_origin_options_shared_reactdom, _args_origin_options_shared, _args_origin_options, _remoteInstance_options_shared_reactdom_, _remoteInstance_options_shared_reactdom, _remoteInstance_options_shared, _remoteInstance_options;
|
|
6
6
|
const hostVersion = ((_args_origin_options = args.origin.options) === null || _args_origin_options === void 0 ? void 0 : (_args_origin_options_shared = _args_origin_options.shared) === null || _args_origin_options_shared === void 0 ? void 0 : (_args_origin_options_shared_reactdom = _args_origin_options_shared['react-dom']) === null || _args_origin_options_shared_reactdom === void 0 ? void 0 : (_args_origin_options_shared_reactdom_ = _args_origin_options_shared_reactdom[0]) === null || _args_origin_options_shared_reactdom_ === void 0 ? void 0 : _args_origin_options_shared_reactdom_.version) || React.version;
|
|
@@ -10,29 +10,28 @@ const loadRemotePackagedReactAndRender = async (args)=>{
|
|
|
10
10
|
if (remoteVersion && hostVersion) {
|
|
11
11
|
var _sharedOptions_find;
|
|
12
12
|
const remoteReactDOM = await remoteInstance.loadShare('react-dom', {
|
|
13
|
-
resolver: (sharedOptions)=>(_sharedOptions_find = sharedOptions.find((
|
|
13
|
+
resolver: (sharedOptions)=>(_sharedOptions_find = sharedOptions.find((i)=>i.version === remoteVersion)) !== null && _sharedOptions_find !== void 0 ? _sharedOptions_find : sharedOptions[0]
|
|
14
14
|
});
|
|
15
15
|
var _sharedOptions_find1;
|
|
16
16
|
const remoteReact = await remoteInstance.loadShare('react', {
|
|
17
|
-
resolver: (sharedOptions)=>(_sharedOptions_find1 = sharedOptions.find((
|
|
17
|
+
resolver: (sharedOptions)=>(_sharedOptions_find1 = sharedOptions.find((i)=>i.version === remoteVersion)) !== null && _sharedOptions_find1 !== void 0 ? _sharedOptions_find1 : sharedOptions[0]
|
|
18
18
|
});
|
|
19
19
|
if (!remoteReact || !remoteReactDOM) {
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
22
|
+
// 返回一个接受 mountNode 和 containerClassName 参数的函数,并添加标记
|
|
23
|
+
const wrappedRender = (mountNode, containerClassName)=>FallBack({
|
|
24
|
+
Original: args.exposeModule.default,
|
|
25
|
+
remoteVersion: ()=>remoteVersion,
|
|
26
|
+
hostVersion: ()=>hostVersion,
|
|
27
|
+
remoteReactDOM: remoteReactDOM,
|
|
28
|
+
remoteReact: remoteReact,
|
|
29
|
+
mountNode,
|
|
30
|
+
containerClassName
|
|
31
|
+
});
|
|
32
|
+
// 添加标记,用于在 RemoteModule 中识别
|
|
33
|
+
wrappedRender.__ICE_MF_RUNTIME_WRAPPER__ = true;
|
|
34
|
+
return wrappedRender;
|
|
36
35
|
}
|
|
37
36
|
return null;
|
|
38
37
|
};
|
|
@@ -66,18 +65,17 @@ export const runtimePlugin = ()=>({
|
|
|
66
65
|
console.log('[runtime Plugin onLoad] use same external react');
|
|
67
66
|
return args;
|
|
68
67
|
}
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
});
|
|
68
|
+
// 返回一个接受 mountNode 和 containerClassName 参数的函数,并添加标记
|
|
69
|
+
const wrappedRender = (mountNode, containerClassName)=>FallBack({
|
|
70
|
+
Original: args.exposeModule.default,
|
|
71
|
+
remoteReactDOM: remoteReactDOM,
|
|
72
|
+
remoteReact: remoteReact,
|
|
73
|
+
mountNode,
|
|
74
|
+
containerClassName
|
|
75
|
+
});
|
|
76
|
+
// 添加标记,用于在 RemoteModule 中识别
|
|
77
|
+
wrappedRender.__ICE_MF_RUNTIME_WRAPPER__ = true;
|
|
78
|
+
return wrappedRender;
|
|
81
79
|
}
|
|
82
80
|
}
|
|
83
81
|
const fallBackRender = await loadRemotePackagedReactAndRender(args);
|
package/es2017/types.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { UserOptions } from '@module-federation/runtime-core';
|
|
2
2
|
import type { Remote } from '@module-federation/runtime-core/dist/src/types';
|
|
3
|
-
import * as React from 'react';
|
|
4
3
|
export interface ExtraInfo {
|
|
5
4
|
external?: Record<string, string>;
|
|
6
5
|
legacy?: boolean;
|
|
@@ -19,69 +18,3 @@ export interface MicroMod {
|
|
|
19
18
|
moduleFederatedName: string;
|
|
20
19
|
extraInfo?: ExtraInfo;
|
|
21
20
|
}
|
|
22
|
-
export interface FederationRuntimePlugin {
|
|
23
|
-
name: string;
|
|
24
|
-
afterResolve?: (args: any) => any;
|
|
25
|
-
onLoad?: (args: any) => any;
|
|
26
|
-
beforeRequest?: (args: any) => any;
|
|
27
|
-
}
|
|
28
|
-
export interface WrapperContext {
|
|
29
|
-
remoteName: string;
|
|
30
|
-
moduleName: string;
|
|
31
|
-
props: Record<string, any>;
|
|
32
|
-
React: typeof import('react');
|
|
33
|
-
ReactDOM?: typeof import('react-dom');
|
|
34
|
-
}
|
|
35
|
-
export interface InjectionContext {
|
|
36
|
-
remoteName: string;
|
|
37
|
-
moduleName: string;
|
|
38
|
-
}
|
|
39
|
-
export interface ComponentWrapper {
|
|
40
|
-
(WrappedComponent: React.ComponentType<any>, context: WrapperContext): React.ComponentType<any>;
|
|
41
|
-
}
|
|
42
|
-
export interface PropInjector {
|
|
43
|
-
(props: Record<string, any>, context: InjectionContext): Record<string, any>;
|
|
44
|
-
}
|
|
45
|
-
export interface EnhancedRuntimePlugin {
|
|
46
|
-
name: string;
|
|
47
|
-
wrapComponent?: ComponentWrapper;
|
|
48
|
-
injectProps?: PropInjector;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Runtime Plugin 包装器对象的接口
|
|
52
|
-
* 包含原始组件和运行时信息,让 RemoteModule 控制 HOC 层级顺序
|
|
53
|
-
*/
|
|
54
|
-
export interface RuntimePluginWrapper {
|
|
55
|
-
readonly type: 'runtime-plugin-wrapper';
|
|
56
|
-
readonly originalComponent: React.ComponentType<any>;
|
|
57
|
-
readonly runtimeInfo: {
|
|
58
|
-
readonly remoteVersion?: string;
|
|
59
|
-
readonly hostVersion?: string;
|
|
60
|
-
readonly remoteReact: () => typeof import('react');
|
|
61
|
-
readonly remoteReactDOM: () => typeof import('react-dom');
|
|
62
|
-
readonly mountNode?: HTMLElement;
|
|
63
|
-
readonly containerClassName?: string;
|
|
64
|
-
};
|
|
65
|
-
readonly reactInstances: {
|
|
66
|
-
readonly react: typeof import('react');
|
|
67
|
-
readonly reactDOM?: typeof import('react-dom');
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* 类型守卫:检查是否为 Runtime Plugin 包装器
|
|
72
|
-
*/
|
|
73
|
-
export declare function isRuntimePluginWrapper(value: any): value is () => RuntimePluginWrapper;
|
|
74
|
-
/**
|
|
75
|
-
* 创建 Runtime Plugin 包装器的工厂函数
|
|
76
|
-
*/
|
|
77
|
-
export declare function createRuntimePluginWrapper(originalComponent: React.ComponentType<any>, runtimeInfo: {
|
|
78
|
-
remoteVersion?: string;
|
|
79
|
-
hostVersion?: string;
|
|
80
|
-
remoteReact: () => typeof import('react');
|
|
81
|
-
remoteReactDOM: () => typeof import('react-dom');
|
|
82
|
-
mountNode?: HTMLElement;
|
|
83
|
-
containerClassName?: string;
|
|
84
|
-
}, reactInstances: {
|
|
85
|
-
react: typeof import('react');
|
|
86
|
-
reactDOM?: typeof import('react-dom');
|
|
87
|
-
}): () => RuntimePluginWrapper;
|
package/es2017/types.js
CHANGED
|
@@ -1,18 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* 类型守卫:检查是否为 Runtime Plugin 包装器
|
|
4
|
-
*/ export function isRuntimePluginWrapper(value) {
|
|
5
|
-
return value && value.__mf_fallback_render;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* 创建 Runtime Plugin 包装器的工厂函数
|
|
9
|
-
*/ export function createRuntimePluginWrapper(originalComponent, runtimeInfo, reactInstances) {
|
|
10
|
-
const wrapper = ()=>({
|
|
11
|
-
type: 'runtime-plugin-wrapper',
|
|
12
|
-
originalComponent,
|
|
13
|
-
runtimeInfo,
|
|
14
|
-
reactInstances
|
|
15
|
-
});
|
|
16
|
-
wrapper.__mf_fallback_render = true;
|
|
17
|
-
return wrapper;
|
|
18
|
-
} // 不再需要联合类型,两种插件分开管理
|
|
1
|
+
export { };
|