@module-federation/bridge-react 0.3.5 → 0.5.0

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/dist/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- import React__default, { createContext, Component, createElement, isValidElement, useContext, useState, useEffect, useRef, forwardRef } from "react";
3
- import { p as pathJoin, L as LoggerInstance, f, a as atLeastReact18, R as RouterContext } from "./context-Bw2PEwa6.js";
2
+ import React__default, { createContext, Component, createElement, isValidElement, forwardRef, useRef, useEffect, useContext, useState } from "react";
3
+ import { L as LoggerInstance, p as pathJoin, f, a as atLeastReact18, R as RouterContext } from "./context-Bw2PEwa6.js";
4
4
  import * as ReactRouterDOM from "react-router-dom";
5
5
  import ReactDOM from "react-dom";
6
6
  const ErrorBoundaryContext = createContext(null);
@@ -98,55 +98,71 @@ function hasArrayChanged() {
98
98
  let b = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [];
99
99
  return a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));
100
100
  }
101
- const RemoteApp = ({
102
- name,
103
- memoryRoute,
104
- basename,
105
- providerInfo,
106
- ...resProps
107
- }) => {
108
- const rootRef = useRef(null);
109
- const renderDom = useRef(null);
110
- const providerInfoRef = useRef(null);
111
- useEffect(() => {
112
- const renderTimeout = setTimeout(() => {
113
- const providerReturn = providerInfo();
114
- providerInfoRef.current = providerReturn;
115
- const renderProps = {
116
- name,
117
- dom: rootRef.current,
118
- basename,
119
- memoryRoute,
120
- ...resProps
121
- };
122
- renderDom.current = rootRef.current;
123
- LoggerInstance.log(
124
- `createRemoteComponent LazyComponent render >>>`,
125
- renderProps
126
- );
127
- providerReturn.render(renderProps);
128
- });
129
- return () => {
130
- clearTimeout(renderTimeout);
131
- setTimeout(() => {
132
- var _a, _b;
133
- if ((_a = providerInfoRef.current) == null ? void 0 : _a.destroy) {
134
- LoggerInstance.log(
135
- `createRemoteComponent LazyComponent destroy >>>`,
136
- { name, basename, dom: renderDom.current }
137
- );
138
- (_b = providerInfoRef.current) == null ? void 0 : _b.destroy({
139
- dom: renderDom.current
140
- });
141
- }
101
+ const RemoteAppWrapper = forwardRef(function(props, ref) {
102
+ const RemoteApp2 = () => {
103
+ LoggerInstance.log(`RemoteAppWrapper RemoteApp props >>>`, { props });
104
+ const {
105
+ moduleName,
106
+ memoryRoute,
107
+ basename,
108
+ providerInfo,
109
+ className,
110
+ style,
111
+ fallback,
112
+ ...resProps
113
+ } = props;
114
+ const rootRef = ref && "current" in ref ? ref : useRef(null);
115
+ const renderDom = useRef(null);
116
+ const providerInfoRef = useRef(null);
117
+ useEffect(() => {
118
+ const renderTimeout = setTimeout(() => {
119
+ const providerReturn = providerInfo();
120
+ providerInfoRef.current = providerReturn;
121
+ const renderProps = {
122
+ moduleName,
123
+ dom: rootRef.current,
124
+ basename,
125
+ memoryRoute,
126
+ fallback,
127
+ ...resProps
128
+ };
129
+ renderDom.current = rootRef.current;
130
+ LoggerInstance.log(
131
+ `createRemoteComponent LazyComponent render >>>`,
132
+ renderProps
133
+ );
134
+ providerReturn.render(renderProps);
142
135
  });
143
- };
144
- }, []);
145
- return /* @__PURE__ */ React__default.createElement("div", { ref: rootRef });
146
- };
147
- RemoteApp["__APP_VERSION__"] = "0.3.5";
136
+ return () => {
137
+ clearTimeout(renderTimeout);
138
+ setTimeout(() => {
139
+ var _a, _b;
140
+ if ((_a = providerInfoRef.current) == null ? void 0 : _a.destroy) {
141
+ LoggerInstance.log(
142
+ `createRemoteComponent LazyComponent destroy >>>`,
143
+ { moduleName, basename, dom: renderDom.current }
144
+ );
145
+ (_b = providerInfoRef.current) == null ? void 0 : _b.destroy({
146
+ dom: renderDom.current
147
+ });
148
+ }
149
+ });
150
+ };
151
+ }, []);
152
+ return /* @__PURE__ */ React__default.createElement(
153
+ "div",
154
+ {
155
+ className: props == null ? void 0 : props.className,
156
+ style: props == null ? void 0 : props.style,
157
+ ref: rootRef
158
+ }
159
+ );
160
+ };
161
+ RemoteApp2["__APP_VERSION__"] = "0.5.0";
162
+ return /* @__PURE__ */ React__default.createElement(RemoteApp2, null);
163
+ });
148
164
  function withRouterData(WrappedComponent) {
149
- return (props) => {
165
+ const Component2 = forwardRef(function(props, ref) {
150
166
  var _a;
151
167
  let enableDispathPopstate = false;
152
168
  let routerContextVal;
@@ -204,10 +220,13 @@ function withRouterData(WrappedComponent) {
204
220
  setPathname(location.pathname);
205
221
  }, [location]);
206
222
  }
207
- return /* @__PURE__ */ React__default.createElement(WrappedComponent, { ...props, basename });
208
- };
223
+ return /* @__PURE__ */ React__default.createElement(WrappedComponent, { ...props, basename, ref });
224
+ });
225
+ return forwardRef(function(props, ref) {
226
+ return /* @__PURE__ */ React__default.createElement(Component2, { ...props, ref });
227
+ });
209
228
  }
