@ice/mf-runtime 0.0.1 → 0.0.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 +218 -7
- package/es2017/index.js +2 -0
- package/esm/index.js +2 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,15 +1,226 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @ice/mf-runtime
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
基于 Module Federation 的运行时工具,用于在 ice.js 应用中加载和管理远程模块。支持跨版本 React 组件加载
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 基于 [Module Federation 2.0](https://module-federation.io/index.html)
|
|
8
|
+
- 支持跨版本 React 组件加载
|
|
9
|
+
- 内置冲突检测和降级渲染
|
|
10
|
+
|
|
11
|
+
## 安装
|
|
6
12
|
|
|
7
13
|
```bash
|
|
8
|
-
$ npm i @
|
|
14
|
+
$ npm i @ice/mf-runtime --save
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 使用
|
|
18
|
+
|
|
19
|
+
### 1. 初始化配置
|
|
20
|
+
|
|
21
|
+
在应用入口处初始化 Module Federation 配置:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { init } from '@ice/mf-runtime';
|
|
25
|
+
|
|
26
|
+
init({
|
|
27
|
+
name: 'host_app', // 当前应用名称
|
|
28
|
+
remotes: [
|
|
29
|
+
{
|
|
30
|
+
name: 'remote_app', // 远程应用名称
|
|
31
|
+
entry: 'http://localhost:3000/remoteEntry.js', // 远程应用入口文件,也支持新的 mf-manifest.json 结构
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
});
|
|
9
35
|
```
|
|
10
36
|
|
|
11
|
-
|
|
37
|
+
### 2. 加载远程模块
|
|
38
|
+
|
|
39
|
+
使用 `RemoteModule` 组件加载远程模块:
|
|
12
40
|
|
|
13
|
-
```
|
|
14
|
-
import
|
|
41
|
+
```tsx
|
|
42
|
+
import { RemoteModule } from '@ice/mf-runtime';
|
|
43
|
+
|
|
44
|
+
function App() {
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
<h1>Host Application</h1>
|
|
48
|
+
<RemoteModule
|
|
49
|
+
module="Widget" // 远程模块名称
|
|
50
|
+
scope="remote_app" // 远程应用名称
|
|
51
|
+
LoadingComponent={<div>Loading...</div>} // 可选的加载状态组件
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
15
56
|
```
|
|
57
|
+
|
|
58
|
+
### 3. 高级配置
|
|
59
|
+
|
|
60
|
+
#### 自定义 Public Path
|
|
61
|
+
|
|
62
|
+
如果远程模块的静态资源需要使用特定的 CDN 地址,可以通过 `publicPath` 属性指定:
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<RemoteModule
|
|
66
|
+
module="Widget"
|
|
67
|
+
scope="remote_app"
|
|
68
|
+
publicPath="https://cdn.example.com/remote-app/"
|
|
69
|
+
/>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### 远程模块高级配置
|
|
73
|
+
|
|
74
|
+
通过 `init` 方法的 `extraInfo` 配置,可以实现更多高级特性:
|
|
75
|
+
|
|
76
|
+
##### 类型定义
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
interface ExtraInfo {
|
|
80
|
+
// 配置外部依赖
|
|
81
|
+
external?: {
|
|
82
|
+
react?: string; // 外部 React 全局变量名
|
|
83
|
+
'react-dom'?: string; // 外部 ReactDOM 全局变量名
|
|
84
|
+
};
|
|
85
|
+
// 是否为旧版本模块(用于兼容性处理)
|
|
86
|
+
legacy?: boolean;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
##### 1. 使用外部依赖
|
|
91
|
+
|
|
92
|
+
当远程模块需要使用 CDN 加载的 React 时,可以通过 `external` 配置指定:
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
init({
|
|
96
|
+
name: 'host_app',
|
|
97
|
+
remotes: [
|
|
98
|
+
{
|
|
99
|
+
name: 'remote_app',
|
|
100
|
+
entry: 'http://localhost:3000/remoteEntry.js',
|
|
101
|
+
extraInfo: {
|
|
102
|
+
external: {
|
|
103
|
+
react: 'React', // 使用全局的 React
|
|
104
|
+
'react-dom': 'ReactDOM' // 使用全局的 ReactDOM
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
当使用模块的 host 应用没有启用 MF 规范时,你可能会遇到 React 多实例引起的问题,对于这类问题,推荐使用外部依赖配置来保证 host 应用和 remote 应用使用同一个环境的 React 实例。
|
|
113
|
+
|
|
114
|
+
此时需要保证环境中存在指定的全局 React。runtime 会自动处理全局多个 React 的兼容性,优先使用兼容的 React 版本渲染。
|
|
115
|
+
|
|
116
|
+
##### 2. 兼容旧版本模块
|
|
117
|
+
|
|
118
|
+
对于一些旧版本的远程模块,可能需要特殊的兼容性处理,此时可以启用 `legacy` 模式:
|
|
119
|
+
|
|
120
|
+
目前 legacy 模式下,会做以下处理:
|
|
121
|
+
1. 兼容 remote 模块 expose name 不以 `./` 开头的情况。
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
init({
|
|
125
|
+
name: 'host_app',
|
|
126
|
+
remotes: [
|
|
127
|
+
{
|
|
128
|
+
name: 'remote_app',
|
|
129
|
+
entry: 'http://localhost:3000/remoteEntry.js',
|
|
130
|
+
extraInfo: {
|
|
131
|
+
legacy: true // 启用兼容模式
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
##### 3. 混合配置示例
|
|
139
|
+
|
|
140
|
+
在实际项目中,可能需要同时配置多个远程模块,每个模块使用不同的配置:
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
init({
|
|
144
|
+
name: 'host_app',
|
|
145
|
+
remotes: [
|
|
146
|
+
{
|
|
147
|
+
name: 'remote_app',
|
|
148
|
+
entry: 'http://localhost:3000/remoteEntry.js',
|
|
149
|
+
extraInfo: {
|
|
150
|
+
external: {
|
|
151
|
+
react: 'React',
|
|
152
|
+
'react-dom': 'ReactDOM'
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: 'remote_app_2',
|
|
158
|
+
entry: 'http://localhost:3002/remoteEntry.js',
|
|
159
|
+
extraInfo: {
|
|
160
|
+
legacy: true
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### 为某个模块指定 React 版本渲染
|
|
168
|
+
|
|
169
|
+
当远程模块使用不同版本的 React 时,可以通过 `runtime` 属性指定运行时:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { RemoteModule } from '@ice/mf-runtime';
|
|
173
|
+
import * as React from 'react';
|
|
174
|
+
import * as ReactDOM from 'react-dom';
|
|
175
|
+
|
|
176
|
+
function App() {
|
|
177
|
+
return (
|
|
178
|
+
<RemoteModule
|
|
179
|
+
module="Widget"
|
|
180
|
+
scope="remote_app"
|
|
181
|
+
runtime={{
|
|
182
|
+
react: React,
|
|
183
|
+
reactDOM: ReactDOM
|
|
184
|
+
}}
|
|
185
|
+
/>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## API
|
|
191
|
+
|
|
192
|
+
### init(options)
|
|
193
|
+
|
|
194
|
+
初始化配置项:
|
|
195
|
+
|
|
196
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
197
|
+
|------|------|------|--------|
|
|
198
|
+
| name | 当前应用名称 | `string` | - |
|
|
199
|
+
| remotes | 远程应用配置数组 | `Array<RemoteConfig>` | `[]` |
|
|
200
|
+
|
|
201
|
+
RemoteConfig 配置:
|
|
202
|
+
|
|
203
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
204
|
+
|------|------|------|--------|
|
|
205
|
+
| name | 远程应用名称 | `string` | - |
|
|
206
|
+
| entry | 远程应用入口文件地址 | `string` | - |
|
|
207
|
+
| extraInfo | 额外配置信息,详见[远程模块高级配置](#远程模块高级配置) | `ExtraInfo` | - |
|
|
208
|
+
|
|
209
|
+
### RemoteModule
|
|
210
|
+
|
|
211
|
+
组件属性:
|
|
212
|
+
|
|
213
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
214
|
+
|------|------|------|--------|
|
|
215
|
+
| module | 远程模块名称 | `string` | - |
|
|
216
|
+
| scope | 远程应用名称 | `string` | - |
|
|
217
|
+
| runtime | React 运行时配置 | `{ react: React, reactDOM: ReactDOM }` | - |
|
|
218
|
+
| publicPath | 远程模块静态资源地址 | `string` | - |
|
|
219
|
+
| LoadingComponent | 加载状态组件 | `ReactNode` | `<div>Loading...</div>` |
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
## 注意事项
|
|
223
|
+
|
|
224
|
+
1. host name 请保证全局唯一。
|
|
225
|
+
2. remote name 的 package.json name 请保证全局唯一,否则会出现意料之外的缓存问题。
|
|
226
|
+
|
package/es2017/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { registerPlugins, init as mfInit } from '@module-federation/runtime';
|
|
2
2
|
import { runtimePlugin } from './runtime-plugin';
|
|
3
|
+
import { initGlobalStore } from './mf-global-store';
|
|
3
4
|
export { loadRemote, registerPlugins } from '@module-federation/runtime';
|
|
4
5
|
export * from './FallBack';
|
|
5
6
|
export * from './RemoteModule';
|
|
6
7
|
export function init(options) {
|
|
8
|
+
initGlobalStore(options);
|
|
7
9
|
mfInit(options);
|
|
8
10
|
registerPlugins([
|
|
9
11
|
runtimePlugin()
|
package/esm/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { registerPlugins, init as mfInit } from "@module-federation/runtime";
|
|
2
2
|
import { runtimePlugin } from "./runtime-plugin";
|
|
3
|
+
import { initGlobalStore } from "./mf-global-store";
|
|
3
4
|
export { loadRemote, registerPlugins } from "@module-federation/runtime";
|
|
4
5
|
export * from "./FallBack";
|
|
5
6
|
export * from "./RemoteModule";
|
|
6
7
|
export function init(options) {
|
|
8
|
+
initGlobalStore(options);
|
|
7
9
|
mfInit(options);
|
|
8
10
|
registerPlugins([
|
|
9
11
|
runtimePlugin()
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ice/mf-runtime",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "ice mf runtime",
|
|
5
5
|
"files": [
|
|
6
6
|
"esm",
|
|
7
7
|
"es2017",
|
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
"stylelint": "^15.0.0"
|
|
65
65
|
},
|
|
66
66
|
"publishConfig": {
|
|
67
|
-
"access": "public"
|
|
67
|
+
"access": "public",
|
|
68
|
+
"registry": "https://registry.npmjs.org"
|
|
68
69
|
},
|
|
69
70
|
"peerDependencies": {
|
|
70
71
|
"react": "^16 || ^17 || ^18"
|