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

External modules not shared #2739

Open
5 tasks done
althaf101 opened this issue Jul 9, 2024 · 4 comments
Open
5 tasks done

External modules not shared #2739

althaf101 opened this issue Jul 9, 2024 · 4 comments

Comments

@althaf101
Copy link

Describe the bug

Background

My module federation setup has a single host and few remotes. Host loads the commonly used vendor packages like react, react-dom, react-router-dom etc.. from my CDN. For this reason, all these common vendor codes are extenalized in the build process of the host via webpack config option externals.

Expectation

The host is supposed to share these packages with remotes, since we have enabled sharing via module federation config.

Reality

But, upon loading the remotes, what I can see is that remotes are bringing its own set of vendor packages or in other words the host's vendor packages are not shared with remote. There is no version conflict warnings from module federation and all these are marked as singletons too.

RCA

Upon digging into module federation source code, I saw that we are iterating over modules from normalModuleFactory inside the ProvideSharedPlugin [here] and this will cause all the externalized packages to get filtered out since normalModuleFactory will not have them and this is why sharing of the externalized packages is not working with module federation.

Currently, I am patching this by executing the below piece of code forcefully for extenalized modules too

compiler.hooks.finishMake.tapPromise("ProvideSharedPlugin", compilation => {
  const resolvedProvideMap = compilationData.get(compilation);
  if (!resolvedProvideMap) return Promise.resolve();
  return Promise.all(
  Array.from(
    resolvedProvideMap,
    ([resource, { config, version }]) =>
	new Promise((resolve, reject) => {
	  compilation.addInclude(
	    compiler.context,
	    new ProvideSharedDependency(
	        config.shareScope,
	        config.shareKey,
	        version || false,
		resource,
		config.eager
	    ),
	    {
		name: undefined
	    },
	    err => {
		if (err) return reject(err);
		resolve(null);
	    }
	  );
       })
     )
  ).then(() => {});
});

Ask

Sharing of extenalized modules should be handled within module federation plugin itself

Reproduction

Used Package Manager

npm

System Info

System:
    OS: macOS 14.5
    CPU: (8) arm64 Apple M1
    Memory: 131.70 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 16.20.2 - ~/.nvm/versions/node/v16.20.2/bin/node
    npm: 8.19.4 - ~/.nvm/versions/node/v16.20.2/bin/npm
  Browsers:
    Chrome: 126.0.6478.127
    Safari: 17.5

Validations

@ScriptedAlchemy
Copy link
Member

You can / should use a runtime plugin to handle this. Use the resolveShare hook and you can replace args.resolver on the hook then just make the resolver return window.react etc.

@althaf101
Copy link
Author

@ScriptedAlchemy

At-least for the moment, we are actually locked into the builtin package that comes with webpack. Can't yet switch to the independent @module-federation/enhanced package. In this case,

  1. Is there any side-effects / issues that you see with the current fix that I have applied ?
  2. Is there a better fix available than the current one that I have applied ?

@ScriptedAlchemy
Copy link
Member

No fix that i know of.

Im not sure what side effects tapping the hook twice will have. It might repeat code in your runtime

If it works, then run with it till it doesn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants