module-federation / module-federation-examples

Implementation examples of module federation , by the creators of module federation
https://module-federation.io/
MIT License
5.54k stars 1.73k forks source link

[Question] Shared modules are duplicate in multi-bundle files of MF v8.2.2 above #3776

Open duyphuong2101 opened 5 months ago

duyphuong2101 commented 5 months ago

Hi guy,

By using webpack-bundle-analyzer to analyze the shell app, we can see all shared lib and @module-federation are included in the multi-bundle files. Here is what we have by analyzing the react-18-ssr example:

- In shell-app server: image

- In client: image

My next.config.js shell-app:

const moduleFederationConfig = {
      name: 'SHELL',
      filename: 'static/chunks/remoteEntry.js',
      remotes: getRemotes(isServer),
      shared: {
        '@t1rearc-ui-base/core': {
          singleton: true,
          eager: true,
          requiredVersion: dependencies['@t1rearc-ui-base/core'],
        },
        zustand: {
          singleton: true,
          requiredVersion: dependencies['zustand'],
        },
      },
    };

But currently, I use MF v7.0.8 it doesn't have this error Please help me re-check the bundle of MF v8.2.2 above! Thanks all,

### Tasks
ScriptedAlchemy commented 5 months ago

Due to bug in webpack and federation when single runtime chunk is used.

Shared modules are only hoisted up to the entrypoint level, not the runtime level - causing duplication acorss entrypoints.

ScriptedAlchemy commented 5 months ago

I should be releaseing support for splitChunks api in next which may improve this issue for you

duyphuong2101 commented 5 months ago

Thanks @ScriptedAlchemy

ScriptedAlchemy commented 4 months ago

@duyphuong2101 you can try this release, i cut it with the new split chunks mods - you can see if it works better or not. 0.0.0-next-20240424224724

duyphuong2101 commented 4 months ago

@ScriptedAlchemy Thanks, I will try the version on my project, and whether it works well or not I will report back to you.

duyphuong2101 commented 4 months ago

Hi @ScriptedAlchemy I took version 0.0.0-next-20240424224724 and tested it on my project, but still getting the same errors. You can take my test project to check

https://github.com/duannx/mf-duplicate-bundle-size-issue/blob/master/README.md

ScriptedAlchemy commented 4 months ago

Are you sharing lodash as eager? Don't use eager sharing

duannx commented 4 months ago

Hi @ScriptedAlchemy, I'm taking over for my colleague.

Yes, we are using eager. We tested with eager : false and lodash is correctly tree-shaken. But the module federation bundle is still there and is duplicated into three chunks: main, webpack, and remoteEntry. All of them are used on the page so we are loading redundant JS

I have a small concern about the eager option. So we should not use it anymore, should we? Is there any difference between eager : true and eager : false on the latest version of @module-federation/nextjs-mf? The reason that we want to use eager : true is that some modules really need to be loaded before other modules. Because they are dependencies of others in a complexity graph. I'm not sure if switching to eager : false would introduce another issue that we don't foresee

Thanks in advance!

image

ScriptedAlchemy commented 4 months ago

Okay the federation package duplicaiton, this is because of how next works. We inject federation runtime into the entrypoint, i then manually use another plugin for next to hoist it into the runtime chunk, but because next uses entry routing and single runtime chunk - each entrypoint contains the runtime package. I can try and scope this down specifically for next.js by attempting to only inject federation runtime into _app.js - next is very sub-optimal unfortunately.

Regarding eager use, eager:true hoists the modules to the top of the runtime, except in next where it only hoists them to the entrypoints, not to the runtime chunks - making eager true not actually eager since its sitting in the entrypoint not the webpack runtime chunk. This is a problem in the eager + multi entry + single runtime chunk, this is a problem in webpacks core.

Instead of relying on eager to try and ensure dependnecy control id use a runtime plugin. With runtime plugins you can take control of the resolver logic of shared and you can force your remotes to always "pick" a certan shared module from another host/remote.

Look at the nextjs internal runtime plugin for example, the runtime plugin uses resolveShare which tells all remotes to prefer the hosts react and react dom, as well and the hosts next/router share over any others provided by the system. Effectively works like what youre trying to do with eager true, which is ensure that the loaded one is used.

https://github.com/module-federation/core/blob/main/packages/nextjs-mf/src/plugins/container/runtimePlugin.ts

Resolve share would let you control this deterministically.

duannx commented 4 months ago

Thank you for that. I'll give it a try

duannx commented 3 months ago

Hi @ScriptedAlchemy, is there any update on this issue? Thank you!

vunguyen10111995 commented 3 months ago

Hi @ScriptedAlchemy, I also get the same problem. Have you had any updated on this issue? I think that is not a small issue so if this issue is fixed, that is a most significant point at this moment. I can not wait more time.

ScriptedAlchemy commented 3 months ago

Hi @ScriptedAlchemy, I also get the same problem.

Have you had any updated on this issue?

I think that is not a small issue so if this issue is fixed, that is a most significant point at this moment.

I can not wait more time.

Does this release solve the problem?

0.0.0-next-20240424224724

vunguyen10111995 commented 3 months ago

Hi @ScriptedAlchemy , I have checked on the new version that you provided but the issue is happened. When I checked the the bundle on analyzer tool, I also saw the duplication of the module-federation. Can you double check that?

duannx commented 3 months ago

Hi @ScriptedAlchemy , the module-federation package is still being duplicated. I tested with the latest version @module-federation/nextjs-mf@8.3.21, but the issue persists. This is a blocker for us in upgrading to @module-federation/nextjs-mf@8, as performance is critically important to us.

The size of the module-federation package is 96KB (21KB gzipped). Tripling this size would have a significant impact.

Is there any change that I can work on it? Please provide me with some instructions.

Thank you for your assistance.

ScriptedAlchemy commented 2 months ago

This is the PR that has the code to re-enable code splitting - which would allow less duplication as it would create another chunk most likely.

https://github.com/module-federation/core/pull/2013