-
-
Notifications
You must be signed in to change notification settings - Fork 787
Description
System Info
System:
OS: macOS 15.6
CPU: (10) arm64 Apple M1 Max
Memory: 22.77 GB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.15.0 - ~/.volta/tools/image/node/22.15.0/bin/node
Yarn: 4.9.1-git.20250411.hash-1908ee79f - ~/.volta/tools/image/yarn/4.9.1/bin/yarn
npm: 10.9.2 - ~/.volta/tools/image/node/22.15.0/bin/npm
pnpm: 10.14.0 - ~/.volta/bin/pnpm
Browsers:
Brave Browser: 137.1.79.126
Chrome: 139.0.7258.139
Safari: 18.6
npmPackages:
@rspack/cli: ^1.4.11 => 1.4.11
@rspack/core: ^1.4.11 => 1.4.11
Details
Hey π
We are currently facing an issue when trying to upgrading rspack to >= v1.4.7
.
When using the Module Federation plugin in conjunction with a custom resolver, the __FEDERATION__.__SHARE__
global variable is empty during runtime - whereas with older versions (<= v1.4.6
) it was correctly populated.
// JSON.stringify(__FEDERATION__.__SHARE__)
'{"spa-federated:0.0.2":{"default":{}}}'
Our resolver plugin uses the unplugin
library which taps into the normalModuleFactory.hooks.resolve
hook - mutating the resolveData.request
field.
I bisected the repo and the regression is likely coming from this refactoring of the hooks:
Before this change, crates/rspack_plugin_mf/src/sharing/provide_shared_plugin.rs
was able to match the shared modules declared in the config using their name (react
, react-dom
β¦) but it is now trying to use the fully qualified path instead - which does not feel right nor user friendly if it means that we have to resolve ahead of time and declare the shared dependencies using the absolute path.
This simple change seems to fix the problem by reverting to the old behaviour:
// crates/rspack_plugin_mf/src/sharing/provide_shared_plugin.rs
+let dependency = data.dependencies[0]
+ .as_module_dependency()
+ .expect("should be module dependency");
-let request = &create_data.raw_request;
+let request = dependency.request();
If that solution seems right to you I created a draft PR π
Reproduce link
See below β¬
Reproduce Steps
Copy paste this in your terminal:
# create a new project
mkdir rspack-repro-mf-shared-custom-resolution
cd rspack-repro-mf-shared-custom-resolution
# init and add packages
pnpm init
pnpm add -D @rspack/core @rspack/cli @module-federation/enhanced [email protected]
# create source entry point
mkdir src
cat <<EOF > src/host.js
import react from "react";
console.log("React version:", react.version);
EOF
# create rspack config
cat <<EOF > rspack.config.mjs
import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const config = {
mode: "development",
devtool: false,
entry: {
main: "./src/host.js",
},
output: {
clean: true,
publicPath: "auto",
},
plugins: [
// Basic module federation plugin
new ModuleFederationPlugin({
name: "host",
shared: {
react: {
version: "18.3.1",
singleton: true,
},
},
}),
// A dummy plugin to simulate a custom resolver
function (compiler) {
compiler.hooks.thisCompilation.tap(
"customResolver",
(compilation, { normalModuleFactory }) => {
normalModuleFactory.hooks.resolve.tap("customResolver", (data) => {
if (data.request.startsWith("react")) {
data.request = require.resolve(data.request);
}
});
}
);
},
],
};
export default config;
EOF
# build the host
pnpm rspack build
# check which shared modules are declared
grep "__webpack_require__.initializeSharingData = { scopeToSharingDataMapping:" ./dist/main.js
Outcome:
# β With the custom resolver (empty object):
# __webpack_require__.initializeSharingData = { scopeToSharingDataMapping: { }, uniqueName: "rspack-repro-mf-shared-custom-resolution" };
// Formatted
__webpack_require__.initializeSharingData = {
scopeToSharingDataMapping: {},
uniqueName: "rspack-repro-mf-shared-custom-resolution",
};
# β
Without it (correct mapping):
# __webpack_require__.initializeSharingData = { scopeToSharingDataMapping: { "default": [{ name: "react", version: "18.3.1", factory: () => (__webpack_require__.e("vendors-node_modules_pnpm_react_18_3_1_node_modules_react_index_js").then(() => (() => (__webpack_require__(/*! ./node_modules/.pnpm/[email protected]/node_modules/react/index.js */ "./node_modules/.pnpm/[email protected]/node_modules/react/index.js"))))), eager: 0, singleton: 1 }] }, uniqueName: "rspack-repro-mf-shared-custom-resolution" };
// Formatted
__webpack_require__.initializeSharingData = {
scopeToSharingDataMapping: {
default: [
{
name: "react",
version: "18.3.1",
factory: () =>
__webpack_require__
.e(
"vendors-node_modules_pnpm_react_18_3_1_node_modules_react_index_js"
)
.then(
() => () =>
__webpack_require__(
/*! ./node_modules/.pnpm/[email protected]/node_modules/react/index.js */ "./node_modules/.pnpm/[email protected]/node_modules/react/index.js"
)
),
eager: 0,
singleton: 1,
},
],
},
uniqueName: "rspack-repro-mf-shared-custom-resolution",
};