@module-federation/bridge-react 0.0.0-next-20241021083129 → 0.0.0-next-20241021084851
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 +2 -5
- package/dist/index.cjs.js +18 -1074
- package/dist/index.d.ts +5 -19
- package/dist/index.es.js +18 -1074
- package/dist/router.cjs.js +1 -1
- package/dist/router.es.js +1 -1
- package/package.json +5 -6
- package/src/create.tsx +2 -2
- package/src/provider.tsx +8 -62
- package/src/remote/index.tsx +3 -50
- package/src/router-v5.tsx +1 -0
- package/src/router.tsx +1 -1
- package/src/lifecycle.ts +0 -28
package/dist/router.cjs.js
CHANGED
|
@@ -65,7 +65,7 @@ function WrapperRouterProvider(props) {
|
|
|
65
65
|
return /* @__PURE__ */ React.createElement(RouterProvider, { router: MemeoryRouterInstance });
|
|
66
66
|
} else {
|
|
67
67
|
const BrowserRouterInstance = createBrowserRouter(routers, {
|
|
68
|
-
basename: routerContextProps.basename
|
|
68
|
+
basename: routerContextProps.basename,
|
|
69
69
|
future: router.future,
|
|
70
70
|
window: router.window
|
|
71
71
|
});
|
package/dist/router.es.js
CHANGED
|
@@ -47,7 +47,7 @@ function WrapperRouterProvider(props) {
|
|
|
47
47
|
return /* @__PURE__ */ React__default.createElement(RouterProvider, { router: MemeoryRouterInstance });
|
|
48
48
|
} else {
|
|
49
49
|
const BrowserRouterInstance = createBrowserRouter(routers, {
|
|
50
|
-
basename: routerContextProps.basename
|
|
50
|
+
basename: routerContextProps.basename,
|
|
51
51
|
future: router.future,
|
|
52
52
|
window: router.window
|
|
53
53
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/bridge-react",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20241021084851",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,13 +35,12 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@loadable/component": "^5.16.4",
|
|
37
37
|
"react-error-boundary": "^4.0.13",
|
|
38
|
-
"@module-federation/bridge-shared": "0.0.0-next-
|
|
38
|
+
"@module-federation/bridge-shared": "0.0.0-next-20241021084851"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"react": ">=
|
|
42
|
-
"react-dom": ">=
|
|
43
|
-
"react-router-dom": ">=4"
|
|
44
|
-
"@module-federation/runtime": "0.0.0-next-20241021083129"
|
|
41
|
+
"react": ">=16.9.0",
|
|
42
|
+
"react-dom": ">=16.9.0",
|
|
43
|
+
"react-router-dom": ">=4"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
46
|
"@testing-library/react": "15.0.7",
|
package/src/create.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
|
+
import type { ProviderParams } from '@module-federation/bridge-shared';
|
|
3
|
+
import { LoggerInstance } from './utils';
|
|
2
4
|
import {
|
|
3
5
|
ErrorBoundary,
|
|
4
6
|
ErrorBoundaryPropsWithComponent,
|
|
5
7
|
} from 'react-error-boundary';
|
|
6
|
-
import { LoggerInstance } from './utils';
|
|
7
8
|
import RemoteApp from './remote';
|
|
8
|
-
import type { ProviderParams } from '@module-federation/bridge-shared';
|
|
9
9
|
|
|
10
10
|
export interface RenderFnParams extends ProviderParams {
|
|
11
11
|
dom?: any;
|
package/src/provider.tsx
CHANGED
|
@@ -2,37 +2,25 @@ import { useLayoutEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import ReactDOM from 'react-dom';
|
|
4
4
|
import ReactDOMClient from 'react-dom/client';
|
|
5
|
+
import { RouterContext } from './context';
|
|
5
6
|
import type {
|
|
6
7
|
ProviderParams,
|
|
7
8
|
RenderFnParams,
|
|
8
9
|
} from '@module-federation/bridge-shared';
|
|
9
|
-
import { ErrorBoundary } from 'react-error-boundary';
|
|
10
|
-
import { RouterContext } from './context';
|
|
11
10
|
import { LoggerInstance, atLeastReact18 } from './utils';
|
|
11
|
+
import { ErrorBoundary } from 'react-error-boundary';
|
|
12
12
|
|
|
13
|
-
type RenderParams = RenderFnParams & any;
|
|
14
|
-
type DestroyParams = {
|
|
15
|
-
dom: HTMLElement;
|
|
16
|
-
};
|
|
17
13
|
type RootType = HTMLElement | ReactDOMClient.Root;
|
|
18
|
-
|
|
19
|
-
type BridgeHooks = {
|
|
20
|
-
beforeBridgeRender?: (params: RenderFnParams) => any;
|
|
21
|
-
afterBridgeRender?: (params: RenderFnParams) => any;
|
|
22
|
-
beforeBridgeDestroy?: (params: DestroyParams) => any;
|
|
23
|
-
afterBridgeDestroy?: (params: DestroyParams) => any;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
14
|
type ProviderFnParams<T> = {
|
|
27
15
|
rootComponent: React.ComponentType<T>;
|
|
28
16
|
render?: (
|
|
29
17
|
App: React.ReactElement,
|
|
30
18
|
id?: HTMLElement | string,
|
|
31
19
|
) => RootType | Promise<RootType>;
|
|
32
|
-
hooks?: BridgeHooks;
|
|
33
20
|
};
|
|
21
|
+
|
|
34
22
|
export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
35
|
-
return (
|
|
23
|
+
return () => {
|
|
36
24
|
const rootMap = new Map<any, RootType>();
|
|
37
25
|
const RawComponent = (info: { propsInfo: T; appInfo: ProviderParams }) => {
|
|
38
26
|
const { appInfo, propsInfo, ...restProps } = info;
|
|
@@ -49,7 +37,7 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
|
49
37
|
};
|
|
50
38
|
|
|
51
39
|
return {
|
|
52
|
-
async render(info:
|
|
40
|
+
async render(info: RenderFnParams & any) {
|
|
53
41
|
LoggerInstance.log(`createBridgeComponent render Info`, info);
|
|
54
42
|
const {
|
|
55
43
|
moduleName,
|
|
@@ -59,21 +47,6 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
|
59
47
|
fallback,
|
|
60
48
|
...propsInfo
|
|
61
49
|
} = info;
|
|
62
|
-
|
|
63
|
-
const beforeBridgeRender =
|
|
64
|
-
(bridgeInfo?.hooks && bridgeInfo?.hooks.beforeBridgeRender) ||
|
|
65
|
-
params?.hooks?.beforeBridgeRender;
|
|
66
|
-
|
|
67
|
-
// 可通过beforeBridgeRender返回一个props对象,用于传递额外的 props 参数
|
|
68
|
-
const beforeBridgeRenderRes =
|
|
69
|
-
beforeBridgeRender && beforeBridgeRender(info);
|
|
70
|
-
const extraProps =
|
|
71
|
-
beforeBridgeRenderRes &&
|
|
72
|
-
typeof beforeBridgeRenderRes === 'object' &&
|
|
73
|
-
beforeBridgeRenderRes?.extraProps
|
|
74
|
-
? beforeBridgeRenderRes?.extraProps
|
|
75
|
-
: {};
|
|
76
|
-
|
|
77
50
|
const rootComponentWithErrorBoundary = (
|
|
78
51
|
// set ErrorBoundary for RawComponent rendering error, usually caused by user app rendering error
|
|
79
52
|
<ErrorBoundary FallbackComponent={fallback}>
|
|
@@ -83,11 +56,11 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
|
83
56
|
basename,
|
|
84
57
|
memoryRoute,
|
|
85
58
|
}}
|
|
86
|
-
propsInfo={
|
|
59
|
+
propsInfo={propsInfo}
|
|
87
60
|
/>
|
|
88
61
|
</ErrorBoundary>
|
|
89
62
|
);
|
|
90
|
-
|
|
63
|
+
|
|
91
64
|
if (atLeastReact18(React)) {
|
|
92
65
|
if (bridgeInfo?.render) {
|
|
93
66
|
// in case bridgeInfo?.render is an async function, resolve this to promise
|
|
@@ -104,33 +77,11 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
|
104
77
|
const renderFn = bridgeInfo?.render || ReactDOM.render;
|
|
105
78
|
renderFn?.(rootComponentWithErrorBoundary, info.dom);
|
|
106
79
|
}
|
|
107
|
-
|
|
108
|
-
const afterBridgeRender =
|
|
109
|
-
(bridgeInfo?.hooks && bridgeInfo?.hooks.afterBridgeDestroy) ||
|
|
110
|
-
params?.hooks?.afterBridgeRender;
|
|
111
|
-
afterBridgeRender && afterBridgeRender(info);
|
|
112
80
|
},
|
|
113
|
-
|
|
114
|
-
async destroy(info: DestroyParams) {
|
|
81
|
+
async destroy(info: { dom: HTMLElement }) {
|
|
115
82
|
LoggerInstance.log(`createBridgeComponent destroy Info`, {
|
|
116
83
|
dom: info.dom,
|
|
117
84
|
});
|
|
118
|
-
|
|
119
|
-
// call beforeBridgeDestroy hook
|
|
120
|
-
if (
|
|
121
|
-
bridgeInfo?.hooks &&
|
|
122
|
-
bridgeInfo?.hooks.beforeBridgeDestroy &&
|
|
123
|
-
typeof bridgeInfo?.hooks.beforeBridgeDestroy === 'function'
|
|
124
|
-
) {
|
|
125
|
-
bridgeInfo.hooks.beforeBridgeDestroy(info);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const beforeBridgeDestroy =
|
|
129
|
-
(bridgeInfo?.hooks && bridgeInfo?.hooks.beforeBridgeDestroy) ||
|
|
130
|
-
params?.hooks?.beforeBridgeDestroy;
|
|
131
|
-
beforeBridgeDestroy && beforeBridgeDestroy(info);
|
|
132
|
-
|
|
133
|
-
// call destroy function
|
|
134
85
|
if (atLeastReact18(React)) {
|
|
135
86
|
const root = rootMap.get(info.dom);
|
|
136
87
|
(root as ReactDOMClient.Root)?.unmount();
|
|
@@ -138,11 +89,6 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
|
138
89
|
} else {
|
|
139
90
|
ReactDOM.unmountComponentAtNode(info.dom);
|
|
140
91
|
}
|
|
141
|
-
|
|
142
|
-
const afterBridgeDestroy =
|
|
143
|
-
(bridgeInfo?.hooks && bridgeInfo?.hooks.afterBridgeDestroy) ||
|
|
144
|
-
params?.hooks?.afterBridgeDestroy;
|
|
145
|
-
afterBridgeDestroy && afterBridgeDestroy(info);
|
|
146
92
|
},
|
|
147
93
|
rawComponent: bridgeInfo.rootComponent,
|
|
148
94
|
__BRIDGE_FN__: (_args: T) => {},
|
package/src/remote/index.tsx
CHANGED
|
@@ -7,25 +7,9 @@ import React, {
|
|
|
7
7
|
} from 'react';
|
|
8
8
|
import * as ReactRouterDOM from 'react-router-dom';
|
|
9
9
|
import type { ProviderParams } from '@module-federation/bridge-shared';
|
|
10
|
+
import { LoggerInstance, pathJoin } from '../utils';
|
|
10
11
|
import { dispatchPopstateEnv } from '@module-federation/bridge-shared';
|
|
11
12
|
import { ErrorBoundaryPropsWithComponent } from 'react-error-boundary';
|
|
12
|
-
import { registerBridgeLifeCycle } from '../lifecycle';
|
|
13
|
-
import { LoggerInstance, pathJoin } from '../utils';
|
|
14
|
-
|
|
15
|
-
export const getModuleName = (id: string) => {
|
|
16
|
-
// separate module name without detailed module path
|
|
17
|
-
// @vmok-e2e/edenx-demo-app2/button -> @vmok-e2e/edenx-demo-app2
|
|
18
|
-
const idArray = id.split('/');
|
|
19
|
-
if (idArray.length < 2) {
|
|
20
|
-
return id;
|
|
21
|
-
}
|
|
22
|
-
return idArray[0] + '/' + idArray[1];
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const getRootDomDefaultClassName = (moduleName: string) => {
|
|
26
|
-
const name = getModuleName(moduleName).replace(/\@/, '').replace(/\//, '-');
|
|
27
|
-
return `bridge-root-component-${name}`;
|
|
28
|
-
};
|
|
29
13
|
|
|
30
14
|
declare const __APP_VERSION__: string;
|
|
31
15
|
export interface RenderFnParams extends ProviderParams {
|
|
@@ -55,7 +39,6 @@ const RemoteAppWrapper = forwardRef(function (
|
|
|
55
39
|
props: RemoteAppParams & RenderFnParams,
|
|
56
40
|
ref,
|
|
57
41
|
) {
|
|
58
|
-
const bridgeHook = registerBridgeLifeCycle();
|
|
59
42
|
const RemoteApp = () => {
|
|
60
43
|
LoggerInstance.log(`RemoteAppWrapper RemoteApp props >>>`, { props });
|
|
61
44
|
const {
|
|
@@ -82,7 +65,7 @@ const RemoteAppWrapper = forwardRef(function (
|
|
|
82
65
|
const providerReturn = providerInfo();
|
|
83
66
|
providerInfoRef.current = providerReturn;
|
|
84
67
|
|
|
85
|
-
|
|
68
|
+
const renderProps = {
|
|
86
69
|
moduleName,
|
|
87
70
|
dom: rootRef.current,
|
|
88
71
|
basename,
|
|
@@ -95,24 +78,6 @@ const RemoteAppWrapper = forwardRef(function (
|
|
|
95
78
|
`createRemoteComponent LazyComponent render >>>`,
|
|
96
79
|
renderProps,
|
|
97
80
|
);
|
|
98
|
-
|
|
99
|
-
if (bridgeHook && bridgeHook?.lifecycle?.beforeBridgeRender) {
|
|
100
|
-
const beforeBridgeRenderRes =
|
|
101
|
-
bridgeHook?.lifecycle?.beforeBridgeRender.emit({
|
|
102
|
-
...renderProps,
|
|
103
|
-
});
|
|
104
|
-
const extraProps =
|
|
105
|
-
beforeBridgeRenderRes &&
|
|
106
|
-
typeof beforeBridgeRenderRes === 'object' &&
|
|
107
|
-
beforeBridgeRenderRes?.extraProps
|
|
108
|
-
? beforeBridgeRenderRes?.extraProps
|
|
109
|
-
: {};
|
|
110
|
-
|
|
111
|
-
renderProps = {
|
|
112
|
-
...renderProps,
|
|
113
|
-
...extraProps,
|
|
114
|
-
} as any;
|
|
115
|
-
}
|
|
116
81
|
providerReturn.render(renderProps);
|
|
117
82
|
});
|
|
118
83
|
|
|
@@ -124,16 +89,6 @@ const RemoteAppWrapper = forwardRef(function (
|
|
|
124
89
|
`createRemoteComponent LazyComponent destroy >>>`,
|
|
125
90
|
{ moduleName, basename, dom: renderDom.current },
|
|
126
91
|
);
|
|
127
|
-
if (bridgeHook && bridgeHook?.lifecycle?.afterBridgeDestroy) {
|
|
128
|
-
bridgeHook?.lifecycle?.afterBridgeDestroy.emit({
|
|
129
|
-
moduleName,
|
|
130
|
-
dom: renderDom.current,
|
|
131
|
-
basename,
|
|
132
|
-
memoryRoute,
|
|
133
|
-
fallback,
|
|
134
|
-
...resProps,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
92
|
providerInfoRef.current?.destroy({
|
|
138
93
|
dom: renderDom.current,
|
|
139
94
|
});
|
|
@@ -142,11 +97,9 @@ const RemoteAppWrapper = forwardRef(function (
|
|
|
142
97
|
};
|
|
143
98
|
}, []);
|
|
144
99
|
|
|
145
|
-
// bridge-remote-root
|
|
146
|
-
const rootComponentClassName = `${getRootDomDefaultClassName(moduleName)} ${props?.className}`;
|
|
147
100
|
return (
|
|
148
101
|
<div
|
|
149
|
-
className={
|
|
102
|
+
className={props?.className}
|
|
150
103
|
style={props?.style}
|
|
151
104
|
ref={rootRef}
|
|
152
105
|
></div>
|
package/src/router-v5.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import React, { useContext } from 'react';
|
|
|
2
2
|
// The upper alias react-router-dom$ into this file avoids the loop
|
|
3
3
|
// @ts-ignore
|
|
4
4
|
import * as ReactRouterDom from 'react-router-dom/index.js';
|
|
5
|
+
|
|
5
6
|
import { RouterContext } from './context';
|
|
6
7
|
import { LoggerInstance } from './utils';
|
|
7
8
|
|
package/src/router.tsx
CHANGED
|
@@ -59,7 +59,7 @@ function WrapperRouterProvider(
|
|
|
59
59
|
return <RouterProvider router={MemeoryRouterInstance} />;
|
|
60
60
|
} else {
|
|
61
61
|
const BrowserRouterInstance = createBrowserRouter(routers, {
|
|
62
|
-
basename: routerContextProps.basename
|
|
62
|
+
basename: routerContextProps.basename,
|
|
63
63
|
future: router.future,
|
|
64
64
|
window: router.window,
|
|
65
65
|
});
|
package/src/lifecycle.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { getInstance } from '@module-federation/runtime';
|
|
2
|
-
import helper from '@module-federation/runtime/helpers';
|
|
3
|
-
|
|
4
|
-
function registerBridgeLifeCycle() {
|
|
5
|
-
const { registerPlugins, pluginHelper } = helper.global;
|
|
6
|
-
const host = getInstance();
|
|
7
|
-
const pluginSystem = new pluginHelper.PluginSystem({
|
|
8
|
-
beforeBridgeRender: new pluginHelper.SyncHook<[Record<string, any>], any>(),
|
|
9
|
-
afterBridgeRender: new pluginHelper.SyncHook<[Record<string, any>], any>(),
|
|
10
|
-
beforeBridgeDestroy: new pluginHelper.SyncHook<
|
|
11
|
-
[Record<string, any>],
|
|
12
|
-
any
|
|
13
|
-
>(),
|
|
14
|
-
afterBridgeDestroy: new pluginHelper.SyncHook<[Record<string, any>], any>(),
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
if (host) {
|
|
18
|
-
registerPlugins<typeof pluginSystem.lifecycle, typeof pluginSystem>(
|
|
19
|
-
host?.options?.plugins,
|
|
20
|
-
[pluginSystem],
|
|
21
|
-
);
|
|
22
|
-
return pluginSystem;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { registerBridgeLifeCycle };
|