@module-federation/bridge-react 0.0.0-next-20250126041131 → 0.0.0-next-20250208084948

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,11 +1,20 @@
1
1
  # @module-federation/bridge-react
2
2
 
3
- ## 0.0.0-next-20250126041131
3
+ ## 0.0.0-next-20250208084948
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - @module-federation/sdk@0.0.0-next-20250126041131
8
- - @module-federation/bridge-shared@0.0.0-next-20250126041131
7
+ - c3387db: fix: the bridge-react package was failing when used with React 16 due to missing react-dom/client module
8
+ - @module-federation/sdk@0.0.0-next-20250208084948
9
+ - @module-federation/bridge-shared@0.0.0-next-20250208084948
10
+
11
+ ## 0.8.10
12
+
13
+ ### Patch Changes
14
+
15
+ - e751ad0: change rollup config to prevent react-dom/client code being bundled into the bridge-react package
16
+ - @module-federation/sdk@0.8.10
17
+ - @module-federation/bridge-shared@0.8.10
9
18
 
10
19
  ## 0.8.9
11
20
 
@@ -323,18 +323,6 @@ createLogger(PREFIX);
323
323
  const LoggerInstance = createLogger(
324
324
  "[ Module Federation Bridge React ]"
325
325
  );
326
- function atLeastReact18(React2) {
327
- if (React2 && typeof React2.version === "string" && React2.version.indexOf(".") >= 0) {
328
- const majorVersionString = React2.version.split(".")[0];
329
- try {
330
- return Number(majorVersionString) >= 18;
331
- } catch (err) {
332
- return false;
333
- }
334
- } else {
335
- return false;
336
- }
337
- }
338
326
  function pathJoin(...args) {
339
327
  const res = args.reduce((res2, path) => {
340
328
  let nPath = path;
@@ -372,6 +360,5 @@ const getRootDomDefaultClassName = (moduleName) => {
372
360
  const RouterContext = React.createContext(null);
373
361
  exports.LoggerInstance = LoggerInstance;
374
362
  exports.RouterContext = RouterContext;
375
- exports.atLeastReact18 = atLeastReact18;
376
363
  exports.getRootDomDefaultClassName = getRootDomDefaultClassName;
377
364
  exports.pathJoin = pathJoin;
@@ -322,18 +322,6 @@ createLogger(PREFIX);
322
322
  const LoggerInstance = createLogger(
323
323
  "[ Module Federation Bridge React ]"
324
324
  );
325
- function atLeastReact18(React2) {
326
- if (React2 && typeof React2.version === "string" && React2.version.indexOf(".") >= 0) {
327
- const majorVersionString = React2.version.split(".")[0];
328
- try {
329
- return Number(majorVersionString) >= 18;
330
- } catch (err) {
331
- return false;
332
- }
333
- } else {
334
- return false;
335
- }
336
- }
337
325
  function pathJoin(...args) {
338
326
  const res = args.reduce((res2, path) => {
339
327
  let nPath = path;
@@ -372,7 +360,6 @@ const RouterContext = React__default.createContext(null);
372
360
  export {
373
361
  LoggerInstance as L,
374
362
  RouterContext as R,
375
- atLeastReact18 as a,
376
363
  getRootDomDefaultClassName as g,
377
364
  pathJoin as p
378
365
  };
package/dist/index.cjs.js CHANGED
@@ -1,7 +1,29 @@
1
1
  "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
2
24
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
25
  const React = require("react");
4
- const context = require("./context-DS0wRSh7.cjs");
26
+ const context = require("./context-BwD5jfgB.cjs");
5
27
  const ReactRouterDOM = require("react-router-dom");
6
28
  const plugin = require("./plugin.cjs.js");
7
29
  const ReactDOM = require("react-dom");
@@ -212,7 +234,7 @@ const RemoteAppWrapper = React.forwardRef(function(props, ref) {
212
234
  }
213
235
  );
214
236
  };
215
- RemoteApp2["__APP_VERSION__"] = "0.8.9";
237
+ RemoteApp2["__APP_VERSION__"] = "0.8.10";
216
238
  return /* @__PURE__ */ React.createElement(RemoteApp2, null);
217
239
  });
218
240
  function withRouterData(WrappedComponent) {
@@ -295,14 +317,14 @@ function createLazyRemoteComponent(info) {
295
317
  exportName
296
318
  });
297
319
  try {
298
- const m2 = await info.loader();
299
- const moduleName = m2 && m2[Symbol.for("mf_module_id")];
320
+ const m = await info.loader();
321
+ const moduleName = m && m[Symbol.for("mf_module_id")];
300
322
  context.LoggerInstance.debug(
301
323
  `createRemoteComponent LazyComponent loadRemote info >>>`,
302
- { name: moduleName, module: m2, exportName }
324
+ { name: moduleName, module: m, exportName }
303
325
  );
304
- const exportFn = m2[exportName];
305
- if (exportName in m2 && typeof exportFn === "function") {
326
+ const exportFn = m[exportName];
327
+ if (exportName in m && typeof exportFn === "function") {
306
328
  const RemoteAppComponent = React.forwardRef((props, ref) => {
307
329
  return /* @__PURE__ */ React.createElement(
308
330
  RemoteApp,
@@ -322,7 +344,7 @@ function createLazyRemoteComponent(info) {
322
344
  } else {
323
345
  context.LoggerInstance.debug(
324
346
  `createRemoteComponent LazyComponent module not found >>>`,
325
- { name: moduleName, module: m2, exportName }
347
+ { name: moduleName, module: m, exportName }
326
348
  );
327
349
  throw Error(
328
350
  `Make sure that ${moduleName} has the correct export when export is ${String(
@@ -343,30 +365,6 @@ function createRemoteComponent(info) {
343
365
  }
344
366
  );
345
367
  }
346
- var client = {};
347
- var m = ReactDOM;
348
- if (process.env.NODE_ENV === "production") {
349
- client.createRoot = m.createRoot;
350
- client.hydrateRoot = m.hydrateRoot;
351
- } else {
352
- var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
353
- client.createRoot = function(c, o) {
354
- i.usingClientEntryPoint = true;
355
- try {
356
- return m.createRoot(c, o);
357
- } finally {
358
- i.usingClientEntryPoint = false;
359
- }
360
- };
361
- client.hydrateRoot = function(c, h, o) {
362
- i.usingClientEntryPoint = true;
363
- try {
364
- return m.hydrateRoot(c, h, o);
365
- } finally {
366
- i.usingClientEntryPoint = false;
367
- }
368
- };
369
- }
370
368
  function createBridgeComponent(bridgeInfo) {
371
369
  return () => {
372
370
  const rootMap = /* @__PURE__ */ new Map();
@@ -400,53 +398,45 @@ function createBridgeComponent(bridgeInfo) {
400
398
  ...propsInfo
401
399
  } = info;
402
400
  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)) || {};
403
- const rootComponentWithErrorBoundary = (
404
- // set ErrorBoundary for RawComponent rendering error, usually caused by user app rendering error
405
- /* @__PURE__ */ React__namespace.createElement(ErrorBoundary, { FallbackComponent: fallback }, /* @__PURE__ */ React__namespace.createElement(
406
- RawComponent,
407
- {
408
- appInfo: {
409
- moduleName,
410
- basename,
411
- memoryRoute
412
- },
413
- propsInfo: { ...propsInfo, ...beforeBridgeRenderRes == null ? void 0 : beforeBridgeRenderRes.extraProps }
414
- }
415
- ))
416
- );
417
- if (context.atLeastReact18(React__namespace)) {
418
- if (bridgeInfo == null ? void 0 : bridgeInfo.render) {
419
- Promise.resolve(
420
- bridgeInfo == null ? void 0 : bridgeInfo.render(rootComponentWithErrorBoundary, dom)
421
- ).then((root) => rootMap.set(info.dom, root));
422
- } else {
423
- const root = client.createRoot(info.dom);
424
- root.render(rootComponentWithErrorBoundary);
425
- rootMap.set(info.dom, root);
401
+ const rootComponentWithErrorBoundary = /* @__PURE__ */ React__namespace.createElement(ErrorBoundary, { FallbackComponent: fallback }, /* @__PURE__ */ React__namespace.createElement(
402
+ RawComponent,
403
+ {
404
+ appInfo: {
405
+ moduleName,
406
+ basename,
407
+ memoryRoute
408
+ },
409
+ propsInfo: { ...propsInfo, ...beforeBridgeRenderRes == null ? void 0 : beforeBridgeRenderRes.extraProps }
426
410
  }
411
+ ));
412
+ if (bridgeInfo == null ? void 0 : bridgeInfo.render) {
413
+ Promise.resolve(
414
+ bridgeInfo == null ? void 0 : bridgeInfo.render(rootComponentWithErrorBoundary, dom)
415
+ ).then((root) => rootMap.set(info.dom, root));
427
416
  } else {
428
- const renderFn = (bridgeInfo == null ? void 0 : bridgeInfo.render) || ReactDOM.render;
429
- renderFn == null ? void 0 : renderFn(rootComponentWithErrorBoundary, info.dom);
417
+ import("react-dom/client").then(
418
+ (ReactDOMClient) => {
419
+ const root = ReactDOMClient.createRoot(info.dom);
420
+ root.render(rootComponentWithErrorBoundary);
421
+ rootMap.set(info.dom, root);
422
+ }
423
+ );
430
424
  }
431
425
  ((_f = (_e = (_d = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _d.lifecycle) == null ? void 0 : _e.afterBridgeRender) == null ? void 0 : _f.emit(info)) || {};
432
426
  },
433
- async destroy(info) {
434
- var _a, _b, _c, _d, _e, _f;
435
- context.LoggerInstance.debug(`createBridgeComponent destroy Info`, {
436
- dom: info.dom
437
- });
438
- (_c = (_b = (_a = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _a.lifecycle) == null ? void 0 : _b.beforeBridgeDestroy) == null ? void 0 : _c.emit(info);
439
- if (context.atLeastReact18(React__namespace)) {
440
- const root = rootMap.get(info.dom);
441
- root == null ? void 0 : root.unmount();
427
+ destroy(info) {
428
+ var _a, _b, _c;
429
+ context.LoggerInstance.debug(`createBridgeComponent destroy Info`, info);
430
+ const root = rootMap.get(info.dom);
431
+ if (root) {
432
+ if ("unmount" in root) {
433
+ root.unmount();
434
+ } else {
435
+ ReactDOM.unmountComponentAtNode(root);
436
+ }
442
437
  rootMap.delete(info.dom);
443
- } else {
444
- ReactDOM.unmountComponentAtNode(info.dom);
445
438
  }
446
- (_f = (_e = (_d = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _d.lifecycle) == null ? void 0 : _e.afterBridgeDestroy) == null ? void 0 : _f.emit(info);
447
- },
448
- rawComponent: bridgeInfo.rootComponent,
449
- __BRIDGE_FN__: (_args) => {
439
+ (_c = (_b = (_a = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _a.lifecycle) == null ? void 0 : _b.destroyBridge) == null ? void 0 : _c.emit(info);
450
440
  }
451
441
  };
452
442
  };
package/dist/index.d.ts CHANGED
@@ -1,19 +1,27 @@
1
1
  import { ComponentType } from 'react';
2
2
  import { default as default_2 } from 'react';
3
- import { default as default_3 } from 'react-dom/client';
4
3
  import { ErrorInfo } from 'react';
5
4
  import { PropsWithChildren } from 'react';
6
5
  import * as React_2 from 'react';
7
6
 
8
7
  export declare function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>): () => {
9
8
  render(info: RenderParams): Promise<void>;
10
- destroy(info: DestroyParams): Promise<void>;
11
- rawComponent: React_2.ComponentType<T>;
12
- __BRIDGE_FN__: (_args: T) => void;
9
+ destroy(info: DestroyParams): void;
13
10
  };
14
11
 
15
12
  export declare function createRemoteComponent<T, E extends keyof T>(info: LazyRemoteComponentInfo<T, E>): default_2.ForwardRefExoticComponent<default_2.PropsWithoutRef<ProviderParams & ("__BRIDGE_FN__" extends keyof (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never) ? (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"] extends (...args: any) => any ? Parameters<(T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"]>[0] : {} : {})> & default_2.RefAttributes<HTMLDivElement>>;
16
13
 
14
+ /**
15
+ * Creates a root for a container element compatible with both React 16 and 18
16
+ */
17
+ declare function createRoot(container: Element | DocumentFragment, options?: CreateRootOptions): Root;
18
+
19
+ declare interface CreateRootOptions {
20
+ identifierPrefix?: string;
21
+ onRecoverableError?: (error: unknown) => void;
22
+ transitionCallbacks?: unknown;
23
+ }
24
+
17
25
  declare type DestroyParams = {
18
26
  moduleName: string;
19
27
  dom: HTMLElement;
@@ -73,6 +81,11 @@ declare type RenderParams = RenderFnParams & {
73
81
  [key: string]: unknown;
74
82
  };
75
83
 
76
- declare type RootType = HTMLElement | default_3.Root;
84
+ declare interface Root {
85
+ render(children: React.ReactNode): void;
86
+ unmount(): void;
87
+ }
88
+
89
+ declare type RootType = HTMLElement | ReturnType<typeof createRoot>;
77
90
 
78
91
  export { }
package/dist/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import React__default, { createContext, Component, createElement, forwardRef, useRef, useEffect, useContext, useState } from "react";
3
- import { L as LoggerInstance, g as getRootDomDefaultClassName, p as pathJoin, a as atLeastReact18, R as RouterContext } from "./context-BgBVJ06L.js";
3
+ import { L as LoggerInstance, g as getRootDomDefaultClassName, p as pathJoin, R as RouterContext } from "./context-BwUPFSB2.js";
4
4
  import * as ReactRouterDOM from "react-router-dom";
5
5
  import { federationRuntime } from "./plugin.es.js";
6
6
  import ReactDOM from "react-dom";
@@ -193,7 +193,7 @@ const RemoteAppWrapper = forwardRef(function(props, ref) {
193
193
  }
194
194
  );
195
195
  };
196
- RemoteApp2["__APP_VERSION__"] = "0.8.9";
196
+ RemoteApp2["__APP_VERSION__"] = "0.8.10";
197
197
  return /* @__PURE__ */ React__default.createElement(RemoteApp2, null);
198
198
  });
199
199
  function withRouterData(WrappedComponent) {
@@ -276,14 +276,14 @@ function createLazyRemoteComponent(info) {
276
276
  exportName
277
277
  });
278
278
  try {
279
- const m2 = await info.loader();
280
- const moduleName = m2 && m2[Symbol.for("mf_module_id")];
279
+ const m = await info.loader();
280
+ const moduleName = m && m[Symbol.for("mf_module_id")];
281
281
  LoggerInstance.debug(
282
282
  `createRemoteComponent LazyComponent loadRemote info >>>`,
283
- { name: moduleName, module: m2, exportName }
283
+ { name: moduleName, module: m, exportName }
284
284
  );
285
- const exportFn = m2[exportName];
286
- if (exportName in m2 && typeof exportFn === "function") {
285
+ const exportFn = m[exportName];
286
+ if (exportName in m && typeof exportFn === "function") {
287
287
  const RemoteAppComponent = forwardRef((props, ref) => {
288
288
  return /* @__PURE__ */ React__default.createElement(
289
289
  RemoteApp,
@@ -303,7 +303,7 @@ function createLazyRemoteComponent(info) {
303
303
  } else {
304
304
  LoggerInstance.debug(
305
305
  `createRemoteComponent LazyComponent module not found >>>`,
306
- { name: moduleName, module: m2, exportName }
306
+ { name: moduleName, module: m, exportName }
307
307
  );
308
308
  throw Error(
309
309
  `Make sure that ${moduleName} has the correct export when export is ${String(
@@ -324,30 +324,6 @@ function createRemoteComponent(info) {
324
324
  }
325
325
  );
326
326
  }
327
- var client = {};
328
- var m = ReactDOM;
329
- if (process.env.NODE_ENV === "production") {
330
- client.createRoot = m.createRoot;
331
- client.hydrateRoot = m.hydrateRoot;
332
- } else {
333
- var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
334
- client.createRoot = function(c, o) {
335
- i.usingClientEntryPoint = true;
336
- try {
337
- return m.createRoot(c, o);
338
- } finally {
339
- i.usingClientEntryPoint = false;
340
- }
341
- };
342
- client.hydrateRoot = function(c, h, o) {
343
- i.usingClientEntryPoint = true;
344
- try {
345
- return m.hydrateRoot(c, h, o);
346
- } finally {
347
- i.usingClientEntryPoint = false;
348
- }
349
- };
350
- }
351
327
  function createBridgeComponent(bridgeInfo) {
352
328
  return () => {
353
329
  const rootMap = /* @__PURE__ */ new Map();
@@ -381,53 +357,45 @@ function createBridgeComponent(bridgeInfo) {
381
357
  ...propsInfo
382
358
  } = info;
383
359
  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)) || {};
384
- const rootComponentWithErrorBoundary = (
385
- // set ErrorBoundary for RawComponent rendering error, usually caused by user app rendering error
386
- /* @__PURE__ */ React.createElement(ErrorBoundary, { FallbackComponent: fallback }, /* @__PURE__ */ React.createElement(
387
- RawComponent,
388
- {
389
- appInfo: {
390
- moduleName,
391
- basename,
392
- memoryRoute
393
- },
394
- propsInfo: { ...propsInfo, ...beforeBridgeRenderRes == null ? void 0 : beforeBridgeRenderRes.extraProps }
395
- }
396
- ))
397
- );
398
- if (atLeastReact18(React)) {
399
- if (bridgeInfo == null ? void 0 : bridgeInfo.render) {
400
- Promise.resolve(
401
- bridgeInfo == null ? void 0 : bridgeInfo.render(rootComponentWithErrorBoundary, dom)
402
- ).then((root) => rootMap.set(info.dom, root));
403
- } else {
404
- const root = client.createRoot(info.dom);
405
- root.render(rootComponentWithErrorBoundary);
406
- rootMap.set(info.dom, root);
360
+ const rootComponentWithErrorBoundary = /* @__PURE__ */ React.createElement(ErrorBoundary, { FallbackComponent: fallback }, /* @__PURE__ */ React.createElement(
361
+ RawComponent,
362
+ {
363
+ appInfo: {
364
+ moduleName,
365
+ basename,
366
+ memoryRoute
367
+ },
368
+ propsInfo: { ...propsInfo, ...beforeBridgeRenderRes == null ? void 0 : beforeBridgeRenderRes.extraProps }
407
369
  }
370
+ ));
371
+ if (bridgeInfo == null ? void 0 : bridgeInfo.render) {
372
+ Promise.resolve(
373
+ bridgeInfo == null ? void 0 : bridgeInfo.render(rootComponentWithErrorBoundary, dom)
374
+ ).then((root) => rootMap.set(info.dom, root));
408
375
  } else {
409
- const renderFn = (bridgeInfo == null ? void 0 : bridgeInfo.render) || ReactDOM.render;
410
- renderFn == null ? void 0 : renderFn(rootComponentWithErrorBoundary, info.dom);
376
+ import("react-dom/client").then(
377
+ (ReactDOMClient) => {
378
+ const root = ReactDOMClient.createRoot(info.dom);
379
+ root.render(rootComponentWithErrorBoundary);
380
+ rootMap.set(info.dom, root);
381
+ }
382
+ );
411
383
  }
412
384
  ((_f = (_e = (_d = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _d.lifecycle) == null ? void 0 : _e.afterBridgeRender) == null ? void 0 : _f.emit(info)) || {};
413
385
  },
414
- async destroy(info) {
415
- var _a, _b, _c, _d, _e, _f;
416
- LoggerInstance.debug(`createBridgeComponent destroy Info`, {
417
- dom: info.dom
418
- });
419
- (_c = (_b = (_a = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _a.lifecycle) == null ? void 0 : _b.beforeBridgeDestroy) == null ? void 0 : _c.emit(info);
420
- if (atLeastReact18(React)) {
421
- const root = rootMap.get(info.dom);
422
- root == null ? void 0 : root.unmount();
386
+ destroy(info) {
387
+ var _a, _b, _c;
388
+ LoggerInstance.debug(`createBridgeComponent destroy Info`, info);
389
+ const root = rootMap.get(info.dom);
390
+ if (root) {
391
+ if ("unmount" in root) {
392
+ root.unmount();
393
+ } else {
394
+ ReactDOM.unmountComponentAtNode(root);
395
+ }
423
396
  rootMap.delete(info.dom);
424
- } else {
425
- ReactDOM.unmountComponentAtNode(info.dom);
426
397
  }
427
- (_f = (_e = (_d = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _d.lifecycle) == null ? void 0 : _e.afterBridgeDestroy) == null ? void 0 : _f.emit(info);
428
- },
429
- rawComponent: bridgeInfo.rootComponent,
430
- __BRIDGE_FN__: (_args) => {
398
+ (_c = (_b = (_a = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _a.lifecycle) == null ? void 0 : _b.destroyBridge) == null ? void 0 : _c.emit(info);
431
399
  }
432
400
  };
433
401
  };
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const React = require("react");
4
4
  const ReactRouterDom$1 = require("react-router-dom/index.js");
5
- const context = require("./context-DS0wRSh7.cjs");
5
+ const context = require("./context-BwD5jfgB.cjs");
6
6
  const ReactRouterDom = require("react-router-dom/index.js");
7
7
  function _interopNamespaceDefault(e) {
8
8
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -1,6 +1,6 @@
1
1
  import React__default, { useContext } from "react";
2
2
  import * as ReactRouterDom$1 from "react-router-dom/index.js";
3
- import { R as RouterContext, L as LoggerInstance } from "./context-BgBVJ06L.js";
3
+ import { R as RouterContext, L as LoggerInstance } from "./context-BwUPFSB2.js";
4
4
  export * from "react-router-dom/index.js";
5
5
  function WraperRouter(props) {
6
6
  const { basename, ...propsRes } = props;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const React = require("react");
4
4
  const ReactRouterDom$1 = require("react-router-dom/dist/index.js");
5
- const context = require("./context-DS0wRSh7.cjs");
5
+ const context = require("./context-BwD5jfgB.cjs");
6
6
  const ReactRouterDom = require("react-router-dom/dist/index.js");
7
7
  function _interopNamespaceDefault(e) {
8
8
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -1,6 +1,6 @@
1
1
  import React__default, { useContext } from "react";
2
2
  import * as ReactRouterDom$1 from "react-router-dom/dist/index.js";
3
- import { R as RouterContext, L as LoggerInstance } from "./context-BgBVJ06L.js";
3
+ import { R as RouterContext, L as LoggerInstance } from "./context-BwUPFSB2.js";
4
4
  export * from "react-router-dom/dist/index.js";
5
5
  function WraperRouter(props) {
6
6
  const { basename, ...propsRes } = props;
@@ -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-DS0wRSh7.cjs");
5
+ const context = require("./context-BwD5jfgB.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
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-BgBVJ06L.js";
4
+ import { R as RouterContext, L as LoggerInstance } from "./context-BwUPFSB2.js";
5
5
  function WrapperRouter(props) {
6
6
  const { basename, ...propsRes } = props;
7
7
  const routerContextProps = useContext(RouterContext) || {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/bridge-react",
3
- "version": "0.0.0-next-20250126041131",
3
+ "version": "0.0.0-next-20250208084948",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -46,8 +46,8 @@
46
46
  "dependencies": {
47
47
  "@loadable/component": "^5.16.4",
48
48
  "react-error-boundary": "^4.1.2",
49
- "@module-federation/bridge-shared": "0.0.0-next-20250126041131",
50
- "@module-federation/sdk": "0.0.0-next-20250126041131"
49
+ "@module-federation/bridge-shared": "0.0.0-next-20250208084948",
50
+ "@module-federation/sdk": "0.0.0-next-20250208084948"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "react": ">=16.9.0",
@@ -68,7 +68,7 @@
68
68
  "typescript": "^5.2.2",
69
69
  "vite": "^5.2.14",
70
70
  "vite-plugin-dts": "^4.3.0",
71
- "@module-federation/runtime": "0.0.0-next-20250126041131"
71
+ "@module-federation/runtime": "0.0.0-next-20250208084948"
72
72
  },
73
73
  "scripts": {
74
74
  "dev": "vite",
package/src/compat.ts ADDED
@@ -0,0 +1,64 @@
1
+ import ReactDOM from 'react-dom';
2
+
3
+ interface CreateRootOptions {
4
+ identifierPrefix?: string;
5
+ onRecoverableError?: (error: unknown) => void;
6
+ transitionCallbacks?: unknown;
7
+ }
8
+
9
+ interface Root {
10
+ render(children: React.ReactNode): void;
11
+ unmount(): void;
12
+ }
13
+
14
+ // Check if we're running React 18
15
+ const isReact18 = ReactDOM.version.startsWith('18');
16
+
17
+ /**
18
+ * Creates a root for a container element compatible with both React 16 and 18
19
+ */
20
+ export function createRoot(
21
+ container: Element | DocumentFragment,
22
+ options?: CreateRootOptions,
23
+ ): Root {
24
+ if (isReact18) {
25
+ // For React 18, use the new createRoot API
26
+ // @ts-ignore - Types will be available in React 18
27
+ return (ReactDOM as any).createRoot(container, options);
28
+ }
29
+
30
+ // For React 16, simulate the new root API using render/unmountComponentAtNode
31
+ return {
32
+ render(children: React.ReactNode) {
33
+ ReactDOM.render(children, container);
34
+ },
35
+ unmount() {
36
+ ReactDOM.unmountComponentAtNode(container);
37
+ },
38
+ };
39
+ }
40
+
41
+ /**
42
+ * Hydrates a container compatible with both React 16 and 18
43
+ */
44
+ export function hydrateRoot(
45
+ container: Element | DocumentFragment,
46
+ initialChildren: React.ReactNode,
47
+ options?: CreateRootOptions,
48
+ ): Root {
49
+ if (isReact18) {
50
+ // For React 18, use the new hydrateRoot API
51
+ // @ts-ignore - Types will be available in React 18
52
+ return (ReactDOM as any).hydrateRoot(container, initialChildren, options);
53
+ }
54
+
55
+ // For React 16, simulate the new root API using hydrate
56
+ return {
57
+ render(children: React.ReactNode) {
58
+ ReactDOM.hydrate(children, container);
59
+ },
60
+ unmount() {
61
+ ReactDOM.unmountComponentAtNode(container);
62
+ },
63
+ };
64
+ }
package/src/provider.tsx CHANGED
@@ -1,15 +1,14 @@
1
- import { useLayoutEffect, useRef, useState } from 'react';
2
1
  import * as React from 'react';
3
2
  import ReactDOM from 'react-dom';
4
- import ReactDOMClient from 'react-dom/client';
5
3
  import type {
6
4
  ProviderParams,
7
5
  RenderFnParams,
8
6
  } from '@module-federation/bridge-shared';
9
7
  import { ErrorBoundary } from 'react-error-boundary';
10
8
  import { RouterContext } from './context';
11
- import { LoggerInstance, atLeastReact18 } from './utils';
9
+ import { LoggerInstance } from './utils';
12
10
  import { federationRuntime } from './plugin';
11
+ import { createRoot } from './compat';
13
12
 
14
13
  type RenderParams = RenderFnParams & {
15
14
  [key: string]: unknown;
@@ -18,7 +17,7 @@ type DestroyParams = {
18
17
  moduleName: string;
19
18
  dom: HTMLElement;
20
19
  };
21
- type RootType = HTMLElement | ReactDOMClient.Root;
20
+ type RootType = HTMLElement | ReturnType<typeof createRoot>;
22
21
 
23
22
  export type ProviderFnParams<T> = {
24
23
  rootComponent: React.ComponentType<T>;
@@ -67,7 +66,6 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
67
66
  instance?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(info) || {};
68
67
 
69
68
  const rootComponentWithErrorBoundary = (
70
- // set ErrorBoundary for RawComponent rendering error, usually caused by user app rendering error
71
69
  <ErrorBoundary FallbackComponent={fallback}>
72
70
  <RawComponent
73
71
  appInfo={{
@@ -81,53 +79,39 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
81
79
  />
82
80
  </ErrorBoundary>
83
81
  );
84
- // call render function
85
- if (atLeastReact18(React)) {
86
- if (bridgeInfo?.render) {
87
- // in case bridgeInfo?.render is an async function, resolve this to promise
88
- Promise.resolve(
89
- bridgeInfo?.render(rootComponentWithErrorBoundary, dom),
90
- ).then((root: RootType) => rootMap.set(info.dom, root));
91
- } else {
92
- const root: RootType = ReactDOMClient.createRoot(info.dom);
93
- root.render(rootComponentWithErrorBoundary);
94
- rootMap.set(info.dom, root);
95
- }
82
+
83
+ if (bridgeInfo?.render) {
84
+ // in case bridgeInfo?.render is an async function, resolve this to promise
85
+ Promise.resolve(
86
+ bridgeInfo?.render(rootComponentWithErrorBoundary, dom),
87
+ ).then((root: RootType) => rootMap.set(info.dom, root));
96
88
  } else {
97
- // react 17 render
98
- const renderFn = bridgeInfo?.render || ReactDOM.render;
99
- renderFn?.(rootComponentWithErrorBoundary, info.dom);
89
+ // Dynamically import react-dom/client
90
+ import('react-dom/client').then(
91
+ (ReactDOMClient: typeof import('react-dom/client')) => {
92
+ const root = ReactDOMClient.createRoot(info.dom);
93
+ root.render(rootComponentWithErrorBoundary);
94
+ rootMap.set(info.dom, root);
95
+ },
96
+ );
100
97
  }
98
+
101
99
  instance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(info) || {};
102
100
  },
103
101
 
104
- async destroy(info: DestroyParams) {
105
- LoggerInstance.debug(`createBridgeComponent destroy Info`, {
106
- dom: info.dom,
107
- });
108
- instance?.bridgeHook?.lifecycle?.beforeBridgeDestroy?.emit(info);
109
-
110
- // call destroy function
111
- if (atLeastReact18(React)) {
112
- const root = rootMap.get(info.dom);
113
- (root as ReactDOMClient.Root)?.unmount();
102
+ destroy(info: DestroyParams) {
103
+ LoggerInstance.debug(`createBridgeComponent destroy Info`, info);
104
+ const root = rootMap.get(info.dom);
105
+ if (root) {
106
+ if ('unmount' in root) {
107
+ root.unmount();
108
+ } else {
109
+ ReactDOM.unmountComponentAtNode(root as HTMLElement);
110
+ }
114
111
  rootMap.delete(info.dom);
115
- } else {
116
- ReactDOM.unmountComponentAtNode(info.dom);
117
112
  }
118
-
119
- instance?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit(info);
113
+ instance?.bridgeHook?.lifecycle?.destroyBridge?.emit(info);
120
114
  },
121
- rawComponent: bridgeInfo.rootComponent,
122
- __BRIDGE_FN__: (_args: T) => {},
123
115
  };
124
116
  };
125
117
  }
126
-
127
- export function ShadowRoot(info: { children: () => JSX.Element }) {
128
- const [root] = useState(null);
129
- const domRef = useRef(null);
130
- useLayoutEffect(() => {});
131
-
132
- return <div ref={domRef}>{root && <info.children />}</div>;
133
- }
package/vite.config.ts CHANGED
@@ -33,6 +33,7 @@ export default defineConfig({
33
33
  external: [
34
34
  ...perDepsKeys,
35
35
  '@remix-run/router',
36
+ /react-dom\/.*/,
36
37
  'react-router',
37
38
  'react-router-dom/',
38
39
  'react-router-dom/index.js',