Skip to content

Conversation

@sabov
Copy link

@sabov sabov commented Dec 1, 2025

Issue: #362

Multiple instances of @module-federation/runtime are used because:

  • virtualRemoteEntry.ts imports via ESM import
  • virtualShared_preBuild.ts imports via CommonJS require

The fix is to get loadShare/loadRemote methods directly from the runtime instance that was passed through initPromise.

An alternative solution could be turning @module-federation/runtime into a singleton but there are multiple edge cases to take care of like: it could be pre-bundled in one of the remotes, multiple versions could be imported, etc.

Copy link
Collaborator

@gioboa gioboa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's awesome.
Thanks for your help @sabov
Did you test it locally?

@wojtask9
Copy link

wojtask9 commented Dec 2, 2025

it works for me (in DEV mode).
I was just about to send also the same the patch but I wasn't sure how this is related to vite build/preview.

Because I have got this errors.

image

Without this patch it builds in prod mode (but this can be my misconfiguration)

@sabov
Copy link
Author

sabov commented Dec 2, 2025

I get the same error when I try run npm run build in the vite-vite example

examples/vite-vite/vite-host on  page-reload-fix-2 [$] is 󰏗 v0.0.3 via  v18.17.0 took 2s
❯ npm run build

> examples-vite-vite-host@0.0.3 build
> vite build

vite v6.0.6 building for production...
../../../node_modules/.pnpm/@module-federation+sdk@0.18.4/node_modules/@module-federation/sdk/dist/index.cjs.cjs (651:77): Use of eval in "../../../node_modules/.pnpm/@module-federation+sdk@0.18.4/node_modules/@module-federation/sdk/dist/index.cjs.cjs" is strongly discouraged as it poses security risks and may cause issues with minification.
✓ 77 modules transformed.
x Build failed in 325ms
error during build:
src/App.jsx (14:9): "ref" is not exported by "node_modules/__mf__virtual/viteViteHost__loadShare__vue__loadShare__.js", imported by "src/App.jsx".
file: /Users/ssabov/Documents/www/vite/examples/vite-vite/vite-host/src/App.jsx:14:9

12: import { MuiDemo } from '@namespace/viteViteRemote/MuiDemo';
13: import StyledDemo from '@namespace/viteViteRemote/StyledDemo';
14: import { ref } from 'vue';
             ^
15:
16: console.log('Share Vue', ref);

    at getRollupError (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/parseAst.js:396:41)
    at error (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/parseAst.js:392:42)
    at Module.error (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:15593:16)
    at Module.traceVariable (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:16042:29)
    at ModuleScope.findVariable (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:13825:39)
    at Identifier.bind (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:5071:40)
    at CallExpression.bind (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:2654:28)
    at CallExpression.bind (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:11289:15)
    at ExpressionStatement.bind (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:2658:23)
    at Program.bind (file:///Users/ssabov/Documents/www/vite/node_modules/.pnpm/rollup@4.28.1/node_modules/rollup/dist/es/shared/node-entry.js:2654:28)

Looks like this fixes breaks something. I'll try to find a workaround.

@sabov
Copy link
Author

sabov commented Dec 2, 2025

vite-vite example looks good now both in dev and preview mods, @wojtask9 does it work on your end as well?

Screenshot 2025-12-02 at 11 02 21

@sabov sabov requested a review from gioboa December 2, 2025 10:04
@sabov
Copy link
Author

sabov commented Dec 2, 2025

Looks like the runtime.loadShare() instance method returns false when a share isn't found, while the global loadShare() function has fallback behavior to look across different share scope. This might be a breaking change for users.

Copy link
Collaborator

@gioboa gioboa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your commitment. We should definitely try with the latest module federation runtime.

@sabov
Copy link
Author

sabov commented Dec 2, 2025

Looks like the runtime.loadShare() instance method returns false when a share isn't found, while the global loadShare() function has fallback behavior to look across different share scope. This might be a breaking change for users.

Ignore this, I forgot to use lib: () => RefToLib in my other example so it looks good on my end now.

We should definitely try with the latest module federation runtime.

I can update the package and give it a try.

@wojtask9
Copy link

wojtask9 commented Dec 2, 2025

@sabov yeah :) it works in dev and prod mode. Even with bigger project (including vite 7.x).

One thing in prod mode i can see ( It does not affect application)

image

but this comes from

image

Not sure if it is related to this bug. I'll try to test a bit more to be sure that this issue isn't related to vite version or this this changes (cache or something else)

@sabov
Copy link
Author

sabov commented Dec 2, 2025

Thanks for confirming, @wojtask9!

Re: breaking change or not

After a couple of tests I see that with and without the fix in some cases a page still must be loaded twice (I can't reproduce it in the examples).

  • without the fix the page would just hang because of a dead lock: two promises wait for each other to resolve.
  • with the fix there will be an error like factory is not a function. After a page reload it will work fine as before.

I believe this is another issue related to remoteEntry.js being generated with usedShared containing only the shares discovered so far but in some cases it might miss deps and won't be updated unless I reload the page. A workaround on my end is to specify lib in the runtime shared config.

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

Successfully merging this pull request may close these issues.

3 participants