@module-federation/bridge-react 0.0.0-refactor-manifest-20251016072532 → 0.0.0-research-issue-4085-20251016232757

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,12 +1,15 @@
1
1
  # @module-federation/bridge-react
2
2
 
3
- ## 0.0.0-refactor-manifest-20251016072532
3
+ ## 0.0.0-research-issue-4085-20251016232757
4
+
5
+ ### Minor Changes
6
+
7
+ - d225658: feat: Add React Router v7 Support to Module Federation Bridge
4
8
 
5
9
  ### Patch Changes
6
10
 
7
- - Updated dependencies [ef4ada0]
8
- - @module-federation/sdk@0.0.0-refactor-manifest-20251016072532
9
- - @module-federation/bridge-shared@0.0.0-refactor-manifest-20251016072532
11
+ - @module-federation/sdk@0.0.0-research-issue-4085-20251016232757
12
+ - @module-federation/bridge-shared@0.0.0-research-issue-4085-20251016232757
10
13
 
11
14
  ## 0.20.0
12
15
 
@@ -139,7 +139,7 @@ function createBaseBridgeComponent({
139
139
  ...rootOptions
140
140
  };
141
141
  const beforeBridgeRenderRes = ((_c = (_b = (_a = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _a.lifecycle) == null ? void 0 : _b.beforeBridgeRender) == null ? void 0 : _c.emit(info)) || {};
142
- const rootComponentWithErrorBoundary = /* @__PURE__ */ React.createElement(
142
+ const BridgeWrapper = ({ basename: basename2 }) => /* @__PURE__ */ React.createElement(
143
143
  ErrorBoundary,
144
144
  {
145
145
  FallbackComponent: fallback
@@ -149,16 +149,18 @@ function createBaseBridgeComponent({
149
149
  {
150
150
  appInfo: {
151
151
  moduleName,
152
- basename,
152
+ basename: basename2,
153
153
  memoryRoute
154
154
  },
155
155
  propsInfo: {
156
156
  ...propsInfo,
157
+ basename: basename2,
157
158
  ...beforeBridgeRenderRes == null ? void 0 : beforeBridgeRenderRes.extraProps
158
159
  }
159
160
  }
160
161
  )
161
162
  );
163
+ const rootComponentWithErrorBoundary = /* @__PURE__ */ React.createElement(BridgeWrapper, { basename });
162
164
  if (bridgeInfo.render) {
163
165
  await Promise.resolve(
164
166
  bridgeInfo.render(rootComponentWithErrorBoundary, dom)
@@ -184,7 +186,7 @@ function createBaseBridgeComponent({
184
186
  if ("unmount" in root) {
185
187
  root.unmount();
186
188
  } else {
187
- console.warn("Root does not have unmount method");
189
+ LoggerInstance.warn("Root does not have unmount method");
188
190
  }
189
191
  rootMap.delete(dom);
190
192
  }
@@ -156,7 +156,7 @@ function createBaseBridgeComponent({
156
156
  ...rootOptions
157
157
  };
158
158
  const beforeBridgeRenderRes = ((_c = (_b = (_a = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _a.lifecycle) == null ? void 0 : _b.beforeBridgeRender) == null ? void 0 : _c.emit(info)) || {};
159
- const rootComponentWithErrorBoundary = /* @__PURE__ */ React__namespace.createElement(
159
+ const BridgeWrapper = ({ basename: basename2 }) => /* @__PURE__ */ React__namespace.createElement(
160
160
  ErrorBoundary,
161
161
  {
162
162
  FallbackComponent: fallback
@@ -166,16 +166,18 @@ function createBaseBridgeComponent({
166
166
  {
167
167
  appInfo: {
168
168
  moduleName,
169
- basename,
169
+ basename: basename2,
170
170
  memoryRoute
171
171
  },
172
172
  propsInfo: {
173
173
  ...propsInfo,
174
+ basename: basename2,
174
175
  ...beforeBridgeRenderRes == null ? void 0 : beforeBridgeRenderRes.extraProps
175
176
  }
176
177
  }
177
178
  )
178
179
  );
180
+ const rootComponentWithErrorBoundary = /* @__PURE__ */ React__namespace.createElement(BridgeWrapper, { basename });
179
181
  if (bridgeInfo.render) {
180
182
  await Promise.resolve(
181
183
  bridgeInfo.render(rootComponentWithErrorBoundary, dom)
@@ -201,7 +203,7 @@ function createBaseBridgeComponent({
201
203
  if ("unmount" in root) {
202
204
  root.unmount();
203
205
  } else {
204
- console.warn("Root does not have unmount method");
206
+ index.LoggerInstance.warn("Root does not have unmount method");
205
207
  }
206
208
  rootMap.delete(dom);
207
209
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const lazyUtils = require("./utils-0HFFqmd4.js");
4
- const prefetch = require("./prefetch-BQDJK9jf.js");
4
+ const prefetch = require("./prefetch-CA6G6-yu.js");
5
5
  async function callDataFetch() {
6
6
  const dataFetch = globalThis[lazyUtils.DATA_FETCH_FUNCTION];
7
7
  if (dataFetch) {
@@ -1,7 +1,7 @@
1
1
  import { x as DATA_FETCH_FUNCTION } from "./utils-BTpxHmva.mjs";
2
2
  import { C, b, e, h, c, d, r } from "./utils-BTpxHmva.mjs";
3
- import { d as dataFetchFunction } from "./prefetch-COcDj0qT.mjs";
4
- import { i, p } from "./prefetch-COcDj0qT.mjs";
3
+ import { d as dataFetchFunction } from "./prefetch-LIaCm_HY.mjs";
4
+ import { i, p } from "./prefetch-LIaCm_HY.mjs";
5
5
  async function callDataFetch() {
6
6
  const dataFetch = globalThis[DATA_FETCH_FUNCTION];
7
7
  if (dataFetch) {
package/dist/index.cjs.js CHANGED
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const bridgeBase = require("./bridge-base-Bn6DO0Fi.js");
3
+ const bridgeBase = require("./bridge-base-CTNdBioh.js");
4
4
  const ReactDOM = require("react-dom");
5
- const React = require("react");
6
5
  const index = require("./index-DqCpgmgH.js");
6
+ const React = require("react");
7
7
  const ReactRouterDOM = require("react-router-dom");
8
8
  const plugin = require("./plugin.cjs.js");
9
- const lazyLoadComponentPlugin = require("./lazy-load-component-plugin-CB4Y_oAi.js");
9
+ const lazyLoadComponentPlugin = require("./lazy-load-component-plugin-9EYk327t.js");
10
10
  const lazyUtils = require("./utils-0HFFqmd4.js");
11
11
  const dataFetchUtils = require("./data-fetch-utils.cjs.js");
12
- const prefetch = require("./prefetch-BQDJK9jf.js");
12
+ const prefetch = require("./prefetch-CA6G6-yu.js");
13
13
  function _interopNamespaceDefault(e2) {
14
14
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
15
15
  if (e2) {
@@ -39,7 +39,7 @@ function createReact16Or17Root(container) {
39
39
  );
40
40
  }
41
41
  if (isReact18) {
42
- console.warn(
42
+ index.LoggerInstance.warn(
43
43
  `[Bridge-React] React 18 detected in legacy mode. For better compatibility, please use the version-specific import: import { createBridgeComponent } from '@module-federation/bridge-react/v18'`
44
44
  );
45
45
  }
package/dist/index.es.js CHANGED
@@ -1,13 +1,13 @@
1
- import { c as createBaseBridgeComponent, E as ErrorBoundary } from "./bridge-base-DxcR1fja.mjs";
1
+ import { c as createBaseBridgeComponent, E as ErrorBoundary } from "./bridge-base-29j7dZKh.mjs";
2
2
  import ReactDOM from "react-dom";
3
+ import { L as LoggerInstance, p as pathJoin, g as getRootDomDefaultClassName } from "./index-Dm-M9ouh.mjs";
3
4
  import React__default, { forwardRef, useContext, useState, useEffect, useRef } from "react";
4
- import { p as pathJoin, L as LoggerInstance, g as getRootDomDefaultClassName } from "./index-Dm-M9ouh.mjs";
5
5
  import * as ReactRouterDOM from "react-router-dom";
6
6
  import { federationRuntime } from "./plugin.es.js";
7
- import { b, a, c, l } from "./lazy-load-component-plugin-yVGSIjXg.mjs";
7
+ import { b, a, c, l } from "./lazy-load-component-plugin-DzKlAuS1.mjs";
8
8
  import { C, b as b2, E, e, h, c as c2, d, r, s } from "./utils-BTpxHmva.mjs";
9
9
  import { callDataFetch } from "./data-fetch-utils.es.js";
10
- import { p } from "./prefetch-COcDj0qT.mjs";
10
+ import { p } from "./prefetch-LIaCm_HY.mjs";
11
11
  function createReact16Or17Root(container) {
12
12
  return {
13
13
  render(children) {
@@ -20,7 +20,7 @@ function createReact16Or17Root(container) {
20
20
  );
21
21
  }
22
22
  if (isReact18) {
23
- console.warn(
23
+ LoggerInstance.warn(
24
24
  `[Bridge-React] React 18 detected in legacy mode. For better compatibility, please use the version-specific import: import { createBridgeComponent } from '@module-federation/bridge-react/v18'`
25
25
  );
26
26
  }
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const prefetch = require("./prefetch-BQDJK9jf.js");
2
+ const prefetch = require("./prefetch-CA6G6-yu.js");
3
3
  const lazyUtils = require("./utils-0HFFqmd4.js");
4
4
  const React = require("react");
5
5
  const autoFetchData = () => {
@@ -1,4 +1,4 @@
1
- import { i as injectDataFetch, p as prefetch } from "./prefetch-COcDj0qT.mjs";
1
+ import { i as injectDataFetch, p as prefetch } from "./prefetch-LIaCm_HY.mjs";
2
2
  import { i as initDataFetchMap, j as isDataLoaderExpose, k as getDataFetchInfo, m as getDataFetchMapKey, l as logger, n as getDataFetchItem, o as DATA_FETCH_CLIENT_SUFFIX, p as MF_DATA_FETCH_TYPE, q as isCSROnly, a as loadDataFetchModule, M as MF_DATA_FETCH_STATUS, g as getDataFetchMap, t as isServerEnv, u as getDataFetchIdWithErrorMsgs, v as DATA_FETCH_ERROR_PREFIX, E as ERROR_TYPE, w as wrapDataFetchId, L as LOAD_REMOTE_ERROR_PREFIX, x as DATA_FETCH_FUNCTION, y as getLoadedRemoteInfos, f as fetchData$1, z as setDataFetchItemLoadedStatus, F as FS_HREF } from "./utils-BTpxHmva.mjs";
3
3
  import React__default, { useRef, useState, Suspense, useEffect } from "react";
4
4
  const autoFetchData = () => {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const lazyLoadComponentPlugin = require("./lazy-load-component-plugin-CB4Y_oAi.js");
4
- require("./prefetch-BQDJK9jf.js");
3
+ const lazyLoadComponentPlugin = require("./lazy-load-component-plugin-9EYk327t.js");
4
+ require("./prefetch-CA6G6-yu.js");
5
5
  exports.default = lazyLoadComponentPlugin.lazyLoadComponentPlugin;
6
6
  exports.lazyLoadComponentPlugin = lazyLoadComponentPlugin.lazyLoadComponentPlugin;
@@ -1,5 +1,5 @@
1
- import { l, l as l2 } from "./lazy-load-component-plugin-yVGSIjXg.mjs";
2
- import "./prefetch-COcDj0qT.mjs";
1
+ import { l, l as l2 } from "./lazy-load-component-plugin-DzKlAuS1.mjs";
2
+ import "./prefetch-LIaCm_HY.mjs";
3
3
  export {
4
4
  l as default,
5
5
  l2 as lazyLoadComponentPlugin
@@ -211,7 +211,7 @@ function getGlobalFederationConstructor() {
211
211
  function setGlobalFederationConstructor(FederationConstructor, isDebug = index_esm.isDebugMode()) {
212
212
  if (isDebug) {
213
213
  CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
214
- CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "0.0.0-refactor-manifest-20251016072532";
214
+ CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "0.0.0-research-issue-4085-20251016232757";
215
215
  }
216
216
  }
217
217
  function getInfoWithoutType(target, key) {
@@ -210,7 +210,7 @@ function getGlobalFederationConstructor() {
210
210
  function setGlobalFederationConstructor(FederationConstructor, isDebug = isDebugMode()) {
211
211
  if (isDebug) {
212
212
  CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
213
- CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "0.0.0-refactor-manifest-20251016072532";
213
+ CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "0.0.0-research-issue-4085-20251016232757";
214
214
  }
215
215
  }
216
216
  function getInfoWithoutType(target, key) {
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const React = require("react");
4
+ const ReactRouterDom = require("react-router");
5
+ const index = require("./index-DqCpgmgH.js");
6
+ function _interopNamespaceDefault(e) {
7
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
8
+ if (e) {
9
+ for (const k in e) {
10
+ if (k !== "default") {
11
+ const d = Object.getOwnPropertyDescriptor(e, k);
12
+ Object.defineProperty(n, k, d.get ? d : {
13
+ enumerable: true,
14
+ get: () => e[k]
15
+ });
16
+ }
17
+ }
18
+ }
19
+ n.default = e;
20
+ return Object.freeze(n);
21
+ }
22
+ const ReactRouterDom__namespace = /* @__PURE__ */ _interopNamespaceDefault(ReactRouterDom);
23
+ function WraperRouter(props) {
24
+ const { basename, ...propsRes } = props;
25
+ const routerContextProps = React.useContext(index.RouterContext) || {};
26
+ index.LoggerInstance.debug(`WraperRouter info >>>`, {
27
+ ...routerContextProps,
28
+ routerContextProps,
29
+ WraperRouterProps: props
30
+ });
31
+ if (routerContextProps == null ? void 0 : routerContextProps.memoryRoute) {
32
+ return /* @__PURE__ */ React.createElement(
33
+ ReactRouterDom__namespace.MemoryRouter,
34
+ {
35
+ ...props,
36
+ initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
37
+ }
38
+ );
39
+ }
40
+ return /* @__PURE__ */ React.createElement(
41
+ ReactRouterDom__namespace.BrowserRouter,
42
+ {
43
+ ...propsRes,
44
+ basename: (routerContextProps == null ? void 0 : routerContextProps.basename) || basename
45
+ }
46
+ );
47
+ }
48
+ function WraperRouterProvider(props) {
49
+ const { router, ...propsRes } = props;
50
+ const routerContextProps = React.useContext(index.RouterContext) || {};
51
+ const routers = router.routes;
52
+ index.LoggerInstance.debug(`WraperRouterProvider info >>>`, {
53
+ ...routerContextProps,
54
+ routerContextProps,
55
+ WraperRouterProviderProps: props,
56
+ router
57
+ });
58
+ const RouterProvider = ReactRouterDom__namespace["RouterProvider"];
59
+ const createMemoryRouter = ReactRouterDom__namespace["createMemoryRouter"];
60
+ const createBrowserRouter = ReactRouterDom__namespace["createBrowserRouter"];
61
+ if (routerContextProps.memoryRoute) {
62
+ const MemeoryRouterInstance = createMemoryRouter(routers, {
63
+ initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
64
+ });
65
+ return /* @__PURE__ */ React.createElement(RouterProvider, { router: MemeoryRouterInstance });
66
+ } else {
67
+ const BrowserRouterInstance = createBrowserRouter(routers, {
68
+ // In host app, the routerContextProps is {}, so we should use router.basename as fallback
69
+ basename: routerContextProps.basename || router.basename,
70
+ future: router.future,
71
+ window: router.window
72
+ });
73
+ return /* @__PURE__ */ React.createElement(RouterProvider, { ...propsRes, router: BrowserRouterInstance });
74
+ }
75
+ }
76
+ exports.BrowserRouter = WraperRouter;
77
+ exports.RouterProvider = WraperRouterProvider;
78
+ Object.keys(ReactRouterDom).forEach((k) => {
79
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
80
+ enumerable: true,
81
+ get: () => ReactRouterDom[k]
82
+ });
83
+ });
@@ -0,0 +1,20 @@
1
+ import { default as default_2 } from 'react';
2
+ import * as ReactRouterDom from 'react-router';
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";
10
+
11
+ export { }
12
+
13
+
14
+ declare module '@module-federation/runtime-core' {
15
+ interface ModuleFederation {
16
+ createLazyComponent<T, E extends keyof T>(options: Omit<CreateLazyComponentOptions<T, E>, 'instance'>): ReturnType<typeof createLazyComponent<T, E>>;
17
+ prefetch(options: Omit<PrefetchOptions, 'instance'>): ReturnType<typeof prefetch>;
18
+ collectSSRAssets(options: Omit<Parameters<typeof collectSSRAssets>[0], 'instance'>): ReturnType<typeof collectSSRAssets>;
19
+ }
20
+ }
@@ -0,0 +1,61 @@
1
+ import React__default, { useContext } from "react";
2
+ import * as ReactRouterDom from 'react-router/dist/production/index.js';
3
+ export * from 'react-router/dist/production/index.js';
4
+ import { R as RouterContext, L as LoggerInstance } from "./index-Dm-M9ouh.mjs";
5
+ function WraperRouter(props) {
6
+ const { basename, ...propsRes } = props;
7
+ const routerContextProps = useContext(RouterContext) || {};
8
+ LoggerInstance.debug(`WraperRouter info >>>`, {
9
+ ...routerContextProps,
10
+ routerContextProps,
11
+ WraperRouterProps: props
12
+ });
13
+ if (routerContextProps == null ? void 0 : routerContextProps.memoryRoute) {
14
+ return /* @__PURE__ */ React__default.createElement(
15
+ ReactRouterDom.MemoryRouter,
16
+ {
17
+ ...props,
18
+ initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
19
+ }
20
+ );
21
+ }
22
+ return /* @__PURE__ */ React__default.createElement(
23
+ ReactRouterDom.BrowserRouter,
24
+ {
25
+ ...propsRes,
26
+ basename: (routerContextProps == null ? void 0 : routerContextProps.basename) || basename
27
+ }
28
+ );
29
+ }
30
+ function WraperRouterProvider(props) {
31
+ const { router, ...propsRes } = props;
32
+ const routerContextProps = useContext(RouterContext) || {};
33
+ const routers = router.routes;
34
+ LoggerInstance.debug(`WraperRouterProvider info >>>`, {
35
+ ...routerContextProps,
36
+ routerContextProps,
37
+ WraperRouterProviderProps: props,
38
+ router
39
+ });
40
+ const RouterProvider = ReactRouterDom["RouterProvider"];
41
+ const createMemoryRouter = ReactRouterDom["createMemoryRouter"];
42
+ const createBrowserRouter = ReactRouterDom["createBrowserRouter"];
43
+ if (routerContextProps.memoryRoute) {
44
+ const MemeoryRouterInstance = createMemoryRouter(routers, {
45
+ initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
46
+ });
47
+ return /* @__PURE__ */ React__default.createElement(RouterProvider, { router: MemeoryRouterInstance });
48
+ } else {
49
+ const BrowserRouterInstance = createBrowserRouter(routers, {
50
+ // In host app, the routerContextProps is {}, so we should use router.basename as fallback
51
+ basename: routerContextProps.basename || router.basename,
52
+ future: router.future,
53
+ window: router.window
54
+ });
55
+ return /* @__PURE__ */ React__default.createElement(RouterProvider, { ...propsRes, router: BrowserRouterInstance });
56
+ }
57
+ }
58
+ export {
59
+ WraperRouter as BrowserRouter,
60
+ WraperRouterProvider as RouterProvider
61
+ };
package/dist/v18.cjs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const client = require("react-dom/client");
4
- const bridgeBase = require("./bridge-base-Bn6DO0Fi.js");
4
+ const bridgeBase = require("./bridge-base-CTNdBioh.js");
5
5
  function createReact18Root(container, options) {
6
6
  return client.createRoot(container, options);
7
7
  }
package/dist/v18.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRoot } from "react-dom/client";
2
- import { c as createBaseBridgeComponent } from "./bridge-base-DxcR1fja.mjs";
2
+ import { c as createBaseBridgeComponent } from "./bridge-base-29j7dZKh.mjs";
3
3
  function createReact18Root(container, options) {
4
4
  return createRoot(container, options);
5
5
  }
package/dist/v19.cjs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const client = require("react-dom/client");
4
- const bridgeBase = require("./bridge-base-Bn6DO0Fi.js");
4
+ const bridgeBase = require("./bridge-base-CTNdBioh.js");
5
5
  function createReact19Root(container, options) {
6
6
  return client.createRoot(container, options);
7
7
  }
package/dist/v19.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRoot } from "react-dom/client";
2
- import { c as createBaseBridgeComponent } from "./bridge-base-DxcR1fja.mjs";
2
+ import { c as createBaseBridgeComponent } from "./bridge-base-29j7dZKh.mjs";
3
3
  function createReact19Root(container, options) {
4
4
  return createRoot(container, options);
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/bridge-react",
3
- "version": "0.0.0-refactor-manifest-20251016072532",
3
+ "version": "0.0.0-research-issue-4085-20251016232757",
4
4
  "sideEffects": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -51,6 +51,11 @@
51
51
  "import": "./dist/router-v6.es.js",
52
52
  "require": "./dist/router-v6.cjs.js"
53
53
  },
54
+ "./router-v7": {
55
+ "types": "./dist/router-v7.d.ts",
56
+ "import": "./dist/router-v7.es.js",
57
+ "require": "./dist/router-v7.cjs.js"
58
+ },
54
59
  "./lazy-utils": {
55
60
  "types": "./dist/lazy-utils.d.ts",
56
61
  "import": "./dist/lazy-utils.es.js",
@@ -95,13 +100,22 @@
95
100
  "dependencies": {
96
101
  "react-error-boundary": "^4.1.2",
97
102
  "lru-cache": "^10.4.3",
98
- "@module-federation/sdk": "0.0.0-refactor-manifest-20251016072532",
99
- "@module-federation/bridge-shared": "0.0.0-refactor-manifest-20251016072532"
103
+ "@module-federation/sdk": "0.0.0-research-issue-4085-20251016232757",
104
+ "@module-federation/bridge-shared": "0.0.0-research-issue-4085-20251016232757"
100
105
  },
101
106
  "peerDependencies": {
102
107
  "react": ">=16.9.0",
103
108
  "react-dom": ">=16.9.0",
104
- "react-router-dom": "^4 || ^5 || ^6 || ^7"
109
+ "react-router-dom": "^4 || ^5 || ^6 || ^7",
110
+ "react-router": "^7"
111
+ },
112
+ "peerDependenciesMeta": {
113
+ "react-router-dom": {
114
+ "optional": true
115
+ },
116
+ "react-router": {
117
+ "optional": true
118
+ }
105
119
  },
106
120
  "devDependencies": {
107
121
  "@testing-library/react": "15.0.7",
@@ -114,12 +128,13 @@
114
128
  "react": "18.3.1",
115
129
  "react-dom": "18.3.1",
116
130
  "react-router-dom": "6.22.3",
131
+ "react-router": "7.9.4",
117
132
  "typescript": "^5.2.2",
118
133
  "vite": "^5.4.20",
119
134
  "vite-plugin-dts": "^4.3.0",
120
135
  "hono": "3.12.12",
121
- "@module-federation/runtime": "0.0.0-refactor-manifest-20251016072532",
122
- "@module-federation/runtime-core": "0.0.0-refactor-manifest-20251016072532"
136
+ "@module-federation/runtime": "0.0.0-research-issue-4085-20251016232757",
137
+ "@module-federation/runtime-core": "0.0.0-research-issue-4085-20251016232757"
123
138
  },
124
139
  "scripts": {
125
140
  "dev": "vite",
@@ -64,7 +64,7 @@ export function createBaseBridgeComponent<T>({
64
64
  const beforeBridgeRenderRes =
65
65
  instance?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(info) || {};
66
66
 
67
- const rootComponentWithErrorBoundary = (
67
+ const BridgeWrapper = ({ basename }: { basename?: string }) => (
68
68
  <ErrorBoundary
69
69
  FallbackComponent={fallback as React.ComponentType<FallbackProps>}
70
70
  >
@@ -77,6 +77,7 @@ export function createBaseBridgeComponent<T>({
77
77
  propsInfo={
78
78
  {
79
79
  ...propsInfo,
80
+ basename,
80
81
  ...(beforeBridgeRenderRes as any)?.extraProps,
81
82
  } as T
82
83
  }
@@ -84,6 +85,10 @@ export function createBaseBridgeComponent<T>({
84
85
  </ErrorBoundary>
85
86
  );
86
87
 
88
+ const rootComponentWithErrorBoundary = (
89
+ <BridgeWrapper basename={basename} />
90
+ );
91
+
87
92
  if (bridgeInfo.render) {
88
93
  await Promise.resolve(
89
94
  bridgeInfo.render(rootComponentWithErrorBoundary, dom),
@@ -111,7 +116,7 @@ export function createBaseBridgeComponent<T>({
111
116
  if ('unmount' in root) {
112
117
  root.unmount();
113
118
  } else {
114
- console.warn('Root does not have unmount method');
119
+ LoggerInstance.warn('Root does not have unmount method');
115
120
  }
116
121
  rootMap.delete(dom);
117
122
  }
@@ -5,6 +5,7 @@
5
5
  import type { ProviderFnParams } from '../../types';
6
6
  import { createBaseBridgeComponent } from './bridge-base';
7
7
  import ReactDOM from 'react-dom';
8
+ import { LoggerInstance } from '../../utils';
8
9
 
9
10
  export interface CreateRootOptions {
10
11
  identifierPrefix?: string;
@@ -58,7 +59,7 @@ export function createReact16Or17Root(
58
59
  * Provide warning for React 18
59
60
  */
60
61
  if (isReact18) {
61
- console.warn(
62
+ LoggerInstance.warn(
62
63
  `[Bridge-React] React 18 detected in legacy mode. ` +
63
64
  `For better compatibility, please use the version-specific import: ` +
64
65
  `import { createBridgeComponent } from '@module-federation/bridge-react/v18'`,
@@ -0,0 +1,75 @@
1
+ import React, { useContext } from 'react';
2
+ // The upper alias react-router$ into this file avoids the loop
3
+ // React Router v7 uses different dist structure, we'll import from the main entry
4
+ import * as ReactRouterDom from 'react-router';
5
+ import { RouterContext } from '../provider/context';
6
+ import { LoggerInstance } from '../utils';
7
+
8
+ function WraperRouter(
9
+ props:
10
+ | Parameters<typeof ReactRouterDom.BrowserRouter>[0]
11
+ | Parameters<typeof ReactRouterDom.MemoryRouter>[0],
12
+ ) {
13
+ const { basename, ...propsRes } = props;
14
+ const routerContextProps = useContext(RouterContext) || {};
15
+
16
+ LoggerInstance.debug(`WraperRouter info >>>`, {
17
+ ...routerContextProps,
18
+ routerContextProps,
19
+ WraperRouterProps: props,
20
+ });
21
+
22
+ if (routerContextProps?.memoryRoute) {
23
+ return (
24
+ <ReactRouterDom.MemoryRouter
25
+ {...props}
26
+ initialEntries={[routerContextProps?.memoryRoute.entryPath]}
27
+ />
28
+ );
29
+ }
30
+ return (
31
+ <ReactRouterDom.BrowserRouter
32
+ {...propsRes}
33
+ basename={routerContextProps?.basename || basename}
34
+ />
35
+ );
36
+ }
37
+
38
+ function WraperRouterProvider(
39
+ props: Parameters<typeof ReactRouterDom.RouterProvider>[0],
40
+ ) {
41
+ const { router, ...propsRes } = props;
42
+ const routerContextProps = useContext(RouterContext) || {};
43
+ const routers = router.routes;
44
+ LoggerInstance.debug(`WraperRouterProvider info >>>`, {
45
+ ...routerContextProps,
46
+ routerContextProps,
47
+ WraperRouterProviderProps: props,
48
+ router,
49
+ });
50
+ const RouterProvider = (ReactRouterDom as any)['Router' + 'Provider'];
51
+ const createMemoryRouter = (ReactRouterDom as any)['create' + 'MemoryRouter'];
52
+ const createBrowserRouter = (ReactRouterDom as any)[
53
+ 'create' + 'BrowserRouter'
54
+ ];
55
+
56
+ if (routerContextProps.memoryRoute) {
57
+ const MemeoryRouterInstance = createMemoryRouter(routers, {
58
+ initialEntries: [routerContextProps?.memoryRoute.entryPath],
59
+ });
60
+ return <RouterProvider router={MemeoryRouterInstance} />;
61
+ } else {
62
+ const BrowserRouterInstance = createBrowserRouter(routers, {
63
+ // In host app, the routerContextProps is {}, so we should use router.basename as fallback
64
+ basename: routerContextProps.basename || router.basename,
65
+ future: router.future,
66
+ window: router.window,
67
+ });
68
+ return <RouterProvider {...propsRes} router={BrowserRouterInstance} />;
69
+ }
70
+ }
71
+
72
+ // Export all from react-router for v7 compatibility
73
+ export * from 'react-router';
74
+ export { WraperRouter as BrowserRouter };
75
+ export { WraperRouterProvider as RouterProvider };
package/vite.config.ts CHANGED
@@ -24,6 +24,7 @@ export default defineConfig({
24
24
  router: path.resolve(__dirname, 'src/router/default.tsx'),
25
25
  'router-v5': path.resolve(__dirname, 'src/router/v5.tsx'),
26
26
  'router-v6': path.resolve(__dirname, 'src/router/v6.tsx'),
27
+ 'router-v7': path.resolve(__dirname, 'src/router/v7.tsx'),
27
28
  v18: path.resolve(__dirname, 'src/v18.ts'),
28
29
  v19: path.resolve(__dirname, 'src/v19.ts'),
29
30
  'lazy-load-component-plugin': path.resolve(
@@ -49,6 +50,12 @@ export default defineConfig({
49
50
  '@remix-run/router',
50
51
  /react-dom\/.*/,
51
52
  'react-router',
53
+ 'react-router/',
54
+ 'react-router/index.js',
55
+ 'react-router/dist/index.js',
56
+ 'react-router/dist/development/index.js',
57
+ 'react-router/dist/production/index.js',
58
+ /^react-router\/.*/,
52
59
  'react-router-dom/',
53
60
  'react-router-dom/index.js',
54
61
  'react-router-dom/dist/index.js',
@@ -67,6 +74,23 @@ export default defineConfig({
67
74
  );
68
75
  }
69
76
 
77
+ if (fileName.includes('router-v7') && chunk.type === 'chunk') {
78
+ // Replace 'react-router' with the correct v7 dist path based on environment
79
+ const isProduction = process.env.NODE_ENV === 'production';
80
+ const distPath = isProduction
81
+ ? 'react-router/dist/production/index.js'
82
+ : 'react-router/dist/development/index.js';
83
+
84
+ chunk.code = chunk.code.replace(
85
+ /from\s+['"`]react-router['"`]/g,
86
+ `from '${distPath}'`,
87
+ );
88
+ chunk.code = chunk.code.replace(
89
+ /export\s+\*\s+from\s+['"`]react-router['"`]/g,
90
+ `export * from '${distPath}'`,
91
+ );
92
+ }
93
+
70
94
  if (fileName.includes('router-v5') && chunk.type === 'chunk') {
71
95
  chunk.code = chunk.code.replace(
72
96
  // Match 'react-router-dom/' followed by single quotes, double quotes, or backticks, replacing only 'react-router-dom/' to react-router-v5 dist file structure