@module-federation/bridge-react 0.0.0-next-20240619092117 → 0.0.0-next-20240620023927

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # @module-federation/bridge-react
2
2
 
3
- ## 0.0.0-next-20240619092117
3
+ ## 0.0.0-next-20240620023927
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - @module-federation/bridge-shared@0.0.0-next-20240619092117
7
+ - @module-federation/bridge-shared@0.0.0-next-20240620023927
@@ -63,6 +63,7 @@ describe('bridge', () => {
63
63
  expect(getHtml(container)).toMatch('loading');
64
64
 
65
65
  await sleep(200);
66
- expect(getHtml(container)).toMatch('life cycle render hello world');
66
+ expect(getHtml(container)).toMatch('life cycle render');
67
+ expect(getHtml(container)).toMatch('hello world');
67
68
  });
68
69
  });
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React__default from "react";
2
2
  var a = Object.defineProperty;
3
3
  var c = (s, e, t) => e in s ? a(s, e, { enumerable: true, configurable: true, writable: true, value: t }) : s[e] = t;
4
4
  var i = (s, e, t) => (c(s, typeof e != "symbol" ? e + "" : e, t), t);
@@ -35,9 +35,22 @@ function f() {
35
35
  window.dispatchEvent(s);
36
36
  }
37
37
  const LoggerInstance = new g("bridge-react");
38
- const RouterContext = React.createContext(null);
38
+ function atLeastReact18(React2) {
39
+ if (React2 && typeof React2.version === "string" && React2.version.indexOf(".") >= 0) {
40
+ const majorVersionString = React2.version.split(".")[0];
41
+ try {
42
+ return Number(majorVersionString) >= 18;
43
+ } catch (err) {
44
+ return false;
45
+ }
46
+ } else {
47
+ return false;
48
+ }
49
+ }
50
+ const RouterContext = React__default.createContext(null);
39
51
  export {
40
52
  LoggerInstance as L,
41
53
  RouterContext as R,
54
+ atLeastReact18 as a,
42
55
  f
43
56
  };
@@ -36,7 +36,20 @@ function f() {
36
36
  window.dispatchEvent(s);
37
37
  }
38
38
  const LoggerInstance = new g("bridge-react");
39
+ function atLeastReact18(React2) {
40
+ if (React2 && typeof React2.version === "string" && React2.version.indexOf(".") >= 0) {
41
+ const majorVersionString = React2.version.split(".")[0];
42
+ try {
43
+ return Number(majorVersionString) >= 18;
44
+ } catch (err) {
45
+ return false;
46
+ }
47
+ } else {
48
+ return false;
49
+ }
50
+ }
39
51
  const RouterContext = React.createContext(null);
40
52
  exports.LoggerInstance = LoggerInstance;
41
53
  exports.RouterContext = RouterContext;
54
+ exports.atLeastReact18 = atLeastReact18;
42
55
  exports.f = f;
package/dist/index.cjs.js CHANGED
@@ -2,30 +2,50 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const React = require("react");
4
4
  const reactRouterDom = require("react-router-dom");
