Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt the new federation runtime #518

Open
ScriptedAlchemy opened this issue Mar 8, 2024 · 9 comments · May be fixed by #674
Open

Adopt the new federation runtime #518

ScriptedAlchemy opened this issue Mar 8, 2024 · 9 comments · May be fixed by #674
Assignees
Labels
area:repack The issue is about logic/code inside of Re.Pack. status:wip The issue is being worked on. type:feature Proposal or idea for a new feature or enhancement.

Comments

@ScriptedAlchemy
Copy link
Contributor

Describe the feature

I have recently redesigned module federation and introduced the concept of runtime plugins, while they have many uses - i think the new runtime could be a prime candidate for repack as i recall we had to do some special things for ChunkManager, this could likely be moved into a runtime plugin and not require a full webpack plugin for federation to work (i do the same for node.js now too)

Motivation

More flexability to end user and most likely a cleaner implementation of federation for RN apps

Related Issues

@jbroma
Copy link
Member

jbroma commented Mar 8, 2024

hey @ScriptedAlchemy,

you are talking about MF 1.5 correct? I'm all up for it, love the idea. Perhaps runtime plugins would actually help us solve the issue where host app can't define remotes (I think it was related to converting some part of initialisation logic to promise so RN wasn't initialising correctly). I wasn't involved in Re.Pack development at the time where MF was introduced so my knowledge is limited on why things are as they are. In the future, we're also looking forward to migrating to rspack and I know MF 1.5 is already implemented there as a plugin, but I haven't explored it much as of yet, since it's all very fresh.

Could you point me to some resources on what features MF 1.5 offers?

@ScriptedAlchemy
Copy link
Contributor Author

yeah so for RN this is what i was thinking which may help the chunk manager thing.

module-federation/core#2013

Then for defining remotes etc, we can do things like this:
https://github.com/module-federation/module-federation-examples/blob/master/runtime-plugins/remote-control/app1/pick-remote.ts

Resources:
https://github.com/module-federation/universe/tree/main/packages/runtime
https://github.com/module-federation/universe/tree/main/packages/enhanced

We are also finalizing a new api for adding remotes on the fly:
module-federation/core#2171

Heres a post i wrote about it:
https://medium.com/@scriptedalchemy/emodule-federation-gets-upgraded-and-rspack-supports-it-5ddb0d1e9546

Basically youd just swap over to module-federation/enhacend, then any runtime plugins you want to make you can just add as array like i do in examples.

If you want pure at runtime you can do that too with the module-federation/runtime

If you use enhanced, then all it does is init the runtime package under the hood and pass options.
https://github.com/module-federation/module-federation-examples/blob/master/advanced-api/dynamic-remotes/app1/src/App.js

If its something youd want to adopt, im down to help. I dont know a ton of RN but the main thing i had in mind where i could be helpful is with a runtime plugin for chunk handlers that RN needs.

Like node plugin, you make a custom chunk handler plugin. However i discovered i can do same with runtime plugin and since runtime plugins and federation runtime are embedded into the runtime chunks, they boot before any app code does, it boots along with webpacks runtime etc.

We also just rolled out data manifest plugin and preload hooks so if chunkManager needs that upfront in totality, we have a hook in runtime for preloadAssets etc. (was just merged)

Copy link

github-actions bot commented Apr 8, 2024

This issue has been marked as stale because it has been inactive for 30 days. Please update this issue or it will be automatically closed in 14 days.

@github-actions github-actions bot added the Stale label Apr 8, 2024
@jbroma jbroma removed the Stale label Apr 8, 2024
Copy link

github-actions bot commented May 9, 2024

This issue has been marked as stale because it has been inactive for 30 days. Please update this issue or it will be automatically closed in 14 days.

@github-actions github-actions bot added the Stale label May 9, 2024
@jbroma jbroma removed the Stale label May 17, 2024
@ScriptedAlchemy
Copy link
Contributor Author

Bump, not stale

@github-actions github-actions bot added the Stale label Jul 5, 2024
@callstack callstack deleted a comment from github-actions bot Jul 5, 2024
@jbroma jbroma removed the Stale label Jul 5, 2024
@jbroma
Copy link
Member

jbroma commented Jul 26, 2024

Hey @ScriptedAlchemy , finally had some time to look into this, opened a PR with initial support for MF2.

The PR introduces support for Webpack, but I also have a version working with Rspack (and the HMR is working there 🎉). All in all, MF2 looks like a amazing fit, it doesn't need any extra logic from Re.Pack side that was needed in V1, and we can specify remotes in HostApp config without any issues ❤️ (which was a huge pain point before)

For the Webpack part:
The only thing that seems to be in the way of adopting this is createScriptNode in the @module-federation/sdk - it's defaulting to node since document is not defined. In the PR, I've added a simple patch that calls ScriptManager.loadScript to deal with this - very simple patch, and with that everything seems to be working 🎉

I've also noticed that preloadAssets is not really viable in RN env in it's current state so I was forced to ensure every shared dependency has strategy: loaded-first. This runtime plugin from @2heal1 helped with that.

For the Rspack part:
In addition to findings above, there is an issue where ModuleFederation entry in the HostApp is injected after all RePack internal entries and just before the main entry (index.js in this case) in constrast to Webpack, where the MF entry is placed before all other entries:

Webpack:

/******/ 	
/******/ 	// module cache are used so entry inlining is disabled
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	__webpack_require__("./node_modules/.federation/entry.f123e0b15f373767ec444674ae98443f.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/console.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/error-guard.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/react-native@0.74.3_@babel+core@7.24.0_@babel+preset-env@7.24.0_@babel+core@7.24.0__@types+react@18.2.74_react@18.2.0/node_modules/react-native/Libraries/Core/InitializeCore.js");
/******/ 	__webpack_require__("../../packages/repack/dist/modules/configurePublicPath.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/@pmmmwh+react-refresh-webpack-plugin@0.5.13_react-refresh@0.14.2_type-fest@4.12.0_webpack@5.91.0/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js");
/******/ 	__webpack_require__("../../packages/repack/dist/modules/WebpackHMRClient.js");
/******/ 	var __webpack_exports__ = __webpack_require__("./index.js");
/******/ 	// run runtime startup
/******/ 	__webpack_require__.x();
/******/ })()
;//# sourceMappingURL=index.bundle.map?platform=android

