Comments (7)
I need to update the redux example still to use new apis etc from federation
from module-federation-examples.
use dynamic remotes like this.
use module-federation/enhanced
as well
from module-federation-examples.
id love to chip in, yet dont know if you meant it as a "wow theres so much to it, i might do this myself" or more of a "good if this gets an update sometime"
from module-federation-examples.
Well I'm trying to update as many as I can but it's very repetitive and takes a long time. But the tasks are not particularly difficult to port. There's just a lot. By all means feel free to look at any of the examples. All webpack ones still use v1 MF from webpack. But rspack ships with enhanced built in. If you want to give it a stab I'll push to a branch etc if needed.
from module-federation-examples.
Resources
here is the official documentation:
https://webpack.js.org/concepts/module-federation/
i am going to link mentioned resources here just for further reference:
https://github.com/module-federation/universe/tree/main/packages/runtime
https://github.com/module-federation/universe/tree/main/packages/enhanced
id like to include the video and its resources as well:
webpack/webpack.js.org#3757
https://www.youtube.com/watch?v=9F7GoDMrzeQ
Contention
after having a look i assume the dynamic remote pattern applies for it is the remote which should override the mutated store, due to injecting its reducer into it, making it accessible to the host via the App component.
Reasoning
from the official documentation
Each build acts as a container and also consumes other builds as containers. This way, each build is able to access any other exposed module by loading it from its container.
Shared modules are modules that are both overridable and provided as overrides to nested containers. They usually point to the same module in each build, e.g., the same library.
the loadComponent function
// from example dynamic-remotes
function loadComponent(scope, module) {
return async () => {
// Initializes the share scope. This fills it with known provided modules from this build and all remotes
const Module = await loadRemote(`${scope}/${module.slice(2)}`);
return Module;
};
}
which relies on the loadRemote function
https://github.com/module-federation/universe/blob/b129098e1004a2577bc43c9bf2c5004ce928b399/packages/runtime/src/core.ts#L556
async loadRemote<T>(
id: string,
options?: { loadFactory?: boolean; from: 'build' | 'runtime' },
): Promise<T | null> {
try {
const { loadFactory = true } = options || { loadFactory: true };
// 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.
// 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.
// 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)
// 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get
// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
// id: alias(app1) + expose(button) = app1/button
// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
const { module, moduleOptions, remoteMatchInfo } =
await this._getRemoteModuleAndOptions(id);
const { pkgNameOrAlias, remote, expose, id: idRes } = remoteMatchInfo;
const moduleOrFactory = (await module.get(expose, options)) as T;
await this.hooks.lifecycle.onLoad.emit({
id: idRes,
pkgNameOrAlias,
expose,
exposeModule: loadFactory ? moduleOrFactory : undefined,
exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,
remote,
options: moduleOptions,
moduleInstance: module,
origin: this,
});
return moduleOrFactory;
} catch (error) {
const { from = 'runtime' } = options || { from: 'runtime' };
const failOver = await this.hooks.lifecycle.errorLoadRemote.emit({
id,
error,
from,
origin: this,
});
if (!failOver) {
throw error;
}
return failOver as T;
}
}
should load a shared container and initialize sharing on webpack
// ./core/src/api/api.ts
16 export async function loadAndInitializeRemote(
17 remoteOptions: RemoteOptions,
18 ): Promise<RemoteContainer> {
19 const globalScope = getScope();
20 const containerKey = getContainerKey(remoteOptions);
21
22 // TODO: Make this generic, possibly the runtime?
23 const asyncContainer = loadScript(containerKey, remoteOptions);
24
25 if (!asyncContainer) {
26 throw new Error('Unable to load remote container');
27 }
28
29 // TODO: look at init tokens, pass to getSharingScope
30
31 if (!globalScope.__sharing_scope__) {
32 // TODO: Make this generic, possibly the runtime?
33 globalScope.__sharing_scope__ = await initializeSharingScope();
34 }
35
36 return initContainer(asyncContainer, globalScope.__sharing_scope__);
37 }
// ./core/src/integrations/webpack/factory.ts
5 export async function initializeSharingScope(
6 scopeName = 'default',
7 ): Promise<SharedScope> {
8 const webpackShareScopes = __webpack_share_scopes__ as unknown as SharedScope;
9
10 if (!webpackShareScopes?.default) {
11 await __webpack_init_sharing__(scopeName);
12 }
13
14 // TODO: Why would we reference __webpack_require and not __webpack_share_scopes__ ?
15 return (__webpack_require__ as unknown as WebpackRequire)
16 .S as unknown as SharedScope;
17 }
exactly as the function would.
what i dont get, which leads me to my initial question, is how do these approaches differ from one another?
One declared within the confines of a webpack configuration and called using an import statement
// remote2/config/module-federation.js
...
exposes: {
'./App': './src/bootstrap',
},
...
// remote1/src/App.js
...
const RemoteApp = React.lazy(
() => import('remote2/App') as Promise<{ default: React.FC<{ store: AppStore }> }>,
);
...
there while the other within the App.js file (as above)
// from example dynamic-remotes
function loadComponent(scope, module) {
return async () => {
// Initializes the share scope. This fills it with known provided modules from this build and all remotes
const Module = await loadRemote(`${scope}/${module.slice(2)}`);
return Module;
};
}
sorry for updating the comment so frequently 😅
from module-federation-examples.
trying to use dynamicFederation as in
const dynamicFederation = async (scope, module) => {
const container = window[scope];
// or get the container somewhere else
// Initialize the container, it may provide shared modules
await container.init(__webpack_share_scopes__.default);
return container.get(module).then(factory => {
const Module = factory();
return Module;
});
};
sadly fails as the module scoped in window is only the current one, but id like to import from the remote one.
removing ssr is not an option.
from module-federation-examples.
related #3580
from module-federation-examples.
Related Issues (20)
- trying to mix ModuleFederationPlugin doesnt work as expected HOT 1
- circular dependency on federated router HOT 1
- no vite-side remoteEntry.js HOT 3
- rspack-webpack-offload no work! HOT 2
- 404 pages are rendered in federated URLs in nextjs v13 with nextjs-mf v8. HOT 2
- issue with makeSerializable HOT 12
- Child Applications are re-rendering and the states are getting reset when the apllications are loaded using the concept of Dynamic Remote Containers HOT 1
- App router support HOT 7
- NEXT_PRIVATE_LOCAL_WEBPACK HOT 10
- Invalid hook call. Hooks can only be called inside of the body of a function component. HOT 1
- Remote is online but error log says offline HOT 1
- "simple-node" example fails if update "@module-federation/node" dependency to "2.0.11" HOT 2
- Module not found: Can't resolve 'encoding' in '../node_modules/node-fetch/lib' HOT 3
- Please use Angular17.2 as the shell, use the Native Federation package, Angular12 as the remote, use the Module Federation package. Is there any such example? HOT 1
- Is there any example of using server rendering with rspack? HOT 1
- vite-react-microfrontends demo missing file HOT 5
- nextjs(host)+ react webpack(remote):No ModuleFederationPlugin(s) found. HOT 15
- Any Next.js 14 example? HOT 2
- nextjs-v13 routing does not work HOT 1
- nextjs-v13 getServerSideProps not working HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from module-federation-examples.