210
- const RemoteApp$1 = withRouterData(RemoteApp);
229
+ const RemoteApp = withRouterData(RemoteAppWrapper);
211
230
  function createLazyRemoteComponent(info) {
212
231
  const exportName = (info == null ? void 0 : info.export) || "default";
213
232
  return React__default.lazy(async () => {
@@ -224,13 +243,15 @@ function createLazyRemoteComponent(info) {
224
243
  );
225
244
  const exportFn = m2[exportName];
226
245
  if (exportName in m2 && typeof exportFn === "function") {
227
- const RemoteAppComponent = forwardRef((props, _ref) => {
246
+ const RemoteAppComponent = forwardRef((props, ref) => {
228
247
  return /* @__PURE__ */ React__default.createElement(
229
- RemoteApp$1,
248
+ RemoteApp,
230
249
  {
231
- name: moduleName,
250
+ moduleName,
232
251
  providerInfo: exportFn,
233
252
  exportName: info.export || "default",
253
+ fallback: info.fallback,
254
+ ref,
234
255
  ...props
235
256
  }
236
257
  );
@@ -255,10 +276,13 @@ function createLazyRemoteComponent(info) {
255
276
  });
256
277
  }
257
278
  function createRemoteComponent(info) {
258
- const LazyComponent = createLazyRemoteComponent(info);
259
- return (props) => {
260
- return /* @__PURE__ */ React__default.createElement(ErrorBoundary, { FallbackComponent: info.fallback }, /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: info.loading }, /* @__PURE__ */ React__default.createElement(LazyComponent, { ...props })));
261
- };
279
+ return forwardRef((props, ref) => {
280
+ const LazyComponent = createLazyRemoteComponent(info);
281
+ return (
282
+ // set ErrorBoundary for LazyComponent rendering error, usually caused by inner bridge logic render process
283
+ /* @__PURE__ */ React__default.createElement(ErrorBoundary, { FallbackComponent: info.fallback }, /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: info.loading }, /* @__PURE__ */ React__default.createElement(LazyComponent, { ...props, ref })))
284
+ );
285
+ });
262
286
  }
263
287
  var client = {};
264
288
  var m = ReactDOM;
@@ -288,54 +312,65 @@ function createBridgeComponent(bridgeInfo) {
288
312
  return () => {
289
313
  const rootMap = /* @__PURE__ */ new Map();
290
314
  const RawComponent = (info) => {
291
- const { appInfo, propsInfo } = info;
292
- const { name, memoryRoute, basename = "/" } = appInfo;
293
- return /* @__PURE__ */ React.createElement(RouterContext.Provider, { value: { name, basename, memoryRoute } }, /* @__PURE__ */ React.createElement(bridgeInfo.rootComponent, { ...propsInfo, basename }));
315
+ const { appInfo, propsInfo, ...restProps } = info;
316
+ const { moduleName, memoryRoute, basename = "/" } = appInfo;
317
+ return /* @__PURE__ */ React.createElement(RouterContext.Provider, { value: { moduleName, basename, memoryRoute } }, /* @__PURE__ */ React.createElement(
318
+ bridgeInfo.rootComponent,
319
+ {
320
+ ...propsInfo,
321
+ basename,
322
+ ...restProps
323
+ }
324
+ ));
294
325
  };
295
326
  return {
296
- render(info) {
327
+ async render(info) {
297
328
  LoggerInstance.log(`createBridgeComponent render Info`, info);
298
- const { name, basename, memoryRoute, ...propsInfo } = info;
329
+ const {
330
+ moduleName,
331
+ dom,
332
+ basename,
333
+ memoryRoute,
334
+ fallback,
335
+ ...propsInfo
336
+ } = info;
337
+ const rootComponentWithErrorBoundary = (
338
+ // set ErrorBoundary for RawComponent rendering error, usually caused by user app rendering error
339
+ /* @__PURE__ */ React.createElement(ErrorBoundary, { FallbackComponent: fallback }, /* @__PURE__ */ React.createElement(
340
+ RawComponent,
341
+ {
342
+ appInfo: {
343
+ moduleName,
344
+ basename,
345
+ memoryRoute
346
+ },
347
+ propsInfo
348
+ }
349
+ ))
350
+ );
299
351
  if (atLeastReact18(React)) {
300
- const root = client.createRoot(info.dom);
301
- rootMap.set(info.dom, root);
302
- root.render(
303
- /* @__PURE__ */ React.createElement(
304
- RawComponent,
305
- {
306
- propsInfo,
307
- appInfo: {
308
- name,
309
- basename,
310
- memoryRoute
311
- }
312
- }
313
- )
314
- );
352
+ if (bridgeInfo == null ? void 0 : bridgeInfo.render) {
353
+ Promise.resolve(
354
+ bridgeInfo == null ? void 0 : bridgeInfo.render(rootComponentWithErrorBoundary, dom)
355
+ ).then((root) => rootMap.set(info.dom, root));
356
+ } else {
357
+ const root = client.createRoot(info.dom);
358
+ root.render(rootComponentWithErrorBoundary);
359
+ rootMap.set(info.dom, root);
360
+ }
315
361
  } else {
316
- ReactDOM.render(
317
- /* @__PURE__ */ React.createElement(
318
- RawComponent,
319
- {
320
- propsInfo,
321
- appInfo: {
322
- name,
323
- basename,
324
- memoryRoute
325
- }
326
- }
327
- ),
328
- info.dom
329
- );
362
+ const renderFn = (bridgeInfo == null ? void 0 : bridgeInfo.render) || ReactDOM.render;
363
+ renderFn == null ? void 0 : renderFn(rootComponentWithErrorBoundary, info.dom);
330
364
  }
331
365
  },
332
- destroy(info) {
366
+ async destroy(info) {
333
367
  LoggerInstance.log(`createBridgeComponent destroy Info`, {
334
368
  dom: info.dom
335
369
  });
336
370
  if (atLeastReact18(React)) {
337
371
  const root = rootMap.get(info.dom);
338
372
  root == null ? void 0 : root.unmount();
373
+ rootMap.delete(info.dom);
339
374
  } else {
340
375
  ReactDOM.unmountComponentAtNode(info.dom);
341
376
  }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("react");
4
+ const ReactRouterDom = require("react-router-dom/index.js");
5
+ require("./context--mtFt3tp.cjs");
6
+ const router = require("./router.cjs.js");
7
+ exports.BrowserRouter = router.BrowserRouter;
8
+ exports.RouterProvider = router.RouterProvider;
9
+ Object.keys(ReactRouterDom).forEach((k) => {
10
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k))
11
+ Object.defineProperty(exports, k, {
12
+ enumerable: true,
13
+ get: () => ReactRouterDom[k]
14
+ });
15
+ });
@@ -0,0 +1,11 @@
1
+ import { default as default_2 } from 'react';
2
+ import * as ReactRouterDom from 'react-router-dom/';
3
+
4
+ export declare function BrowserRouter(props: Parameters<typeof ReactRouterDom.BrowserRouter>[0] | Parameters<typeof ReactRouterDom.MemoryRouter>[0]): default_2.JSX.Element;
5
+
6
+ export declare function RouterProvider(props: Parameters<typeof ReactRouterDom.RouterProvider>[0]): default_2.JSX.Element;
7
+
8
+
9
+ export * from "react-router-dom/";
10
+
11
+ export { }
@@ -0,0 +1,8 @@
1
+ import "react";
2
+ export * from "react-router-dom/index.js";
3
+ import "./context-Bw2PEwa6.js";
4
+ import { BrowserRouter, RouterProvider } from "./router.es.js";
5
+ export {
6
+ BrowserRouter,
7
+ RouterProvider
8
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("react");
4
+ const ReactRouterDom = require("react-router-dom/dist/index.js");
5
+ require("./context--mtFt3tp.cjs");
6
+ const router = require("./router.cjs.js");
7
+ exports.BrowserRouter = router.BrowserRouter;
8
+ exports.RouterProvider = router.RouterProvider;
9
+ Object.keys(ReactRouterDom).forEach((k) => {
10
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k))
11
+ Object.defineProperty(exports, k, {
12
+ enumerable: true,
13
+ get: () => ReactRouterDom[k]
14
+ });
15
+ });
@@ -0,0 +1,11 @@
1
+ import { default as default_2 } from 'react';
2
+ import * as ReactRouterDom from 'react-router-dom/';
3
+
4
+ export declare function BrowserRouter(props: Parameters<typeof ReactRouterDom.BrowserRouter>[0] | Parameters<typeof ReactRouterDom.MemoryRouter>[0]): default_2.JSX.Element;
5
+
6
+ export declare function RouterProvider(props: Parameters<typeof ReactRouterDom.RouterProvider>[0]): default_2.JSX.Element;
7
+
8
+
9
+ export * from "react-router-dom/";
10
+
11
+ export { }
@@ -0,0 +1,8 @@
1
+ import "react";
2
+ export * from "react-router-dom/dist/index.js";
3
+ import "./context-Bw2PEwa6.js";
4
+ import { BrowserRouter, RouterProvider } from "./router.es.js";
5
+ export {
6
+ BrowserRouter,
7
+ RouterProvider
8
+ };
@@ -20,16 +20,14 @@ function _interopNamespaceDefault(e) {
20
20
  return Object.freeze(n);
21
21
  }
22
22
  const ReactRouterDom__namespace = /* @__PURE__ */ _interopNamespaceDefault(ReactRouterDom);
23
- function WraperRouter(props) {
23
+ function WrapperRouter(props) {
24
24
  const { basename, ...propsRes } = props;
25
25
  const routerContextProps = React.useContext(context.RouterContext) || {};
26
- context.LoggerInstance.log(`WraperRouter info >>>`, {
26
+ context.LoggerInstance.log(`WrapperRouter info >>>`, {
27
27
  ...routerContextProps,
28
28
  routerContextProps,
29
- WraperRouterProps: props
29
+ WrapperRouterProps: props
30
30
  });
31
- if (!routerContextProps)
32
- return /* @__PURE__ */ React.createElement(ReactRouterDom__namespace.BrowserRouter, { ...props });
33
31
  if (routerContextProps == null ? void 0 : routerContextProps.memoryRoute) {
34
32
  return /* @__PURE__ */ React.createElement(
35
33
  ReactRouterDom__namespace.MemoryRouter,
@@ -47,21 +45,19 @@ function WraperRouter(props) {
47
45
  }
48
46
  );
49
47
  }
50
- function WraperRouterProvider(props) {
48
+ function WrapperRouterProvider(props) {
51
49
  const { router, ...propsRes } = props;
52
50
  const routerContextProps = React.useContext(context.RouterContext) || {};
53
51
  const routers = router.routes;
54
- context.LoggerInstance.log(`WraperRouterProvider info >>>`, {
52
+ context.LoggerInstance.log(`WrapperRouterProvider info >>>`, {
55
53
  ...routerContextProps,
56
54
  routerContextProps,
57
- WraperRouterProviderProps: props,
55
+ WrapperRouterProviderProps: props,
58
56
  router
59
57
  });
60
58
  const RouterProvider = ReactRouterDom__namespace["RouterProvider"];
61
59
  const createMemoryRouter = ReactRouterDom__namespace["createMemoryRouter"];
62
60
  const createBrowserRouter = ReactRouterDom__namespace["createBrowserRouter"];
63
- if (!routerContextProps)
64
- return /* @__PURE__ */ React.createElement(RouterProvider, { ...props });
65
61
  if (routerContextProps.memoryRoute) {
66
62
  const MemeoryRouterInstance = createMemoryRouter(routers, {
67
63
  initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
@@ -76,8 +72,8 @@ function WraperRouterProvider(props) {
76
72
  return /* @__PURE__ */ React.createElement(RouterProvider, { ...propsRes, router: BrowserRouterInstance });
77
73
  }
78
74
  }
79
- exports.BrowserRouter = WraperRouter;
80
- exports.RouterProvider = WraperRouterProvider;
75
+ exports.BrowserRouter = WrapperRouter;
76
+ exports.RouterProvider = WrapperRouterProvider;
81
77
  Object.keys(ReactRouterDom).forEach((k) => {
82
78
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k))
83
79
  Object.defineProperty(exports, k, {
package/dist/router.es.js CHANGED
@@ -2,16 +2,14 @@ import React__default, { useContext } from "react";
2
2
  import * as ReactRouterDom from "react-router-dom/";
3
3
  export * from "react-router-dom/";
4
4
  import { R as RouterContext, L as LoggerInstance } from "./context-Bw2PEwa6.js";
5
- function WraperRouter(props) {
5
+ function WrapperRouter(props) {
6
6
  const { basename, ...propsRes } = props;
7
7
  const routerContextProps = useContext(RouterContext) || {};
8
- LoggerInstance.log(`WraperRouter info >>>`, {
8
+ LoggerInstance.log(`WrapperRouter info >>>`, {
9
9
  ...routerContextProps,
10
10
  routerContextProps,
11
- WraperRouterProps: props
11
+ WrapperRouterProps: props
12
12
  });
13
- if (!routerContextProps)
14
- return /* @__PURE__ */ React__default.createElement(ReactRouterDom.BrowserRouter, { ...props });
15
13
  if (routerContextProps == null ? void 0 : routerContextProps.memoryRoute) {
16
14
  return /* @__PURE__ */ React__default.createElement(
17
15
  ReactRouterDom.MemoryRouter,
@@ -29,21 +27,19 @@ function WraperRouter(props) {
29
27
  }
30
28
  );
31
29
  }
32
- function WraperRouterProvider(props) {
30
+ function WrapperRouterProvider(props) {
33
31
  const { router, ...propsRes } = props;
34
32
  const routerContextProps = useContext(RouterContext) || {};
35
33
  const routers = router.routes;
36
- LoggerInstance.log(`WraperRouterProvider info >>>`, {
34
+ LoggerInstance.log(`WrapperRouterProvider info >>>`, {
37
35
  ...routerContextProps,
38
36
  routerContextProps,
39
- WraperRouterProviderProps: props,
37
+ WrapperRouterProviderProps: props,
40
38
  router
41
39
  });
42
40
  const RouterProvider = ReactRouterDom["RouterProvider"];
43
41
  const createMemoryRouter = ReactRouterDom["createMemoryRouter"];
44
42
  const createBrowserRouter = ReactRouterDom["createBrowserRouter"];
45
- if (!routerContextProps)
46
- return /* @__PURE__ */ React__default.createElement(RouterProvider, { ...props });
47
43
  if (routerContextProps.memoryRoute) {
48
44
  const MemeoryRouterInstance = createMemoryRouter(routers, {
49
45
  initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
@@ -59,6 +55,6 @@ function WraperRouterProvider(props) {
59
55
  }
60
56
  }
61
57
  export {
62
- WraperRouter as BrowserRouter,
63
- WraperRouterProvider as RouterProvider
58
+ WrapperRouter as BrowserRouter,
59
+ WrapperRouterProvider as RouterProvider
64
60
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/bridge-react",
3
- "version": "0.3.5",
3
+ "version": "0.5.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -20,12 +20,22 @@
20
20
  "import": "./dist/router.es.js",
21
21
  "require": "./dist/router.cjs.js"
22
22
  },
23
+ "./router-v5": {
24
+ "types": "./dist/router.d.ts",
25
+ "import": "./dist/router.es.js",
26
+ "require": "./dist/router.cjs.js"
27
+ },
28
+ "./router-v6": {
29
+ "types": "./dist/router.d.ts",
30
+ "import": "./dist/router.es.js",
31
+ "require": "./dist/router.cjs.js"
32
+ },
23
33
  "./*": "./*"
24
34
  },
25
35
  "dependencies": {
26
36
  "@loadable/component": "^5.16.4",
27
37
  "react-error-boundary": "^4.0.13",
28
- "@module-federation/bridge-shared": "0.3.5"
38
+ "@module-federation/bridge-shared": "0.5.0"
29
39
  },
30
40
  "peerDependencies": {
31
41
  "react": ">=16.9.0",
package/src/create.tsx CHANGED
@@ -13,11 +13,7 @@ export interface RenderFnParams extends ProviderParams {
13
13
 
14
14
  interface RemoteModule {
15
15
  provider: () => {
16
- render: (
17
- info: ProviderParams & {
18
- dom: any;
19
- },
20
- ) => void;
16
+ render: (info: RenderFnParams) => void;
21
17
  destroy: (info: { dom: any }) => void;
22
18
  };
23
19
  }
@@ -34,6 +30,7 @@ function createLazyRemoteComponent<T, E extends keyof T>(info: {
34
30
  lazyComponent: info.loader,
35
31
  exportName,
36
32
  });
33
+
37
34
  try {
38
35
  const m = (await info.loader()) as RemoteModule;
39
36
  // @ts-ignore
@@ -44,8 +41,7 @@ function createLazyRemoteComponent<T, E extends keyof T>(info: {
44
41
  );
45
42
 
46
43
  // @ts-ignore
47
- const exportFn = m[exportName] as any;
48
-
44
+ const exportFn = m[exportName];
49
45
  if (exportName in m && typeof exportFn === 'function') {
50
46
  const RemoteAppComponent = forwardRef<
51
47
  HTMLDivElement,
@@ -53,12 +49,15 @@ function createLazyRemoteComponent<T, E extends keyof T>(info: {
53
49
  basename?: ProviderParams['basename'];
54
50
  memoryRoute?: ProviderParams['memoryRoute'];
55
51
  }
56
- >((props, _ref) => {
52
+ >((props, ref) => {
57
53
  return (
58
54
  <RemoteApp
59
- name={moduleName}
55
+ // change `name` key to `moduleName` to avoid same property `name` passed by user's props which may cause unexpected issues.
56
+ moduleName={moduleName}
60
57
  providerInfo={exportFn}
61
58
  exportName={info.export || 'default'}
59
+ fallback={info.fallback}
60
+ ref={ref}
62
61
  {...props}
63
62
  />
64
63
  );
@@ -93,26 +92,22 @@ export function createRemoteComponent<T, E extends keyof T>(info: {
93
92
  type ExportType = T[E] extends (...args: any) => any
94
93
  ? ReturnType<T[E]>
95
94
  : never;
95
+
96
96
  type RawComponentType = '__BRIDGE_FN__' extends keyof ExportType
97
97
  ? ExportType['__BRIDGE_FN__'] extends (...args: any) => any
98
98
  ? Parameters<ExportType['__BRIDGE_FN__']>[0]
99
99
  : {}
100
100
  : {};
101
101
 
102
- const LazyComponent = createLazyRemoteComponent(info);
103
-
104
- return (
105
- props: {
106
- basename?: ProviderParams['basename'];
107
- memoryRoute?: ProviderParams['memoryRoute'];
108
- } & RawComponentType,
109
- ) => {
102
+ return forwardRef((props: ProviderParams & RawComponentType, ref) => {
103
+ const LazyComponent = createLazyRemoteComponent(info);
110
104
  return (
105
+ // set ErrorBoundary for LazyComponent rendering error, usually caused by inner bridge logic render process
111
106
  <ErrorBoundary FallbackComponent={info.fallback}>
112
107
  <React.Suspense fallback={info.loading}>
113
- <LazyComponent {...props} />
108
+ <LazyComponent {...props} ref={ref} />
114
109
  </React.Suspense>
115
110
  </ErrorBoundary>
116
111
  );
117
- };
112
+ });
118
113
  }