I've been playing around with this module federation example, where the setup is relatively straightforward - a host is consuming a module from a remote with a shared react dependency. When running this locally, I noticed that despite both host and remote having the same react/react-dom versions, the remote's version is always the one downloaded.
Based on my research it seems that module federation will pick the "best" version of shared dependencies, but I'm surprised that the remote one will be chosen in a case where both have the same version. How is this decision made? Is there a way to force the host's version to be used in this case?
Module Federation allows loading separately compiled applications at runtime. Also, we can share common dependencies. This also allows sharing common data like information on the current user or global filters.
Introduced in Webpack 5, the Module Federation plugin gives developers a way to create multiple separate builds that form a single application. Any JavaScript application that is bundled with Webpack 5.0 or greater can dynamically load or share code and dependencies with any other at runtime.
__webpack_init_sharing__ : This is a Webpack default variable that initializes the shared scope and adds all the known provided modules from the local build or the remote container build. __webpack_share_scopes__ : This is also a default Webpack variable, which initializes the exposed module or the container.
It is now possible to use Module Federation without the restrictions of Vite and Webpack ! That is, you can choose to use the components exposed by vite-plugin-federation in Webpack or the components exposed by Webpack ModuleFederationPlugin in Vite .
Basically, when your host starts up it will register all the versions it has into the shared scope. Every time you load a remoteEntry.js
from a remote, the remote will also add their versions to this same scope, but only if that exact version does not exist already.
So for example, if the host shares module-a
at version 1.0.0
. When the host loads it will put module-a:1.0.0
into the shared context. If the remote also shares module-a:1.0.0
it will not put it in the context, because it is already there. If the host was sharing module-a:1.0.1
then the context will now have two versions: the module-a:1.0.0
from the host and module-a:1.0.1
from the remote.
At this point we are just talking about registration... we haven't chosen which version to use, but we are registering all unique versions shared from all remotes and hosts. And basically the first to register it wins.
Now when the version resolution algorithm runs... it will figure out based on all the requirements which version to use. If the algorithm chooses version 1.0.0
of the module, then it will go to the scope and use whatever module is assigned to version 1.0.0
which in this case would be the one from the host, because the host ran first and was able to register it first. If the algorithm picked 1.0.1
it would use the module from the remote. If multiple remotes provided 1.0.1
then it will use the one from the remote that first registered it into the scope.
This article explains the mechanism very well. https://www.angulararchitects.io/en/aktuelles/getting-out-of-version-mismatch-hell-with-module-federation/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With