Rspack:

// startup
// Load entry module and return exports
__webpack_require__("../../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/console.js");
__webpack_require__("../../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/error-guard.js");
__webpack_require__("../../../node_modules/.pnpm/react-native@0.74.3_@babel+core@7.24.9_@babel+preset-env@7.24.8_@babel+core@7.24.9__@types+react@18.3.3_react@18.2.0/node_modules/react-native/Libraries/Core/InitializeCore.js");
__webpack_require__("../../../packages/repack/dist/modules/configurePublicPath.js");
__webpack_require__("../../../node_modules/.pnpm/@rspack+plugin-react-refresh@1.0.0-alpha.5_react-refresh@0.14.2/node_modules/@rspack/plugin-react-refresh/client/reactRefreshEntry.js");
__webpack_require__("../../../packages/repack/dist/modules/WebpackHMRClient.js");
__webpack_require__("@module-federation/runtime/rspack.js!=!data:text/javascript,import __module_federation_bundler_runtime__ from \"/Users/jbroma/repack/zephyr/node_modules/.pnpm/@module-federation+webpack-bundler-runtime@0.2.8/node_modules/@module-federation/webpack-bundler-runtime/dist/index.cjs.js\";import __module_federation_runtime_plugin_0__ from \"/Users/jbroma/repack/zephyr/examples/with-zephyr/HostApp/runtime-plugin.ts\";const __module_federation_runtime_plugins__ = [__module_federation_runtime_plugin_0__()];const __module_federation_remote_infos__ = {\"MiniApp\":[{\"alias\":\"MiniApp\",\"name\":\"MiniApp\",\"entry\":\"http://localhost:9000/mf-manifest.json?platform=ios\",\"externalType\":\"script\",\"shareScope\":\"default\"}]};const __module_federation_container_name__ = \"HostApp\";if((__webpack_require__.initializeSharingData||__webpack_require__.initializeExposesData)&&__webpack_require__.federation){var __webpack_require___remotesLoadingData,__webpack_require___remotesLoadingData1,__webpack_require___initializeSharingData,__webpack_require___consumesLoadingData,__webpack_require___consumesLoadingData1,__webpack_require___initializeExposesData,__webpack_require___consumesLoadingData2;const override=(obj,key,value)=>{if(!obj)return;if(obj[key])obj[key]=value};const merge=(obj,key,fn)=>{const value=fn();if(Array.isArray(value)){var _obj,_key;var _;(_=(_obj=obj)[_key=key])!==null&&_!==void 0?_:_obj[_key]=[];obj[key].push(...value)}else if(typeof value===\"object\"&&value!==null){var _obj1,_key1;var _1;(_1=(_obj1=obj)[_key1=key])!==null&&_1!==void 0?_1:_obj1[_key1]={};Object.assign(obj[key],value)}};const early=(obj,key,initial)=>{var _obj,_key;var _;(_=(_obj=obj)[_key=key])!==null&&_!==void 0?_:_obj[_key]=initial()};var __webpack_require___remotesLoadingData_chunkMapping;const remotesLoadingChunkMapping=(__webpack_require___remotesLoadingData_chunkMapping=(__webpack_require___remotesLoadingData=__webpack_require__.remotesLoadingData)===null||__webpack_require___remotesLoadingData===void 0?void 0:__webpack_require___remotesLoadingData.chunkMapping)!==null&&__webpack_require___remotesLoadingData_chunkMapping!==void 0?__webpack_require___remotesLoadingData_chunkMapping:{};var __webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping;const remotesLoadingModuleIdToRemoteDataMapping=(__webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping=(__webpack_require___remotesLoadingData1=__webpack_require__.remotesLoadingData)===null||__webpack_require___remotesLoadingData1===void 0?void 0:__webpack_require___remotesLoadingData1.moduleIdToRemoteDataMapping)!==null&&__webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping!==void 0?__webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping:{};var __webpack_require___initializeSharingData_scopeToSharingDataMapping;const initializeSharingScopeToInitDataMapping=(__webpack_require___initializeSharingData_scopeToSharingDataMapping=(__webpack_require___initializeSharingData=__webpack_require__.initializeSharingData)===null||__webpack_require___initializeSharingData===void 0?void 0:__webpack_require___initializeSharingData.scopeToSharingDataMapping)!==null&&__webpack_require___initializeSharingData_scopeToSharingDataMapping!==void 0?__webpack_require___initializeSharingData_scopeToSharingDataMapping:{};var __webpack_require___consumesLoadingData_chunkMapping;const consumesLoadingChunkMapping=(__webpack_require___consumesLoadingData_chunkMapping=(__webpack_require___consumesLoadingData=__webpack_require__.consumesLoadingData)===null||__webpack_require___consumesLoadingData===void 0?void 0:__webpack_require___consumesLoadingData.chunkMapping)!==null&&__webpack_require___consumesLoadingData_chunkMapping!==void 0?__webpack_require___consumesLoadingData_chunkMapping:{};var __webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping;const consumesLoadingModuleToConsumeDataMapping=(__webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping=(__webpack_require___consumesLoadingData1=__webpack_require__.consumesLoadingData)===null||__webpack_require___consumesLoadingData1===void 0?void 0:__webpack_require___consumesLoadingData1.moduleIdToConsumeDataMapping)!==null&&__webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping!==void 0?__webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping:{};const consumesLoadinginstalledModules={};const initializeSharingInitPromises=[];const initializeSharingInitTokens=[];const containerShareScope=(__webpack_require___initializeExposesData=__webpack_require__.initializeExposesData)===null||__webpack_require___initializeExposesData===void 0?void 0:__webpack_require___initializeExposesData.shareScope;for(const key in __module_federation_bundler_runtime__){__webpack_require__.federation[key]=__module_federation_bundler_runtime__[key]}early(__webpack_require__.federation,\"consumesLoadingModuleToHandlerMapping\",()=>{const consumesLoadingModuleToHandlerMapping={};for(let[moduleId,data]of Object.entries(consumesLoadingModuleToConsumeDataMapping)){consumesLoadingModuleToHandlerMapping[moduleId]={getter:data.fallback,shareInfo:{shareConfig:{fixedDependencies:false,requiredVersion:data.requiredVersion,strictVersion:data.strictVersion,singleton:data.singleton,eager:data.eager},scope:[data.shareScope]},shareKey:data.shareKey}}return consumesLoadingModuleToHandlerMapping});early(__webpack_require__.federation,\"initOptions\",()=>({}));early(__webpack_require__.federation.initOptions,\"name\",()=>__module_federation_container_name__);early(__webpack_require__.federation.initOptions,\"shared\",()=>{const shared={};for(let[scope,stages]of Object.entries(initializeSharingScopeToInitDataMapping)){for(let stage of stages){if(typeof stage===\"object\"&&stage!==null){const{name,version,factory,eager}=stage;const options={version,scope:[scope],get:factory};if(shared[name]){shared[name].push(options)}else{shared[name]=[options]}}}}return shared});merge(__webpack_require__.federation.initOptions,\"remotes\",()=>Object.values(__module_federation_remote_infos__).flat().filter(remote=>remote.externalType===\"script\"));merge(__webpack_require__.federation.initOptions,\"plugins\",()=>__module_federation_runtime_plugins__);early(__webpack_require__.federation,\"bundlerRuntimeOptions\",()=>({}));early(__webpack_require__.federation.bundlerRuntimeOptions,\"remotes\",()=>({}));early(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"chunkMapping\",()=>remotesLoadingChunkMapping);early(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"idToExternalAndNameMapping\",()=>{const remotesLoadingIdToExternalAndNameMappingMapping={};for(let[moduleId,data]of Object.entries(remotesLoadingModuleIdToRemoteDataMapping)){remotesLoadingIdToExternalAndNameMappingMapping[moduleId]=[data.shareScope,data.name,data.externalModuleId,data.remoteName]}return remotesLoadingIdToExternalAndNameMappingMapping});early(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"webpackRequire\",()=>__webpack_require__);merge(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"idToRemoteMap\",()=>{const idToRemoteMap={};for(let[id,remoteData]of Object.entries(remotesLoadingModuleIdToRemoteDataMapping)){const info=__module_federation_remote_infos__[remoteData.remoteName];if(info)idToRemoteMap[id]=info}return idToRemoteMap});override(__webpack_require__,\"S\",__webpack_require__.federation.bundlerRuntime.S);if(__webpack_require__.federation.attachShareScopeMap){__webpack_require__.federation.attachShareScopeMap(__webpack_require__)}override(__webpack_require__.f,\"remotes\",(chunkId,promises)=>__webpack_require__.federation.bundlerRuntime.remotes({chunkId,promises,chunkMapping:remotesLoadingChunkMapping,idToExternalAndNameMapping:__webpack_require__.federation.bundlerRuntimeOptions.remotes.idToExternalAndNameMapping,idToRemoteMap:__webpack_require__.federation.bundlerRuntimeOptions.remotes.idToRemoteMap,webpackRequire:__webpack_require__}));override(__webpack_require__.f,\"consumes\",(chunkId,promises)=>__webpack_require__.federation.bundlerRuntime.consumes({chunkId,promises,chunkMapping:consumesLoadingChunkMapping,moduleToHandlerMapping:__webpack_require__.federation.consumesLoadingModuleToHandlerMapping,installedModules:consumesLoadinginstalledModules,webpackRequire:__webpack_require__}));override(__webpack_require__,\"I\",(name,initScope)=>__webpack_require__.federation.bundlerRuntime.I({shareScopeName:name,initScope,initPromises:initializeSharingInitPromises,initTokens:initializeSharingInitTokens,webpackRequire:__webpack_require__}));override(__webpack_require__,\"initContainer\",(shareScope,initScope,remoteEntryInitOptions)=>__webpack_require__.federation.bundlerRuntime.initContainerEntry({shareScope,initScope,remoteEntryInitOptions,shareScopeKey:containerShareScope,webpackRequire:__webpack_require__}));override(__webpack_require__,\"getContainer\",(module1,getScope)=>{var moduleMap=__webpack_require__.initializeExposesData.moduleMap;__webpack_require__.R=getScope;getScope=Object.prototype.hasOwnProperty.call(moduleMap,module1)?moduleMap[module1]():Promise.resolve().then(()=>{throw new Error('Module \"'+module1+'\" does not exist in container.')});__webpack_require__.R=undefined;return getScope});__webpack_require__.federation.instance=__webpack_require__.federation.runtime.init(__webpack_require__.federation.initOptions);if((__webpack_require___consumesLoadingData2=__webpack_require__.consumesLoadingData)===null||__webpack_require___consumesLoadingData2===void 0?void 0:__webpack_require___consumesLoadingData2.initialConsumes){__webpack_require__.federation.bundlerRuntime.installInitialConsumes({webpackRequire:__webpack_require__,installedModules:consumesLoadinginstalledModules,initialConsumes:__webpack_require__.consumesLoadingData.initialConsumes,moduleToHandlerMapping:__webpack_require__.federation.consumesLoadingModuleToHandlerMapping})}}");
var __webpack_exports__ = __webpack_require__("./index.js");
})()

