-
Notifications
You must be signed in to change notification settings - Fork 110
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
Comments
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 Could you point me to some resources on what features MF 1.5 offers? |
yeah so for RN this is what i was thinking which may help the chunk manager thing. Then for defining remotes etc, we can do things like this: Resources: We are also finalizing a new api for adding remotes on the fly: Heres a post i wrote about it: 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. 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) |
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. |
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. |
Bump, not stale |
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: I've also noticed that For the Rspack part: 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/@[email protected]/node_modules/@react-native/js-polyfills/console.js");
/******/ __webpack_require__("../../node_modules/.pnpm/@[email protected]/node_modules/@react-native/js-polyfills/error-guard.js");
/******/ __webpack_require__("../../node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]_@[email protected]__@[email protected][email protected]/node_modules/react-native/Libraries/Core/InitializeCore.js");
/******/ __webpack_require__("../../packages/repack/dist/modules/configurePublicPath.js");
/******/ __webpack_require__("../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/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/@[email protected]/node_modules/@react-native/js-polyfills/console.js");
__webpack_require__("../../../node_modules/.pnpm/@[email protected]/node_modules/@react-native/js-polyfills/error-guard.js");
__webpack_require__("../../../node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]_@[email protected]__@[email protected][email protected]/node_modules/react-native/Libraries/Core/InitializeCore.js");
__webpack_require__("../../../packages/repack/dist/modules/configurePublicPath.js");
__webpack_require__("../../../node_modules/.pnpm/@[email protected][email protected]/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/@[email protected]/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 Anyways, the biggest issue is to figure out how we can deal with the patch and move forward with the MF2 in Re.Pack. |
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? |
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 🎉 |
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. |
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. |
This issue has been automatically closed because it has been inactive for more than 14 days. Please reopen if you want to add more context. |
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
The text was updated successfully, but these errors were encountered: