@module-federation/bridge-react 0.0.0-next-20240822090000 → 0.0.0-next-20240823062237
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/CHANGELOG.md +16 -3
- package/__tests__/bridge.spec.tsx +37 -3
- package/dist/index.cjs.js +142 -112
- package/dist/index.d.ts +16 -15
- package/dist/index.es.js +144 -114
- package/dist/router-v5.cjs.js +56 -0
- package/dist/router-v5.d.ts +9 -0
- package/dist/router-v5.es.js +32 -0
- package/dist/router-v6.cjs.js +83 -0
- package/dist/router-v6.d.ts +11 -0
- package/dist/router-v6.es.js +60 -0
- package/dist/router.cjs.js +8 -12
- package/dist/router.es.js +8 -12
- package/package.json +12 -2
- package/src/create.tsx +21 -25
- package/src/provider.tsx +69 -64
- package/src/remote/index.tsx +93 -56
- package/src/router-v5.tsx +44 -0
- package/src/router-v6.tsx +73 -0
- package/src/router.tsx +8 -10
- package/vite.config.ts +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
# @module-federation/bridge-react
|
|
2
2
|
|
|
3
|
-
## 0.0.0-next-
|
|
3
|
+
## 0.0.0-next-20240823062237
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
|
|
7
|
+
- @module-federation/bridge-shared@0.0.0-next-20240823062237
|
|
8
|
+
|
|
9
|
+
## 0.5.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- @module-federation/bridge-shared@0.5.1
|
|
14
|
+
|
|
15
|
+
## 0.5.0
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 49d6135: feat(@module-federation/bridge): enhance Bridge capabilities and fix some issues
|
|
20
|
+
- Updated dependencies [49d6135]
|
|
21
|
+
- @module-federation/bridge-shared@0.5.0
|
|
9
22
|
|
|
10
23
|
## 0.4.0
|
|
11
24
|
|
|
@@ -45,8 +45,8 @@ describe('bridge', () => {
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
it('createRemoteComponent', async () => {
|
|
48
|
-
function Component(
|
|
49
|
-
return <div>life cycle render {
|
|
48
|
+
function Component({ props }: { props?: Record<string, any> }) {
|
|
49
|
+
return <div>life cycle render {props?.msg}</div>;
|
|
50
50
|
}
|
|
51
51
|
const BridgeComponent = createBridgeComponent({
|
|
52
52
|
rootComponent: Component,
|
|
@@ -61,11 +61,45 @@ describe('bridge', () => {
|
|
|
61
61
|
loading: <div>loading</div>,
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
const { container } = render(
|
|
64
|
+
const { container } = render(
|
|
65
|
+
<RemoteComponent props={{ msg: 'hello world' }} />,
|
|
66
|
+
);
|
|
67
|
+
expect(getHtml(container)).toMatch('loading');
|
|
68
|
+
|
|
69
|
+
await sleep(200);
|
|
70
|
+
expect(getHtml(container)).toMatch('life cycle render');
|
|
71
|
+
expect(getHtml(container)).toMatch('hello world');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('createRemoteComponent and obtain ref property', async () => {
|
|
75
|
+
const ref = {
|
|
76
|
+
current: null,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
function Component({ props }: { props?: Record<string, any> }) {
|
|
80
|
+
return <div>life cycle render {props?.msg}</div>;
|
|
81
|
+
}
|
|
82
|
+
const BridgeComponent = createBridgeComponent({
|
|
83
|
+
rootComponent: Component,
|
|
84
|
+
});
|
|
85
|
+
const RemoteComponent = createRemoteComponent({
|
|
86
|
+
loader: async () => {
|
|
87
|
+
return {
|
|
88
|
+
default: BridgeComponent,
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
fallback: () => <div></div>,
|
|
92
|
+
loading: <div>loading</div>,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const { container } = render(
|
|
96
|
+
<RemoteComponent ref={ref} props={{ msg: 'hello world' }} />,
|
|
97
|
+
);
|
|
65
98
|
expect(getHtml(container)).toMatch('loading');
|
|
66
99
|
|
|
67
100
|
await sleep(200);
|
|
68
101
|
expect(getHtml(container)).toMatch('life cycle render');
|
|
69
102
|
expect(getHtml(container)).toMatch('hello world');
|
|
103
|
+
expect(ref.current).not.toBeNull();
|
|
70
104
|
});
|
|
71
105
|
});
|
package/dist/index.cjs.js
CHANGED
|
@@ -117,55 +117,71 @@ function hasArrayChanged() {
|
|
|
117
117
|
let b = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [];
|
|
118
118
|
return a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));
|
|
119
119
|
}
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
`createRemoteComponent LazyComponent destroy >>>`,
|
|
155
|
-
{ name, basename, dom: renderDom.current }
|
|
156
|
-
);
|
|
157
|
-
(_b = providerInfoRef.current) == null ? void 0 : _b.destroy({
|
|
158
|
-
dom: renderDom.current
|
|
159
|
-
});
|
|
160
|
-
}
|
|
120
|
+
const RemoteAppWrapper = React.forwardRef(function(props, ref) {
|
|
121
|
+
const RemoteApp2 = () => {
|
|
122
|
+
context.LoggerInstance.log(`RemoteAppWrapper RemoteApp props >>>`, { props });
|
|
123
|
+
const {
|
|
124
|
+
moduleName,
|
|
125
|
+
memoryRoute,
|
|
126
|
+
basename,
|
|
127
|
+
providerInfo,
|
|
128
|
+
className,
|
|
129
|
+
style,
|
|
130
|
+
fallback,
|
|
131
|
+
...resProps
|
|
132
|
+
} = props;
|
|
133
|
+
const rootRef = ref && "current" in ref ? ref : React.useRef(null);
|
|
134
|
+
const renderDom = React.useRef(null);
|
|
135
|
+
const providerInfoRef = React.useRef(null);
|
|
136
|
+
React.useEffect(() => {
|
|
137
|
+
const renderTimeout = setTimeout(() => {
|
|
138
|
+
const providerReturn = providerInfo();
|
|
139
|
+
providerInfoRef.current = providerReturn;
|
|
140
|
+
const renderProps = {
|
|
141
|
+
moduleName,
|
|
142
|
+
dom: rootRef.current,
|
|
143
|
+
basename,
|
|
144
|
+
memoryRoute,
|
|
145
|
+
fallback,
|
|
146
|
+
...resProps
|
|
147
|
+
};
|
|
148
|
+
renderDom.current = rootRef.current;
|
|
149
|
+
context.LoggerInstance.log(
|
|
150
|
+
`createRemoteComponent LazyComponent render >>>`,
|
|
151
|
+
renderProps
|
|
152
|
+
);
|
|
153
|
+
providerReturn.render(renderProps);
|
|
161
154
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
155
|
+
return () => {
|
|
156
|
+
clearTimeout(renderTimeout);
|
|
157
|
+
setTimeout(() => {
|
|
158
|
+
var _a, _b;
|
|
159
|
+
if ((_a = providerInfoRef.current) == null ? void 0 : _a.destroy) {
|
|
160
|
+
context.LoggerInstance.log(
|
|
161
|
+
`createRemoteComponent LazyComponent destroy >>>`,
|
|
162
|
+
{ moduleName, basename, dom: renderDom.current }
|
|
163
|
+
);
|
|
164
|
+
(_b = providerInfoRef.current) == null ? void 0 : _b.destroy({
|
|
165
|
+
dom: renderDom.current
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
}, []);
|
|
171
|
+
return /* @__PURE__ */ React.createElement(
|
|
172
|
+
"div",
|
|
173
|
+
{
|
|
174
|
+
className: props == null ? void 0 : props.className,
|
|
175
|
+
style: props == null ? void 0 : props.style,
|
|
176
|
+
ref: rootRef
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
RemoteApp2["__APP_VERSION__"] = "0.5.1";
|
|
181
|
+
return /* @__PURE__ */ React.createElement(RemoteApp2, null);
|
|
182
|
+
});
|
|
167
183
|
function withRouterData(WrappedComponent) {
|
|
168
|
-
|
|
184
|
+
const Component = React.forwardRef(function(props, ref) {
|
|
169
185
|
var _a;
|
|
170
186
|
let enableDispathPopstate = false;
|
|
171
187
|
let routerContextVal;
|
|
@@ -223,10 +239,13 @@ function withRouterData(WrappedComponent) {
|
|
|
223
239
|
setPathname(location.pathname);
|
|
224
240
|
}, [location]);
|
|
225
241
|
}
|
|
226
|
-
return /* @__PURE__ */ React.createElement(WrappedComponent, { ...props, basename });
|
|
227
|
-
};
|
|
242
|
+
return /* @__PURE__ */ React.createElement(WrappedComponent, { ...props, basename, ref });
|
|
243
|
+
});
|
|
244
|
+
return React.forwardRef(function(props, ref) {
|
|
245
|
+
return /* @__PURE__ */ React.createElement(Component, { ...props, ref });
|
|
246
|
+
});
|
|
228
247
|
}
|
|
229
|
-
const RemoteApp
|
|
248
|
+
const RemoteApp = withRouterData(RemoteAppWrapper);
|
|
230
249
|
function createLazyRemoteComponent(info) {
|
|
231
250
|
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
232
251
|
return React.lazy(async () => {
|
|
@@ -243,13 +262,15 @@ function createLazyRemoteComponent(info) {
|
|
|
243
262
|
);
|
|
244
263
|
const exportFn = m2[exportName];
|
|
245
264
|
if (exportName in m2 && typeof exportFn === "function") {
|
|
246
|
-
const RemoteAppComponent = React.forwardRef((props,
|
|
265
|
+
const RemoteAppComponent = React.forwardRef((props, ref) => {
|
|
247
266
|
return /* @__PURE__ */ React.createElement(
|
|
248
|
-
RemoteApp
|
|
267
|
+
RemoteApp,
|
|
249
268
|
{
|
|
250
|
-
|
|
269
|
+
moduleName,
|
|
251
270
|
providerInfo: exportFn,
|
|
252
271
|
exportName: info.export || "default",
|
|
272
|
+
fallback: info.fallback,
|
|
273
|
+
ref,
|
|
253
274
|
...props
|
|
254
275
|
}
|
|
255
276
|
);
|
|
@@ -274,10 +295,12 @@ function createLazyRemoteComponent(info) {
|
|
|
274
295
|
});
|
|
275
296
|
}
|
|
276
297
|
function createRemoteComponent(info) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
298
|
+
return React.forwardRef(
|
|
299
|
+
(props, ref) => {
|
|
300
|
+
const LazyComponent = createLazyRemoteComponent(info);
|
|
301
|
+
return /* @__PURE__ */ React.createElement(ErrorBoundary, { FallbackComponent: info.fallback }, /* @__PURE__ */ React.createElement(React.Suspense, { fallback: info.loading }, /* @__PURE__ */ React.createElement(LazyComponent, { ...props, ref })));
|
|
302
|
+
}
|
|
303
|
+
);
|
|
281
304
|
}
|
|
282
305
|
var client = {};
|
|
283
306
|
var m = ReactDOM;
|
|
@@ -304,69 +327,76 @@ if (process.env.NODE_ENV === "production") {
|
|
|
304
327
|
};
|
|
305
328
|
}
|
|
306
329
|
function createBridgeComponent(bridgeInfo) {
|
|
307
|
-
let provider;
|
|
308
330
|
return () => {
|
|
309
331
|
const rootMap = /* @__PURE__ */ new Map();
|
|
310
332
|
const RawComponent = (info) => {
|
|
311
|
-
const { appInfo, propsInfo } = info;
|
|
312
|
-
const {
|
|
313
|
-
return /* @__PURE__ */ React__namespace.createElement(context.RouterContext.Provider, { value: {
|
|
333
|
+
const { appInfo, propsInfo, ...restProps } = info;
|
|
334
|
+
const { moduleName, memoryRoute, basename = "/" } = appInfo;
|
|
335
|
+
return /* @__PURE__ */ React__namespace.createElement(context.RouterContext.Provider, { value: { moduleName, basename, memoryRoute } }, /* @__PURE__ */ React__namespace.createElement(
|
|
336
|
+
bridgeInfo.rootComponent,
|
|
337
|
+
{
|
|
338
|
+
...propsInfo,
|
|
339
|
+
basename,
|
|
340
|
+
...restProps
|
|
341
|
+
}
|
|
342
|
+
));
|
|
314
343
|
};
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
render
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
344
|
+
return {
|
|
345
|
+
async render(info) {
|
|
346
|
+
context.LoggerInstance.log(`createBridgeComponent render Info`, info);
|
|
347
|
+
const {
|
|
348
|
+
moduleName,
|
|
349
|
+
dom,
|
|
350
|
+
basename,
|
|
351
|
+
memoryRoute,
|
|
352
|
+
fallback,
|
|
353
|
+
...propsInfo
|
|
354
|
+
} = info;
|
|
355
|
+
const rootComponentWithErrorBoundary = (
|
|
356
|
+
// set ErrorBoundary for RawComponent rendering error, usually caused by user app rendering error
|
|
357
|
+
/* @__PURE__ */ React__namespace.createElement(ErrorBoundary, { FallbackComponent: fallback }, /* @__PURE__ */ React__namespace.createElement(
|
|
358
|
+
RawComponent,
|
|
359
|
+
{
|
|
360
|
+
appInfo: {
|
|
361
|
+
moduleName,
|
|
362
|
+
basename,
|
|
363
|
+
memoryRoute
|
|
364
|
+
},
|
|
365
|
+
propsInfo
|
|
366
|
+
}
|
|
367
|
+
))
|
|
368
|
+
);
|
|
369
|
+
if (context.atLeastReact18(React__namespace)) {
|
|
370
|
+
if (bridgeInfo == null ? void 0 : bridgeInfo.render) {
|
|
371
|
+
Promise.resolve(
|
|
372
|
+
bridgeInfo == null ? void 0 : bridgeInfo.render(rootComponentWithErrorBoundary, dom)
|
|
373
|
+
).then((root) => rootMap.set(info.dom, root));
|
|
374
|
+
} else {
|
|
321
375
|
const root = client.createRoot(info.dom);
|
|
376
|
+
root.render(rootComponentWithErrorBoundary);
|
|
322
377
|
rootMap.set(info.dom, root);
|
|
323
|
-
root.render(
|
|
324
|
-
/* @__PURE__ */ React__namespace.createElement(
|
|
325
|
-
RawComponent,
|
|
326
|
-
{
|
|
327
|
-
propsInfo,
|
|
328
|
-
appInfo: {
|
|
329
|
-
name,
|
|
330
|
-
basename,
|
|
331
|
-
memoryRoute
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
)
|
|
335
|
-
);
|
|
336
|
-
} else {
|
|
337
|
-
ReactDOM.render(
|
|
338
|
-
/* @__PURE__ */ React__namespace.createElement(
|
|
339
|
-
RawComponent,
|
|
340
|
-
{
|
|
341
|
-
propsInfo,
|
|
342
|
-
appInfo: {
|
|
343
|
-
name,
|
|
344
|
-
basename,
|
|
345
|
-
memoryRoute
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
),
|
|
349
|
-
info.dom
|
|
350
|
-
);
|
|
351
378
|
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
dom: info.dom
|
|
356
|
-
});
|
|
357
|
-
if (context.atLeastReact18(React__namespace)) {
|
|
358
|
-
const root = rootMap.get(info.dom);
|
|
359
|
-
root == null ? void 0 : root.unmount();
|
|
360
|
-
} else {
|
|
361
|
-
ReactDOM.unmountComponentAtNode(info.dom);
|
|
362
|
-
}
|
|
363
|
-
},
|
|
364
|
-
rawComponent: bridgeInfo.rootComponent,
|
|
365
|
-
__BRIDGE_FN__: (_args) => {
|
|
379
|
+
} else {
|
|
380
|
+
const renderFn = (bridgeInfo == null ? void 0 : bridgeInfo.render) || ReactDOM.render;
|
|
381
|
+
renderFn == null ? void 0 : renderFn(rootComponentWithErrorBoundary, info.dom);
|
|
366
382
|
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
|
|
383
|
+
},
|
|
384
|
+
async destroy(info) {
|
|
385
|
+
context.LoggerInstance.log(`createBridgeComponent destroy Info`, {
|
|
386
|
+
dom: info.dom
|
|
387
|
+
});
|
|
388
|
+
if (context.atLeastReact18(React__namespace)) {
|
|
389
|
+
const root = rootMap.get(info.dom);
|
|
390
|
+
root == null ? void 0 : root.unmount();
|
|
391
|
+
rootMap.delete(info.dom);
|
|
392
|
+
} else {
|
|
393
|
+
ReactDOM.unmountComponentAtNode(info.dom);
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
rawComponent: bridgeInfo.rootComponent,
|
|
397
|
+
__BRIDGE_FN__: (_args) => {
|
|
398
|
+
}
|
|
399
|
+
};
|
|
370
400
|
};
|
|
371
401
|
}
|
|
372
402
|
exports.createBridgeComponent = createBridgeComponent;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
2
|
import { default as default_2 } from 'react';
|
|
3
|
+
import { default as default_3 } from 'react-dom/client';
|
|
3
4
|
import { ErrorInfo } from 'react';
|
|
4
5
|
import { PropsWithChildren } from 'react';
|
|
5
6
|
import * as React_2 from 'react';
|
|
6
7
|
|
|
7
|
-
export declare function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>): () =>
|
|
8
|
+
export declare function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>): () => {
|
|
9
|
+
render(info: RenderFnParams & any): Promise<void>;
|
|
10
|
+
destroy(info: {
|
|
11
|
+
dom: HTMLElement;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
rawComponent: React_2.ComponentType<T>;
|
|
14
|
+
__BRIDGE_FN__: (_args: T) => void;
|
|
15
|
+
};
|
|
8
16
|
|
|
9
17
|
export declare function createRemoteComponent<T, E extends keyof T>(info: {
|
|
10
18
|
loader: () => Promise<T>;
|
|
11
19
|
loading: default_2.ReactNode;
|
|
12
20
|
fallback: ErrorBoundaryPropsWithComponent['FallbackComponent'];
|
|
13
21
|
export?: E;
|
|
14
|
-
}): (
|
|
15
|
-
basename?: ProviderParams['basename'];
|
|
16
|
-
memoryRoute?: ProviderParams['memoryRoute'];
|
|
17
|
-
} & ("__BRIDGE_FN__" extends keyof (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never) ? (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"] extends (...args: any) => any ? Parameters<(T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"]>[0] : {} : {})) => default_2.JSX.Element;
|
|
22
|
+
}): default_2.ForwardRefExoticComponent<default_2.PropsWithoutRef<ProviderParams & ("__BRIDGE_FN__" extends keyof (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never) ? (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"] extends (...args: any) => any ? Parameters<(T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"]>[0] : {} : {})> & default_2.RefAttributes<HTMLDivElement>>;
|
|
18
23
|
|
|
19
24
|
declare type ErrorBoundaryPropsWithComponent = ErrorBoundarySharedProps & {
|
|
20
25
|
fallback?: never;
|
|
@@ -40,29 +45,25 @@ declare type FallbackProps = {
|
|
|
40
45
|
resetErrorBoundary: (...args: any[]) => void;
|
|
41
46
|
};
|
|
42
47
|
|
|
43
|
-
declare interface Provider<T> {
|
|
44
|
-
render(info: any): void;
|
|
45
|
-
destroy(info: {
|
|
46
|
-
dom: HTMLElement;
|
|
47
|
-
}): void;
|
|
48
|
-
rawComponent: React_2.ComponentType;
|
|
49
|
-
__BRIDGE_FN__: (_args: T) => void;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
48
|
declare type ProviderFnParams<T> = {
|
|
53
49
|
rootComponent: React_2.ComponentType<T>;
|
|
50
|
+
render?: (App: React_2.ReactElement, id?: HTMLElement | string) => RootType | Promise<RootType>;
|
|
54
51
|
};
|
|
55
52
|
|
|
56
53
|
export declare interface ProviderParams {
|
|
57
|
-
|
|
54
|
+
moduleName?: string;
|
|
58
55
|
basename?: string;
|
|
59
56
|
memoryRoute?: {
|
|
60
57
|
entryPath: string;
|
|
61
58
|
};
|
|
59
|
+
style?: React.CSSProperties;
|
|
60
|
+
className?: string;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
export declare interface RenderFnParams extends ProviderParams {
|
|
65
64
|
dom: HTMLElement;
|
|
66
65
|
}
|
|
67
66
|
|
|
67
|
+
declare type RootType = HTMLElement | default_3.Root;
|
|
68
|
+
|
|
68
69
|
export { }
|