This can be worked around by declaring react and react-native as runtime shared deps and it works quite well, but it's not so easy to do this for deep imports which we need in some places (like WebpackHMRClient or configurePublicPath) and we need to ensure those are singletons as well. Having entry prepended to everything else like in Webpack would be perfect, wondering if Rspack allows to modify entries in such way?

Anyways, the biggest issue is to figure out how we can deal with the patch and move forward with the MF2 in Re.Pack.

@jbroma
Copy link
Member

jbroma commented Jul 26, 2024

One more thing - couldn't get Chrome MF extension to work, do you see any use-case for it in context of RN & Re.Pack?

@jbroma jbroma self-assigned this Jul 26, 2024
@jbroma jbroma added status:wip The issue is being worked on. type:feature Proposal or idea for a new feature or enhancement. area:repack The issue is about logic/code inside of Re.Pack. labels Jul 26, 2024
@jbroma
Copy link
Member

jbroma commented Aug 1, 2024

Hey @ScriptedAlchemy , finally had some time to look into this, opened a PR with initial support for MF2.

The PR introduces support for Webpack, but I also have a version working with Rspack (and the HMR is working there 🎉). All in all, MF2 looks like a amazing fit, it doesn't need any extra logic from Re.Pack side that was needed in V1, and we can specify remotes in HostApp config without any issues ❤️ (which was a huge pain point before)

For the Webpack part: The only thing that seems to be in the way of adopting this is createScriptNode in the @module-federation/sdk - it's defaulting to node since document is not defined. In the PR, I've added a simple patch that calls ScriptManager.loadScript to deal with this - very simple patch, and with that everything seems to be working 🎉

I've also noticed that preloadAssets is not really viable in RN env in it's current state so I was forced to ensure every shared dependency has strategy: loaded-first. This runtime plugin from @2heal1 helped with that.

For the Rspack part: In addition to findings above, there is an issue where ModuleFederation entry in the HostApp is injected after all RePack internal entries and just before the main entry (index.js in this case) in constrast to Webpack, where the MF entry is placed before all other entries:

Webpack:

/******/ 	
/******/ 	// module cache are used so entry inlining is disabled
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	__webpack_require__("./node_modules/.federation/entry.f123e0b15f373767ec444674ae98443f.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/console.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/error-guard.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/react-native@0.74.3_@babel+core@7.24.0_@babel+preset-env@7.24.0_@babel+core@7.24.0__@types+react@18.2.74_react@18.2.0/node_modules/react-native/Libraries/Core/InitializeCore.js");
/******/ 	__webpack_require__("../../packages/repack/dist/modules/configurePublicPath.js");
/******/ 	__webpack_require__("../../node_modules/.pnpm/@pmmmwh+react-refresh-webpack-plugin@0.5.13_react-refresh@0.14.2_type-fest@4.12.0_webpack@5.91.0/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js");
/******/ 	__webpack_require__("../../packages/repack/dist/modules/WebpackHMRClient.js");
/******/ 	var __webpack_exports__ = __webpack_require__("./index.js");
/******/ 	// run runtime startup
/******/ 	__webpack_require__.x();
/******/ })()
;//# sourceMappingURL=index.bundle.map?platform=android