5
- const context = require("./context-C7FfFcIe.cjs");
6
- const require$$0 = require("react-dom");
5
+ const context = require("./context-ePt4wynZ.cjs");
6
+ const ReactDOM = require("react-dom");
7
+ function _interopNamespaceDefault(e) {
8
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
9
+ if (e) {
10
+ for (const k in e) {
11
+ if (k !== "default") {
12
+ const d = Object.getOwnPropertyDescriptor(e, k);
13
+ Object.defineProperty(n, k, d.get ? d : {
14
+ enumerable: true,
15
+ get: () => e[k]
16
+ });
17
+ }
18
+ }
19
+ }
20
+ n.default = e;
21
+ return Object.freeze(n);
22
+ }
23
+ const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
7
24
  const RemoteApp = ({
8
25
  name,
9
26
  memoryRoute,
10
27
  basename,
11
28
  providerInfo,
29
+ dispathPopstate,
12
30
  ...resProps
13
31
  }) => {
14
32
  const rootRef = React.useRef(null);
15
33
  const renderDom = React.useRef(null);
16
- const location = reactRouterDom.useLocation();
17
- const [pathname, setPathname] = React.useState(location.pathname);
18
34
  const providerInfoRef = React.useRef(null);
19
- React.useEffect(() => {
20
- if (pathname !== "" && pathname !== location.pathname) {
21
- context.LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
22
- name,
23
- pathname: location.pathname
24
- });
25
- context.f();
26
- }
27
- setPathname(location.pathname);
28
- }, [location]);
35
+ if (dispathPopstate) {
36
+ const location = reactRouterDom.useLocation();
37
+ const [pathname, setPathname] = React.useState(location.pathname);
38
+ React.useEffect(() => {
39
+ if (pathname !== "" && pathname !== location.pathname) {
40
+ context.LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
41
+ name,
42
+ pathname: location.pathname
43
+ });
44
+ context.f();
45
+ }
46
+ setPathname(location.pathname);
47
+ }, [location]);
48
+ }
29
49
  React.useEffect(() => {
30
50
  const renderTimeout = setTimeout(() => {
31
51
  const providerReturn = providerInfo();
@@ -68,7 +88,7 @@ function createRemoteComponent(lazyComponent, info) {
68
88
  const exportName = (info == null ? void 0 : info.export) || "default";
69
89
  const routerContextVal = React.useContext(reactRouterDom.UNSAFE_RouteContext);
70
90
  let basename = "/";
71
- if (routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
91
+ if (routerContextVal && routerContextVal.matches && routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
72
92
  basename = routerContextVal.matches[0].pathnameBase;
73
93
  }
74
94
  const LazyComponent = React.useMemo(() => {
@@ -77,7 +97,8 @@ function createRemoteComponent(lazyComponent, info) {
77
97
  basename,
78
98
  lazyComponent,
79
99
  exportName,
80
- props
100
+ props,
101
+ routerContextVal
81
102
  });
82
103
  const m2 = await lazyComponent();
83
104
  const moduleName = m2 && m2[Symbol.for("mf_module_id")];
@@ -92,6 +113,7 @@ function createRemoteComponent(lazyComponent, info) {
92
113
  RemoteApp,
93
114
  {
94
115
  name: moduleName,
116
+ dispathPopstate: (routerContextVal == null ? void 0 : routerContextVal.matches) && (routerContextVal == null ? void 0 : routerContextVal.matches.length) > 0,
95
117
  ...info,
96
118
  ...props,
97
119
  providerInfo: exportFn,
@@ -107,7 +129,7 @@ function createRemoteComponent(lazyComponent, info) {
107
129
  };
108
130
  }
109
131
  var client = {};
110
- var m = require$$0;
132
+ var m = ReactDOM;
111
133
  if (process.env.NODE_ENV === "production") {
112
134
  client.createRoot = m.createRoot;
113
135
  client.hydrateRoot = m.hydrateRoot;
@@ -136,34 +158,55 @@ function createBridgeComponent(bridgeInfo) {
136
158
  const RawComponent = (info) => {
137
159
  const { appInfo, propsInfo } = info;
138
160
  const { name, memoryRoute, basename = "/" } = appInfo;
139
- return /* @__PURE__ */ React.createElement(context.RouterContext.Provider, { value: { name, basename, memoryRoute } }, /* @__PURE__ */ React.createElement(bridgeInfo.rootComponent, { ...propsInfo, basename }));
161
+ return /* @__PURE__ */ React__namespace.createElement(context.RouterContext.Provider, { value: { name, basename, memoryRoute } }, /* @__PURE__ */ React__namespace.createElement(bridgeInfo.rootComponent, { ...propsInfo, basename }));
140
162
  };
141
163
  return {
142
164
  render(info) {
143
165
  context.LoggerInstance.log(`createBridgeComponent render Info`, info);
144
- const root = client.createRoot(info.dom);
145
- rootMap.set(info.dom, root);
146
166
  const { name, basename, memoryRoute, ...propsInfo } = info;
147
- root.render(
148
- /* @__PURE__ */ React.createElement(
149
- RawComponent,
150
- {
151
- propsInfo,
152
- appInfo: {
153
- name,
154
- basename,
155
- memoryRoute
167
+ if (context.atLeastReact18(React__namespace)) {
168
+ const root = client.createRoot(info.dom);
169
+ rootMap.set(info.dom, root);
170
+ root.render(
171
+ /* @__PURE__ */ React__namespace.createElement(
172
+ RawComponent,
173
+ {
174
+ propsInfo,
175
+ appInfo: {
176
+ name,
177
+ basename,
178
+ memoryRoute
179
+ }
156
180
  }
157
- }
158
- )
159
- );
181
+ )
182
+ );
183
+ } else {
184
+ ReactDOM.render(
185
+ /* @__PURE__ */ React__namespace.createElement(
186
+ RawComponent,
187
+ {
188
+ propsInfo,
189
+ appInfo: {
190
+ name,
191
+ basename,
192
+ memoryRoute
193
+ }
194
+ }
195
+ ),
196
+ info.dom
197
+ );
198
+ }
160
199
  },
161
200
  destroy(info) {
162
201
  context.LoggerInstance.log(`createBridgeComponent destroy Info`, {
163
202
  dom: info.dom
164
203
  });
165
- const root = rootMap.get(info.dom);
166
- root == null ? void 0 : root.unmount();
204
+ if (context.atLeastReact18(React__namespace)) {
205
+ const root = rootMap.get(info.dom);
206
+ root == null ? void 0 : root.unmount();
207
+ } else {
208
+ ReactDOM.unmountComponentAtNode(info.dom);
209
+ }
167
210
  },
168
211
  rawComponent: bridgeInfo.rootComponent,
169
212
  __BRIDGE_FN__: (_args) => {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { default as default_2 } from 'react';
2
+ import * as React_2 from 'react';
2
3
  import { ReactNode } from 'react';
3
4
 
4
5
  export declare function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>): () => {
@@ -6,7 +7,7 @@ export declare function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>
6
7
  destroy(info: {
7
8
  dom: HTMLElement;
8
9
  }): void;
9
- rawComponent: default_2.ComponentType<T>;
10
+ rawComponent: React_2.ComponentType<T>;
10
11
  __BRIDGE_FN__: (_args: T) => void;
11
12
  };
12
13
 
@@ -19,7 +20,7 @@ export declare function createRemoteComponent<T, E extends keyof T>(lazyComponen
19
20
  } & ("__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;
20
21
 
21
22
  declare type ProviderFnParams<T> = {
22
- rootComponent: default_2.ComponentType<T>;
23
+ rootComponent: React_2.ComponentType<T>;
23
24
  };
24
25
 
25
26
  export declare interface ProviderParams {
package/dist/index.es.js CHANGED
@@ -1,29 +1,33 @@
1
- import React, { useContext, useMemo, useRef, useState, useEffect } from "react";
1
+ import * as React from "react";
2
+ import React__default, { useContext, useMemo, useRef, useState, useEffect } from "react";
2
3
  import { UNSAFE_RouteContext, useLocation } from "react-router-dom";
3
- import { L as LoggerInstance, f, R as RouterContext } from "./context-CoFgcMIF.js";
4
- import require$$0 from "react-dom";
4
+ import { L as LoggerInstance, f, a as atLeastReact18, R as RouterContext } from "./context-CPtN38Ur.js";
5
+ import ReactDOM from "react-dom";
5
6
  const RemoteApp = ({
6
7
  name,
7
8
  memoryRoute,
8
9
  basename,
9
10
  providerInfo,
11
+ dispathPopstate,
10
12
  ...resProps
11
13
  }) => {
12
14
  const rootRef = useRef(null);
13
15
  const renderDom = useRef(null);
14
- const location = useLocation();
15
- const [pathname, setPathname] = useState(location.pathname);
16
16
  const providerInfoRef = useRef(null);
17
- useEffect(() => {
18
- if (pathname !== "" && pathname !== location.pathname) {
19
- LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
20
- name,
21
- pathname: location.pathname
22
- });
23
- f();
24
- }
25
- setPathname(location.pathname);
26
- }, [location]);
17
+ if (dispathPopstate) {
18
+ const location = useLocation();
19
+ const [pathname, setPathname] = useState(location.pathname);
20
+ useEffect(() => {
21
+ if (pathname !== "" && pathname !== location.pathname) {
22
+ LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
23
+ name,
24
+ pathname: location.pathname
25
+ });
26
+ f();
27
+ }
28
+ setPathname(location.pathname);
29
+ }, [location]);
30
+ }
27
31
  useEffect(() => {
28
32
  const renderTimeout = setTimeout(() => {
29
33
  const providerReturn = providerInfo();
@@ -58,7 +62,7 @@ const RemoteApp = ({
58
62
  });
59
63
  };
60
64
  }, []);
61
- return /* @__PURE__ */ React.createElement("div", { ref: rootRef });
65
+ return /* @__PURE__ */ React__default.createElement("div", { ref: rootRef });
62
66
  };
63
67
  RemoteApp["__APP_VERSION__"] = "0.0.1";
64
68
  function createRemoteComponent(lazyComponent, info) {
@@ -66,16 +70,17 @@ function createRemoteComponent(lazyComponent, info) {
66
70
  const exportName = (info == null ? void 0 : info.export) || "default";
67
71
  const routerContextVal = useContext(UNSAFE_RouteContext);
68
72
  let basename = "/";
69
- if (routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
73
+ if (routerContextVal && routerContextVal.matches && routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
70
74
  basename = routerContextVal.matches[0].pathnameBase;
71
75
  }
72
76
  const LazyComponent = useMemo(() => {
73
- return React.lazy(async () => {
77
+ return React__default.lazy(async () => {
74
78
  LoggerInstance.log(`createRemoteComponent LazyComponent create >>>`, {
75
79
  basename,
76
80
  lazyComponent,
77
81
  exportName,
78
- props
82
+ props,
83
+ routerContextVal
79
84
  });
80
85
  const m2 = await lazyComponent();
81
86
  const moduleName = m2 && m2[Symbol.for("mf_module_id")];
@@ -86,10 +91,11 @@ function createRemoteComponent(lazyComponent, info) {
86
91
  const exportFn = m2[exportName];
87
92
  if (exportName in m2 && typeof exportFn === "function") {
88
93
  return {
89
- default: () => /* @__PURE__ */ React.createElement(
94
+ default: () => /* @__PURE__ */ React__default.createElement(
90
95
  RemoteApp,
91
96
  {
92
97
  name: moduleName,
98
+ dispathPopstate: (routerContextVal == null ? void 0 : routerContextVal.matches) && (routerContextVal == null ? void 0 : routerContextVal.matches.length) > 0,
93
99
  ...info,
94
100
  ...props,
95
101
  providerInfo: exportFn,
@@ -101,11 +107,11 @@ function createRemoteComponent(lazyComponent, info) {
101
107
  throw Error("module not found");
102
108
  });
103
109
  }, [exportName, basename, props.memoryRoute]);
104
- return /* @__PURE__ */ React.createElement(React.Suspense, { fallback: props.fallback }, /* @__PURE__ */ React.createElement(LazyComponent, null));
110
+ return /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: props.fallback }, /* @__PURE__ */ React__default.createElement(LazyComponent, null));
105
111
  };
106
112
  }
107
113
  var client = {};
108
- var m = require$$0;
114
+ var m = ReactDOM;
109
115
  if (process.env.NODE_ENV === "production") {
110
116
  client.createRoot = m.createRoot;
111
117
  client.hydrateRoot = m.hydrateRoot;
@@ -139,29 +145,50 @@ function createBridgeComponent(bridgeInfo) {
139
145
  return {
140
146
  render(info) {
141
147
  LoggerInstance.log(`createBridgeComponent render Info`, info);
142
- const root = client.createRoot(info.dom);
143
- rootMap.set(info.dom, root);
144
148
  const { name, basename, memoryRoute, ...propsInfo } = info;
145
- root.render(
146
- /* @__PURE__ */ React.createElement(
147
- RawComponent,
148
- {
149
- propsInfo,
150
- appInfo: {
151
- name,
152
- basename,
153
- memoryRoute
149
+ if (atLeastReact18(React)) {
150
+ const root = client.createRoot(info.dom);
151
+ rootMap.set(info.dom, root);
152
+ root.render(
153
+ /* @__PURE__ */ React.createElement(
154
+ RawComponent,
155
+ {
156
+ propsInfo,
157
+ appInfo: {
158
+ name,
159
+ basename,
160
+ memoryRoute
161
+ }
154
162
  }
155
- }
156
- )
157
- );
163
+ )
164
+ );
165
+ } else {
166
+ ReactDOM.render(
167
+ /* @__PURE__ */ React.createElement(
168
+ RawComponent,
169
+ {
170
+ propsInfo,
171
+ appInfo: {
172
+ name,
173
+ basename,
174
+ memoryRoute
175
+ }
176
+ }
177
+ ),
178
+ info.dom
179
+ );
180
+ }
158
181
  },
159
182
  destroy(info) {
160
183
  LoggerInstance.log(`createBridgeComponent destroy Info`, {
161
184
  dom: info.dom
162
185
  });
163
- const root = rootMap.get(info.dom);
164
- root == null ? void 0 : root.unmount();
186
+ if (atLeastReact18(React)) {
187
+ const root = rootMap.get(info.dom);
188
+ root == null ? void 0 : root.unmount();
189
+ } else {
190
+ ReactDOM.unmountComponentAtNode(info.dom);
191
+ }
165
192
  },
166
193
  rawComponent: bridgeInfo.rootComponent,
167
194
  __BRIDGE_FN__: (_args) => {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const React = require("react");
4
4
  const ReactRouterDom = require("react-router-dom/");
5
- const context = require("./context-C7FfFcIe.cjs");
5
+ const context = require("./context-ePt4wynZ.cjs");
6
6
  function _interopNamespaceDefault(e) {
7
7
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
8
8
  if (e) {
package/dist/router.es.js CHANGED
@@ -1,7 +1,7 @@
1
- import React, { useContext } from "react";
1
+ import React__default, { useContext } from "react";
2
2
  import * as ReactRouterDom from "react-router-dom/";
3
3
  export * from "react-router-dom/";
4
- import { R as RouterContext, L as LoggerInstance } from "./context-CoFgcMIF.js";
4
+ import { R as RouterContext, L as LoggerInstance } from "./context-CPtN38Ur.js";
5
5
  function WraperRouter(props) {
6
6
  const { basename, ...propsRes } = props;
7
7
  const routerContextProps = useContext(RouterContext) || {};
@@ -11,9 +11,9 @@ function WraperRouter(props) {
11
11
  WraperRouterProps: props
12
12
  });
13
13
  if (!routerContextProps)
14
- return /* @__PURE__ */ React.createElement(ReactRouterDom.BrowserRouter, { ...props });
14
+ return /* @__PURE__ */ React__default.createElement(ReactRouterDom.BrowserRouter, { ...props });
15
15
  if (routerContextProps == null ? void 0 : routerContextProps.memoryRoute) {
16
- return /* @__PURE__ */ React.createElement(
16
+ return /* @__PURE__ */ React__default.createElement(
17
17
  ReactRouterDom.MemoryRouter,
18
18
  {
19
19
  ...props,
@@ -21,7 +21,7 @@ function WraperRouter(props) {
21
21
  }
22
22
  );
23
23
  }
24
- return /* @__PURE__ */ React.createElement(
24
+ return /* @__PURE__ */ React__default.createElement(
25
25
  ReactRouterDom.BrowserRouter,
26
26
  {
27
27
  ...propsRes,
@@ -40,19 +40,19 @@ function WraperRouterProvider(props) {
40
40
  router
41
41
  });
42
42
  if (!routerContextProps)
43
- return /* @__PURE__ */ React.createElement(ReactRouterDom.RouterProvider, { ...props });
43
+ return /* @__PURE__ */ React__default.createElement(ReactRouterDom.RouterProvider, { ...props });
44
44
  if (routerContextProps.memoryRoute) {
45
45
  const MemeoryRouterInstance = ReactRouterDom.createMemoryRouter(routers, {
46
46
  initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
47
47
  });
48
- return /* @__PURE__ */ React.createElement(ReactRouterDom.RouterProvider, { router: MemeoryRouterInstance });
48
+ return /* @__PURE__ */ React__default.createElement(ReactRouterDom.RouterProvider, { router: MemeoryRouterInstance });
49
49
  } else {
50
50
  const BrowserRouterInstance = ReactRouterDom.createBrowserRouter(routers, {
51
51
  basename: routerContextProps.basename,
52
52
  future: router.future,
53
53
  window: router.window
54
54
  });
55
- return /* @__PURE__ */ React.createElement(
55
+ return /* @__PURE__ */ React__default.createElement(
56
56
  ReactRouterDom.RouterProvider,
57
57
  {
58
58
  ...propsRes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/bridge-react",
3
- "version": "0.0.0-next-20240619092117",
3
+ "version": "0.0.0-next-20240620023927",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -25,12 +25,12 @@
25
25
  "dependencies": {
26
26
  "@loadable/component": "^5.16.4",
27
27
  "react-error-boundary": "^4.0.13",
28
- "@module-federation/bridge-shared": "0.0.0-next-20240619092117"
28
+ "@module-federation/bridge-shared": "0.0.0-next-20240620023927"
29
29
  },
30
30
  "peerDependencies": {
31
- "react": "=18",
32
- "react-dom": "=18",
33
- "react-router-dom": ">=5"
31
+ "react": ">=16.9.0",
32
+ "react-dom": ">=16.9.0",
33
+ "react-router-dom": ">=4"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@testing-library/react": "15.0.7",
package/src/create.tsx CHANGED
@@ -31,6 +31,7 @@ interface RemoteModule {
31
31
  interface RemoteAppParams {
32
32
  name: string;
33
33
  providerInfo: NonNullable<RemoteModule['provider']>;
34
+ dispathPopstate: boolean;
34
35
  }
35
36
 
36
37
  const RemoteApp = ({
@@ -38,24 +39,27 @@ const RemoteApp = ({
38
39
  memoryRoute,
39
40
  basename,
40
41
  providerInfo,
42
+ dispathPopstate,
41
43
  ...resProps
42
44
  }: RemoteAppParams & ProviderParams) => {
43
45
  const rootRef = useRef(null);
44
46
  const renderDom = useRef(null);
45
- const location = useLocation();
46
- const [pathname, setPathname] = useState(location.pathname);
47
47
  const providerInfoRef = useRef<any>(null);
48
-
49
- useEffect(() => {
50
- if (pathname !== '' && pathname !== location.pathname) {
51
- LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
52
- name,
53
- pathname: location.pathname,
54
- });
55
- dispatchPopstateEnv();
56
- }
57
- setPathname(location.pathname);
58
- }, [location]);
48
+ if (dispathPopstate) {
49
+ const location = useLocation();
50
+ const [pathname, setPathname] = useState(location.pathname);
51
+
52
+ useEffect(() => {
53
+ if (pathname !== '' && pathname !== location.pathname) {
54
+ LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
55
+ name,
56
+ pathname: location.pathname,
57
+ });
58
+ dispatchPopstateEnv();
59
+ }
60
+ setPathname(location.pathname);
61
+ }, [location]);
62
+ }
59
63
 
60
64
  useEffect(() => {
61
65
  const renderTimeout = setTimeout(() => {
@@ -124,6 +128,8 @@ export function createRemoteComponent<T, E extends keyof T>(
124
128
  const routerContextVal = useContext(UNSAFE_RouteContext);
125
129
  let basename = '/';
126
130
  if (
131
+ routerContextVal &&
132
+ routerContextVal.matches &&
127
133
  routerContextVal.matches[0] &&
128
134
  routerContextVal.matches[0].pathnameBase
129
135
  ) {
@@ -138,6 +144,7 @@ export function createRemoteComponent<T, E extends keyof T>(
138
144
  lazyComponent,
139
145
  exportName,
140
146
  props,
147
+ routerContextVal,
141
148
  });
142
149
  const m = (await lazyComponent()) as RemoteModule;
143
150
  // @ts-ignore
@@ -155,6 +162,10 @@ export function createRemoteComponent<T, E extends keyof T>(
155
162
  default: () => (
156
163
  <RemoteApp
157
164
  name={moduleName}
165
+ dispathPopstate={
166
+ routerContextVal?.matches &&
167
+ routerContextVal?.matches.length > 0
168
+ }
158
169
  {...info}
159
170
  {...props}
160
171
  providerInfo={exportFn}
package/src/provider.tsx CHANGED
@@ -1,11 +1,13 @@
1
- import React, { useLayoutEffect, useRef, useState } from 'react';
2
- import ReactDOM from 'react-dom/client';
1
+ import { useLayoutEffect, useRef, useState } from 'react';
2
+ import * as React from 'react';
3
+ import ReactDOM from 'react-dom';
4
+ import ReactDOMClient from 'react-dom/client';
3
5
  import { RouterContext } from './context';
4
6
  import type {
5
7
  ProviderParams,
6
8
  RenderFnParams,
7
9
  } from '@module-federation/bridge-shared';
8
- import { LoggerInstance } from './utils';
10
+ import { LoggerInstance, atLeastReact18 } from './utils';
9
11
 
10
12
  type ProviderFnParams<T> = {
11
13
  rootComponent: React.ComponentType<T>;
@@ -13,7 +15,7 @@ type ProviderFnParams<T> = {
13
15
 
14
16
  export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
15
17
  return () => {
16
- const rootMap = new Map<any, ReactDOM.Root>();
18
+ const rootMap = new Map<any, ReactDOMClient.Root>();
17
19
 
18
20
  const RawComponent = (info: { propsInfo: T; appInfo: ProviderParams }) => {
19
21
  const { appInfo, propsInfo } = info;
@@ -29,26 +31,45 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
29
31
  return {
30
32
  render(info: RenderFnParams & any) {
31
33
  LoggerInstance.log(`createBridgeComponent render Info`, info);
32
- const root = ReactDOM.createRoot(info.dom);
33
- rootMap.set(info.dom, root);
34
34
  const { name, basename, memoryRoute, ...propsInfo } = info;
35
- root.render(
36
- <RawComponent
37
- propsInfo={propsInfo}
38
- appInfo={{
39
- name,
40
- basename,
41
- memoryRoute,
42
- }}
43
- />,
44
- );
35
+
36
+ if (atLeastReact18(React)) {
37
+ const root = ReactDOMClient.createRoot(info.dom);
38
+ rootMap.set(info.dom, root);
39
+ root.render(
40
+ <RawComponent
41
+ propsInfo={propsInfo}
42
+ appInfo={{
43
+ name,
44
+ basename,
45
+ memoryRoute,
46
+ }}
47
+ />,
48
+ );
49
+ } else {
50
+ ReactDOM.render(
51
+ <RawComponent
52
+ propsInfo={propsInfo}
53
+ appInfo={{
54
+ name,
55
+ basename,
56
+ memoryRoute,
57
+ }}
58
+ />,
59
+ info.dom,
60
+ );
61
+ }
45
62
  },
46
63
  destroy(info: { dom: HTMLElement }) {
47
64
  LoggerInstance.log(`createBridgeComponent destroy Info`, {
48
65
  dom: info.dom,
49
66
  });
50
- const root = rootMap.get(info.dom);
51
- root?.unmount();
67
+ if (atLeastReact18(React)) {
68
+ const root = rootMap.get(info.dom);
69
+ root?.unmount();
70
+ } else {
71
+ ReactDOM.unmountComponentAtNode(info.dom);
72
+ }
52
73
  },
53
74
  rawComponent: bridgeInfo.rootComponent,
54
75
  __BRIDGE_FN__: (_args: T) => {},
package/src/utils.ts CHANGED
@@ -1,3 +1,23 @@
1
+ import React from 'react';
1
2
  import { Logger } from '@module-federation/bridge-shared';
2
3
 
3
4
  export const LoggerInstance = new Logger('bridge-react');
5
+
6
+ type typeReact = typeof React;
7
+
8
+ export function atLeastReact18(React: typeReact) {
9
+ if (
10
+ React &&
11
+ typeof React.version === 'string' &&
12
+ React.version.indexOf('.') >= 0
13
+ ) {
14
+ const majorVersionString = React.version.split('.')[0];
15
+ try {
16
+ return Number(majorVersionString) >= 18;
17
+ } catch (err) {
18
+ return false;
19
+ }
20
+ } else {
21
+ return false;
22
+ }
23
+ }