From 599e61c6854a57c3d4a6b191126d8c1d68361e90 Mon Sep 17 00:00:00 2001 From: fengdanping Date: Tue, 2 Sep 2025 13:26:00 +0800 Subject: [PATCH 1/3] fix(bridge-react-webpack-plugin): proxying react-router failed in the modernjs projects --- .changeset/fair-hounds-sleep.md | 6 +++ .../bridge-react-webpack-plugin/src/index.ts | 40 +++++++++---------- .../src/wrapper/ModuleFederationPlugin.ts | 19 ++++----- 3 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 .changeset/fair-hounds-sleep.md diff --git a/.changeset/fair-hounds-sleep.md b/.changeset/fair-hounds-sleep.md new file mode 100644 index 00000000000..eabf4a40f1d --- /dev/null +++ b/.changeset/fair-hounds-sleep.md @@ -0,0 +1,6 @@ +--- +'@module-federation/bridge-react-webpack-plugin': patch +'@module-federation/enhanced': patch +--- + +fix(bridge): fix the issue where bridge proxy react-router fails in modernjs projects diff --git a/packages/bridge/bridge-react-webpack-plugin/src/index.ts b/packages/bridge/bridge-react-webpack-plugin/src/index.ts index da47bed04ba..340a03fcf8e 100644 --- a/packages/bridge/bridge-react-webpack-plugin/src/index.ts +++ b/packages/bridge/bridge-react-webpack-plugin/src/index.ts @@ -1,5 +1,5 @@ -import fs from 'node:fs'; -import path from 'node:path'; +// import fs from 'node:fs'; +// import path from 'node:path'; import type { moduleFederationPlugin } from '@module-federation/sdk'; import { getBridgeRouterAlias } from './utis'; @@ -34,27 +34,27 @@ class ReactBridgeAliasChangerPlugin { apply(compiler: any) { compiler.hooks.afterEnvironment.tap('ReactBridgeAliasPlugin', () => { // Gets the path to the node_modules directory - const nodeModulesPath = path.resolve(compiler.context, 'node_modules'); - const targetFilePath = path.join(nodeModulesPath, this.targetFile); + // const nodeModulesPath = path.resolve(compiler.context, 'node_modules'); + // const targetFilePath = path.join(nodeModulesPath, this.targetFile); - if (fs.existsSync(targetFilePath)) { - const originalResolve = compiler.options.resolve || {}; - const originalAlias = originalResolve.alias || {}; + // if (fs.existsSync(targetFilePath)) { + const originalResolve = compiler.options.resolve || {}; + const originalAlias = originalResolve.alias || {}; - // Update alias - const updatedAlias = { - // allow `alias` can be override - // [this.alias]: targetFilePath, - ...getBridgeRouterAlias(originalAlias['react-router-dom']), - ...originalAlias, - }; + // Update alias + const updatedAlias = { + // allow `alias` can be override + // [this.alias]: targetFilePath, + ...getBridgeRouterAlias(originalAlias['react-router-dom']), + ...originalAlias, + }; - // Update the webpack configuration - compiler.options.resolve = { - ...originalResolve, - alias: updatedAlias, - }; - } + // Update the webpack configuration + compiler.options.resolve = { + ...originalResolve, + alias: updatedAlias, + }; + // } }); } } diff --git a/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts b/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts index 5994c53c5df..3f8279f7166 100644 --- a/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts +++ b/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts @@ -4,8 +4,8 @@ import type IModuleFederationPlugin from '../lib/container/ModuleFederationPlugi import type { ResourceInfo } from '@module-federation/manifest'; import { getWebpackPath } from '@module-federation/sdk/normalize-webpack-path'; -import path from 'node:path'; -import fs from 'node:fs'; +// import path from 'node:path'; +// import fs from 'node:fs'; import ReactBridgePlugin from '@module-federation/bridge-react-webpack-plugin'; export const PLUGIN_NAME = 'ModuleFederationPlugin'; @@ -30,16 +30,13 @@ export default class ModuleFederationPlugin implements WebpackPluginInstance { this._mfPlugin!.apply(compiler); // react bridge plugin - const nodeModulesPath = path.resolve(compiler.context, 'node_modules'); - const reactPath = path.join( - nodeModulesPath, - '@module-federation/bridge-react', - ); + // const nodeModulesPath = path.resolve(compiler.context, 'node_modules'); + // const reactPath = path.join( + // nodeModulesPath, + // '@module-federation/bridge-react', + // ); // Check whether react exists - if ( - fs.existsSync(reactPath) && - (!this._options?.bridge || !this._options.bridge.disableAlias) - ) { + if (this._options?.bridge?.disableAlias !== true) { new ReactBridgePlugin({ moduleFederationOptions: this._options, }).apply(compiler); From 330fe2927d8ed5e10221080c23af8c4afe40db0b Mon Sep 17 00:00:00 2001 From: fengdanping Date: Tue, 2 Sep 2025 13:40:22 +0800 Subject: [PATCH 2/3] feat(sdk): support bridge.enable config to allow users to enable and disable the bridge capability --- .changeset/fair-hounds-sleep.md | 2 +- .changeset/swift-dancers-cross.md | 9 +++++++++ .../bridge-react-webpack-plugin/src/index.ts | 13 ------------- .../container/ModuleFederationPlugin.check.ts | 5 ++++- .../schemas/container/ModuleFederationPlugin.ts | 5 +++++ .../src/wrapper/ModuleFederationPlugin.ts | 15 ++++----------- packages/modernjs/src/cli/configPlugin.ts | 12 ++---------- packages/rspack/src/ModuleFederationPlugin.ts | 6 +----- .../src/types/plugins/ModuleFederationPlugin.ts | 5 +++++ 9 files changed, 31 insertions(+), 41 deletions(-) create mode 100644 .changeset/swift-dancers-cross.md diff --git a/.changeset/fair-hounds-sleep.md b/.changeset/fair-hounds-sleep.md index eabf4a40f1d..89897dfb1a7 100644 --- a/.changeset/fair-hounds-sleep.md +++ b/.changeset/fair-hounds-sleep.md @@ -3,4 +3,4 @@ '@module-federation/enhanced': patch --- -fix(bridge): fix the issue where bridge proxy react-router fails in modernjs projects +fix(bridge-react-webpack-plugin): fix the proxying react-router failed issue in the modernjs projects diff --git a/.changeset/swift-dancers-cross.md b/.changeset/swift-dancers-cross.md new file mode 100644 index 00000000000..839c51894cc --- /dev/null +++ b/.changeset/swift-dancers-cross.md @@ -0,0 +1,9 @@ +--- +'@module-federation/bridge-react-webpack-plugin': patch +'@module-federation/enhanced': patch +'@module-federation/modern-js': patch +'@module-federation/rspack': patch +'@module-federation/sdk': patch +--- + +feat(react-bridge): support the bridge.enable configuration to allow users to explicitly enable and disable the bridge capability diff --git a/packages/bridge/bridge-react-webpack-plugin/src/index.ts b/packages/bridge/bridge-react-webpack-plugin/src/index.ts index 340a03fcf8e..517631a6d92 100644 --- a/packages/bridge/bridge-react-webpack-plugin/src/index.ts +++ b/packages/bridge/bridge-react-webpack-plugin/src/index.ts @@ -1,5 +1,3 @@ -// import fs from 'node:fs'; -// import path from 'node:path'; import type { moduleFederationPlugin } from '@module-federation/sdk'; import { getBridgeRouterAlias } from './utis'; @@ -33,28 +31,17 @@ class ReactBridgeAliasChangerPlugin { apply(compiler: any) { compiler.hooks.afterEnvironment.tap('ReactBridgeAliasPlugin', () => { - // Gets the path to the node_modules directory - // const nodeModulesPath = path.resolve(compiler.context, 'node_modules'); - // const targetFilePath = path.join(nodeModulesPath, this.targetFile); - - // if (fs.existsSync(targetFilePath)) { const originalResolve = compiler.options.resolve || {}; const originalAlias = originalResolve.alias || {}; - - // Update alias const updatedAlias = { - // allow `alias` can be override - // [this.alias]: targetFilePath, ...getBridgeRouterAlias(originalAlias['react-router-dom']), ...originalAlias, }; - // Update the webpack configuration compiler.options.resolve = { ...originalResolve, alias: updatedAlias, }; - // } }); } } diff --git a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts index a2c17aab47a..6bd962d1440 100644 --- a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts +++ b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts @@ -382,7 +382,10 @@ const t = { }, bridge: { type: 'object', - properties: { disableAlias: { type: 'boolean', default: !1 } }, + properties: { + disableAlias: { type: 'boolean', default: !1 }, + enable: { type: 'boolean', default: !1 }, + }, additionalProperties: !1, }, virtualRuntimeEntry: { type: 'boolean' }, diff --git a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts index 8c7f55aac82..e3e3bae4a0a 100644 --- a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts +++ b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts @@ -829,6 +829,11 @@ export default { type: 'boolean', default: false, }, + enable: { + description: 'Whether to enable the bridge', + type: 'boolean', + default: false, + }, }, additionalProperties: false, }, diff --git a/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts b/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts index 3f8279f7166..400411f68db 100644 --- a/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts +++ b/packages/enhanced/src/wrapper/ModuleFederationPlugin.ts @@ -2,10 +2,7 @@ import type { WebpackPluginInstance, Compiler } from 'webpack'; import type { moduleFederationPlugin } from '@module-federation/sdk'; import type IModuleFederationPlugin from '../lib/container/ModuleFederationPlugin'; import type { ResourceInfo } from '@module-federation/manifest'; - import { getWebpackPath } from '@module-federation/sdk/normalize-webpack-path'; -// import path from 'node:path'; -// import fs from 'node:fs'; import ReactBridgePlugin from '@module-federation/bridge-react-webpack-plugin'; export const PLUGIN_NAME = 'ModuleFederationPlugin'; @@ -29,14 +26,10 @@ export default class ModuleFederationPlugin implements WebpackPluginInstance { this._mfPlugin = new CoreModuleFederationPlugin(this._options); this._mfPlugin!.apply(compiler); - // react bridge plugin - // const nodeModulesPath = path.resolve(compiler.context, 'node_modules'); - // const reactPath = path.join( - // nodeModulesPath, - // '@module-federation/bridge-react', - // ); - // Check whether react exists - if (this._options?.bridge?.disableAlias !== true) { + if ( + this._options?.bridge?.enable && + this._options?.bridge?.disableAlias !== true + ) { new ReactBridgePlugin({ moduleFederationOptions: this._options, }).apply(compiler); diff --git a/packages/modernjs/src/cli/configPlugin.ts b/packages/modernjs/src/cli/configPlugin.ts index 64bd548c670..a868ef44faf 100644 --- a/packages/modernjs/src/cli/configPlugin.ts +++ b/packages/modernjs/src/cli/configPlugin.ts @@ -1,5 +1,5 @@ import path from 'path'; -import fs from 'fs'; +// import fs from 'fs'; import { getIPV4, isWebTarget, skipByTarget } from './utils'; import { moduleFederationPlugin, encodeName } from '@module-federation/sdk'; import { bundle } from '@modern-js/node-bundle-require'; @@ -164,15 +164,7 @@ export const patchMFConfig = ( const runtimePlugins = [...(mfConfig.runtimePlugins || [])]; try { - const nodeModulesPath = path.resolve(process.cwd(), 'node_modules'); - const bridgeReactPath = path.join( - nodeModulesPath, - '@module-federation/bridge-react', - ); - if ( - fs.existsSync(bridgeReactPath) && - (!mfConfig?.bridge || !mfConfig.bridge.disableAlias) - ) { + if (mfConfig?.bridge?.enable && mfConfig?.bridge?.disableAlias !== true) { mfConfig.bridge = { disableAlias: true, }; diff --git a/packages/rspack/src/ModuleFederationPlugin.ts b/packages/rspack/src/ModuleFederationPlugin.ts index 575b5342e6c..8969bf44347 100644 --- a/packages/rspack/src/ModuleFederationPlugin.ts +++ b/packages/rspack/src/ModuleFederationPlugin.ts @@ -186,11 +186,7 @@ export class ModuleFederationPlugin implements RspackPluginInstance { '@module-federation/bridge-react', ); - // Check whether react exists - if ( - fs.existsSync(reactPath) && - (!options?.bridge || !options.bridge.disableAlias) - ) { + if (options?.bridge?.enable && options?.bridge?.disableAlias !== true) { new ReactBridgePlugin({ moduleFederationOptions: this._options, }).apply(compiler); diff --git a/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts b/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts index de865cfcb63..97d5303a507 100644 --- a/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts +++ b/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts @@ -278,6 +278,11 @@ export interface ModuleFederationPluginOptions { * @default false */ disableAlias?: boolean; + /** + * Whether to enable the bridge + * @default false + */ + enable?: boolean; }; /** * Configuration for async boundary plugin From 3d6496cd85d153db36687b30f443f20b4f83ca83 Mon Sep 17 00:00:00 2001 From: fengdanping Date: Tue, 2 Sep 2025 14:48:22 +0800 Subject: [PATCH 3/3] feat: disable the setting disableAlias true in the modernjs plugin --- packages/modernjs/src/cli/configPlugin.ts | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/modernjs/src/cli/configPlugin.ts b/packages/modernjs/src/cli/configPlugin.ts index a868ef44faf..16de12909a4 100644 --- a/packages/modernjs/src/cli/configPlugin.ts +++ b/packages/modernjs/src/cli/configPlugin.ts @@ -163,18 +163,19 @@ export const patchMFConfig = ( const runtimePlugins = [...(mfConfig.runtimePlugins || [])]; - try { - if (mfConfig?.bridge?.enable && mfConfig?.bridge?.disableAlias !== true) { - mfConfig.bridge = { - disableAlias: true, - }; - logger.debug( - `${PLUGIN_IDENTIFIER} use "@module-federation/modern-js/react" instead of "@module-federation/bridge-react" !`, - ); - } - } catch (e) { - // noop - } + // or set disableAlias only in ssr mode + // try { + // if (mfConfig?.bridge?.enable && mfConfig?.bridge?.disableAlias !== true) { + // mfConfig.bridge = { + // disableAlias: true, + // }; + // logger.debug( + // `${PLUGIN_IDENTIFIER} use "@module-federation/modern-js/react" instead of "@module-federation/bridge-react" !`, + // ); + // } + // } catch (e) { + // // noop + // } patchDTSConfig(mfConfig, isServer); injectRuntimePlugins(