Rspack:

// startup
// Load entry module and return exports
__webpack_require__("../../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/console.js");
__webpack_require__("../../../node_modules/.pnpm/@react-native+js-polyfills@0.74.85/node_modules/@react-native/js-polyfills/error-guard.js");
__webpack_require__("../../../node_modules/.pnpm/react-native@0.74.3_@babel+core@7.24.9_@babel+preset-env@7.24.8_@babel+core@7.24.9__@types+react@18.3.3_react@18.2.0/node_modules/react-native/Libraries/Core/InitializeCore.js");
__webpack_require__("../../../packages/repack/dist/modules/configurePublicPath.js");
__webpack_require__("../../../node_modules/.pnpm/@rspack+plugin-react-refresh@1.0.0-alpha.5_react-refresh@0.14.2/node_modules/@rspack/plugin-react-refresh/client/reactRefreshEntry.js");
__webpack_require__("../../../packages/repack/dist/modules/WebpackHMRClient.js");
__webpack_require__("@module-federation/runtime/rspack.js!=!data:text/javascript,import __module_federation_bundler_runtime__ from \"/Users/jbroma/repack/zephyr/node_modules/.pnpm/@module-federation+webpack-bundler-runtime@0.2.8/node_modules/@module-federation/webpack-bundler-runtime/dist/index.cjs.js\";import __module_federation_runtime_plugin_0__ from \"/Users/jbroma/repack/zephyr/examples/with-zephyr/HostApp/runtime-plugin.ts\";const __module_federation_runtime_plugins__ = [__module_federation_runtime_plugin_0__()];const __module_federation_remote_infos__ = {\"MiniApp\":[{\"alias\":\"MiniApp\",\"name\":\"MiniApp\",\"entry\":\"http://localhost:9000/mf-manifest.json?platform=ios\",\"externalType\":\"script\",\"shareScope\":\"default\"}]};const __module_federation_container_name__ = \"HostApp\";if((__webpack_require__.initializeSharingData||__webpack_require__.initializeExposesData)&&__webpack_require__.federation){var __webpack_require___remotesLoadingData,__webpack_require___remotesLoadingData1,__webpack_require___initializeSharingData,__webpack_require___consumesLoadingData,__webpack_require___consumesLoadingData1,__webpack_require___initializeExposesData,__webpack_require___consumesLoadingData2;const override=(obj,key,value)=>{if(!obj)return;if(obj[key])obj[key]=value};const merge=(obj,key,fn)=>{const value=fn();if(Array.isArray(value)){var _obj,_key;var _;(_=(_obj=obj)[_key=key])!==null&&_!==void 0?_:_obj[_key]=[];obj[key].push(...value)}else if(typeof value===\"object\"&&value!==null){var _obj1,_key1;var _1;(_1=(_obj1=obj)[_key1=key])!==null&&_1!==void 0?_1:_obj1[_key1]={};Object.assign(obj[key],value)}};const early=(obj,key,initial)=>{var _obj,_key;var _;(_=(_obj=obj)[_key=key])!==null&&_!==void 0?_:_obj[_key]=initial()};var __webpack_require___remotesLoadingData_chunkMapping;const remotesLoadingChunkMapping=(__webpack_require___remotesLoadingData_chunkMapping=(__webpack_require___remotesLoadingData=__webpack_require__.remotesLoadingData)===null||__webpack_require___remotesLoadingData===void 0?void 0:__webpack_require___remotesLoadingData.chunkMapping)!==null&&__webpack_require___remotesLoadingData_chunkMapping!==void 0?__webpack_require___remotesLoadingData_chunkMapping:{};var __webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping;const remotesLoadingModuleIdToRemoteDataMapping=(__webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping=(__webpack_require___remotesLoadingData1=__webpack_require__.remotesLoadingData)===null||__webpack_require___remotesLoadingData1===void 0?void 0:__webpack_require___remotesLoadingData1.moduleIdToRemoteDataMapping)!==null&&__webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping!==void 0?__webpack_require___remotesLoadingData_moduleIdToRemoteDataMapping:{};var __webpack_require___initializeSharingData_scopeToSharingDataMapping;const initializeSharingScopeToInitDataMapping=(__webpack_require___initializeSharingData_scopeToSharingDataMapping=(__webpack_require___initializeSharingData=__webpack_require__.initializeSharingData)===null||__webpack_require___initializeSharingData===void 0?void 0:__webpack_require___initializeSharingData.scopeToSharingDataMapping)!==null&&__webpack_require___initializeSharingData_scopeToSharingDataMapping!==void 0?__webpack_require___initializeSharingData_scopeToSharingDataMapping:{};var __webpack_require___consumesLoadingData_chunkMapping;const consumesLoadingChunkMapping=(__webpack_require___consumesLoadingData_chunkMapping=(__webpack_require___consumesLoadingData=__webpack_require__.consumesLoadingData)===null||__webpack_require___consumesLoadingData===void 0?void 0:__webpack_require___consumesLoadingData.chunkMapping)!==null&&__webpack_require___consumesLoadingData_chunkMapping!==void 0?__webpack_require___consumesLoadingData_chunkMapping:{};var __webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping;const consumesLoadingModuleToConsumeDataMapping=(__webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping=(__webpack_require___consumesLoadingData1=__webpack_require__.consumesLoadingData)===null||__webpack_require___consumesLoadingData1===void 0?void 0:__webpack_require___consumesLoadingData1.moduleIdToConsumeDataMapping)!==null&&__webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping!==void 0?__webpack_require___consumesLoadingData_moduleIdToConsumeDataMapping:{};const consumesLoadinginstalledModules={};const initializeSharingInitPromises=[];const initializeSharingInitTokens=[];const containerShareScope=(__webpack_require___initializeExposesData=__webpack_require__.initializeExposesData)===null||__webpack_require___initializeExposesData===void 0?void 0:__webpack_require___initializeExposesData.shareScope;for(const key in __module_federation_bundler_runtime__){__webpack_require__.federation[key]=__module_federation_bundler_runtime__[key]}early(__webpack_require__.federation,\"consumesLoadingModuleToHandlerMapping\",()=>{const consumesLoadingModuleToHandlerMapping={};for(let[moduleId,data]of Object.entries(consumesLoadingModuleToConsumeDataMapping)){consumesLoadingModuleToHandlerMapping[moduleId]={getter:data.fallback,shareInfo:{shareConfig:{fixedDependencies:false,requiredVersion:data.requiredVersion,strictVersion:data.strictVersion,singleton:data.singleton,eager:data.eager},scope:[data.shareScope]},shareKey:data.shareKey}}return consumesLoadingModuleToHandlerMapping});early(__webpack_require__.federation,\"initOptions\",()=>({}));early(__webpack_require__.federation.initOptions,\"name\",()=>__module_federation_container_name__);early(__webpack_require__.federation.initOptions,\"shared\",()=>{const shared={};for(let[scope,stages]of Object.entries(initializeSharingScopeToInitDataMapping)){for(let stage of stages){if(typeof stage===\"object\"&&stage!==null){const{name,version,factory,eager}=stage;const options={version,scope:[scope],get:factory};if(shared[name]){shared[name].push(options)}else{shared[name]=[options]}}}}return shared});merge(__webpack_require__.federation.initOptions,\"remotes\",()=>Object.values(__module_federation_remote_infos__).flat().filter(remote=>remote.externalType===\"script\"));merge(__webpack_require__.federation.initOptions,\"plugins\",()=>__module_federation_runtime_plugins__);early(__webpack_require__.federation,\"bundlerRuntimeOptions\",()=>({}));early(__webpack_require__.federation.bundlerRuntimeOptions,\"remotes\",()=>({}));early(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"chunkMapping\",()=>remotesLoadingChunkMapping);early(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"idToExternalAndNameMapping\",()=>{const remotesLoadingIdToExternalAndNameMappingMapping={};for(let[moduleId,data]of Object.entries(remotesLoadingModuleIdToRemoteDataMapping)){remotesLoadingIdToExternalAndNameMappingMapping[moduleId]=[data.shareScope,data.name,data.externalModuleId,data.remoteName]}return remotesLoadingIdToExternalAndNameMappingMapping});early(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"webpackRequire\",()=>__webpack_require__);merge(__webpack_require__.federation.bundlerRuntimeOptions.remotes,\"idToRemoteMap\",()=>{const idToRemoteMap={};for(let[id,remoteData]of Object.entries(remotesLoadingModuleIdToRemoteDataMapping)){const info=__module_federation_remote_infos__[remoteData.remoteName];if(info)idToRemoteMap[id]=info}return idToRemoteMap});override(__webpack_require__,\"S\",__webpack_require__.federation.bundlerRuntime.S);if(__webpack_require__.federation.attachShareScopeMap){__webpack_require__.federation.attachShareScopeMap(__webpack_require__)}override(__webpack_require__.f,\"remotes\",(chunkId,promises)=>__webpack_require__.federation.bundlerRuntime.remotes({chunkId,promises,chunkMapping:remotesLoadingChunkMapping,idToExternalAndNameMapping:__webpack_require__.federation.bundlerRuntimeOptions.remotes.idToExternalAndNameMapping,idToRemoteMap:__webpack_require__.federation.bundlerRuntimeOptions.remotes.idToRemoteMap,webpackRequire:__webpack_require__}));override(__webpack_require__.f,\"consumes\",(chunkId,promises)=>__webpack_require__.federation.bundlerRuntime.consumes({chunkId,promises,chunkMapping:consumesLoadingChunkMapping,moduleToHandlerMapping:__webpack_require__.federation.consumesLoadingModuleToHandlerMapping,installedModules:consumesLoadinginstalledModules,webpackRequire:__webpack_require__}));override(__webpack_require__,\"I\",(name,initScope)=>__webpack_require__.federation.bundlerRuntime.I({shareScopeName:name,initScope,initPromises:initializeSharingInitPromises,initTokens:initializeSharingInitTokens,webpackRequire:__webpack_require__}));override(__webpack_require__,\"initContainer\",(shareScope,initScope,remoteEntryInitOptions)=>__webpack_require__.federation.bundlerRuntime.initContainerEntry({shareScope,initScope,remoteEntryInitOptions,shareScopeKey:containerShareScope,webpackRequire:__webpack_require__}));override(__webpack_require__,\"getContainer\",(module1,getScope)=>{var moduleMap=__webpack_require__.initializeExposesData.moduleMap;__webpack_require__.R=getScope;getScope=Object.prototype.hasOwnProperty.call(moduleMap,module1)?moduleMap[module1]():Promise.resolve().then(()=>{throw new Error('Module \"'+module1+'\" does not exist in container.')});__webpack_require__.R=undefined;return getScope});__webpack_require__.federation.instance=__webpack_require__.federation.runtime.init(__webpack_require__.federation.initOptions);if((__webpack_require___consumesLoadingData2=__webpack_require__.consumesLoadingData)===null||__webpack_require___consumesLoadingData2===void 0?void 0:__webpack_require___consumesLoadingData2.initialConsumes){__webpack_require__.federation.bundlerRuntime.installInitialConsumes({webpackRequire:__webpack_require__,installedModules:consumesLoadinginstalledModules,initialConsumes:__webpack_require__.consumesLoadingData.initialConsumes,moduleToHandlerMapping:__webpack_require__.federation.consumesLoadingModuleToHandlerMapping})}}");
var __webpack_exports__ = __webpack_require__("./index.js");
})()

This can be worked around by declaring react and react-native as runtime shared deps and it works quite well, but it's not so easy to do this for deep imports which we need in some places (like WebpackHMRClient or configurePublicPath) and we need to ensure those are singletons as well. Having entry prepended to everything else like in Webpack would be perfect, wondering if Rspack allows to modify entries in such way?

Anyways, the biggest issue is to figure out how we can deal with the patch and move forward with the MF2 in Re.Pack.

Scratch the Rspack part, figured it out by reordering EntryPlugins and adding some shims for the startup, works essentially the same as on webpack now 🎉

Copy link

github-actions bot commented Sep 1, 2024

This issue has been marked as stale because it has been inactive for 30 days. Please update this issue or it will be automatically closed in 14 days.

@github-actions github-actions bot added the Stale label Sep 1, 2024
@jbroma jbroma removed the Stale label Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:repack The issue is about logic/code inside of Re.Pack. status:wip The issue is being worked on. type:feature Proposal or idea for a new feature or enhancement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants