Feature: MFE import functions
Clear and concise description of the problem
Angular architects has their own code to import modules using import(). https://github.com/angular-architects/module-federation-plugin/blob/main/libs/mf-runtime/src/lib/loader/dynamic-federation.ts
You have an example doing something similar for React. https://github.com/module-federation/module-federation-examples/blob/master/advanced-api/dynamic-remotes-runtime-environment-variables/host/src/hooks/useFederatedComponent.js
Would it be possible to generalize what your code uses like how angular architects has? It would be amazing if there was a single library that could leverage the high customization level the advanced mod fed plugin has and provides functions that can create a shared scope, import MFEs and even import/initialize web components. This library has everything I want to customize the remoteEntry.js file, but now it needs some helper functions to import these MFEs and share a scope object between them.
Suggested solution
There are a bunch of different ways to achieve this.
prototype code of mine using systemjs
// https://medium.com/@rkhasawneh/single-spa-with-module-federation-in-systemjs-446f0de4832b
// https://github.com/rami8k/spa-complete-example
export async function importApp(app, shareScope, importedApps) {
let appParts = getAppParts(app)
// if no module property then this MFE isn't using module federation
if(!appParts.module) {
return System.import(appParts.app);
}
return System.import(appParts.app).then(app => {
if(!importedApps.includes(appParts.app)) {
// https://webpack.js.org/concepts/module-federation/#dynamic-remote-containers
app.init(shareScope)
}
if(appParts.module) {
return app.get(appParts.module).then(module => {
return module();
});
} else {
return app;
}
});
}
function getAppParts(app) {
let appParts = app.split('/')
if(app.startsWith('@') && appParts.length > 2) {
return {
app: `${appParts[0]}/${appParts[1]}`,
module: appParts.length > 2 ? appParts[2] : null
}
}
return {
app: appParts[0],
module: appParts[1]
}
}
You could take inspiration from how @angular-architects does it https://github.com/angular-architects/module-federation-plugin/blob/main/libs/mf-runtime/src/lib/loader/dynamic-federation.ts
This prototype of mine tries to be able to import both MFEs and module federated MFEs using @angular-architects/mod-fed and systemjs. No fear posting this code here.
let importedApps = [];
let shareScope = [];
export async function importApp(app, shareScope, importedApps) {
let appParts = getAppParts(app);
// if(!appParts.module) {
// return System.import(appParts.app);
// }
// if(app == "consumer-services") {
// const s = {
// type: "manifest",
// remoteName: appParts.app,
// exposedModule: `./${appParts.module ? appParts.module : ''}`
// } as LoadRemoteModuleOptions;
// return loadRemoteModule(s);
// const url = System.resolve(appParts.app);
// const s = {
// type: "manifest",
// remoteName: appParts.app,
// exposedModule: `./${appParts.module ? appParts.module : ''}`
// } as LoadRemoteModuleOptions;
// return loadRemoteModule(s).then(
// (module) => {console.log(module); System.set(appParts.app, module); return module;}
// );
// return await import(/* webpackIgnore:true */ url).then(
// (see) => {
// System.set(appParts.app, see);
// return see;
// }
// );
// } else {
return System.import(appParts.app).then(app => {
if(!importedApps.includes(appParts.app) && app.init !== undefined) {
// const s = {
// type: "manifest",
// remoteName: appParts.app,
// exposedModule: `./${appParts.module ? appParts.module : ''}`
// } as LoadRemoteModuleOptions;
// return loadRemoteModule(s);
app.init(shareScope);
}
if(app.get !== undefined) {
return app.get(`./${appParts.module ? appParts.module : ''}`).then(module => {
return module();
})
} else {
return app;
}
});
// }
}
function getAppParts(app) {
let appParts = app.split('/')
if(app.startsWith('@')) {
if(appParts.length > 2) {
return {
app: `${appParts[0]}/${appParts[1]}`,
module: appParts.length > 2 ? appParts[2] : null
}
}
}
return {
app: appParts[0],
module: appParts.length > 2 ? appParts[1] : null
};
}
Alternative
No response
Additional context
No response
Validations
- [X] Read the Contributing Guidelines.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Just use module-federation/runtime. LoadRemote and init
https://module-federation.io/guide/basic/runtime.html
https://github.com/module-federation/module-federation-examples/tree/master/dynamic-system-host
Is there a function I can call to pass my manifest json to? I prefer to using that than hardcoding. I do have it calling init(), but there's a weird build error. Also you should be exporting the object type the init method references to make typing easier. Makes it hard to type stuff.
Provide a repo or send a PR for the TS stuff.
If you use a runtime plugin you can change the remotes on the fly.
Stale issue message
That's what I've done.
Is there a function I can call to pass my manifest json to? I prefer to using that than hardcoding. I do have it calling init(), but there's a weird build error. Also you should be exporting the object type the init method references to make typing easier. Makes it hard to type stuff.
![]()
Send a PR improving our types if you wish.
