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

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

Open
duyphuong2101 opened this issue Mar 28, 2024 · 10 comments

Comments

@duyphuong2101
Copy link

duyphuong2101 commented Mar 28, 2024

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

No tasks being tracked yet.
@ScriptedAlchemy
Copy link
Member

ScriptedAlchemy commented Apr 2, 2024

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
Copy link
Member

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

@duyphuong2101
Copy link
Author

Thanks @ScriptedAlchemy

@ScriptedAlchemy
Copy link
Member

@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
Copy link
Author

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

@duyphuong2101
Copy link
Author

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
Copy link
Member

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

@duannx
Copy link

duannx commented May 7, 2024

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
Copy link
Member

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
Copy link

duannx commented May 10, 2024

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

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

3 participants