vite icon indicating copy to clipboard operation
vite copied to clipboard

✨ Vite 7 Support

Open pcfreak30 opened this issue 5 months ago • 6 comments

Describe the bug

error during build:
Build failed with 1 error:

[plugin vite:oxc-transpile]
Error: `await` is only allowed within async functions and at the top levels of modules
11 |            requiredVersion: "18"
12 |    } } }));
13 |    const exportModule = await res.then((factory) => factory());
   |                        ^^^^^
14 |    module.exports = exportModule;
15 |  });
    at transformWithOxc

This is connected to https://github.com/module-federation/vite/blob/e7ff316cc6c073224007dcbc39914dc94f20a077/src/virtualModules/virtualShared_preBuild.ts#L39

I have tried to debug further but vite 7 is making it extremely hard to breakpoint and debug inside the plugin. So it is unclear if I will be able to get a solution if I can't do so.

I am unsure also what has changed. The info I was able to extract though is the following from the vite-vite/vite-host example app:

import { __commonJSMin } from "./chunk-!~{004}~.js";
import { require_index_cjs, require_viteViteHost__mf_v__runtimeInit__mf_v__ } from "./viteViteHost__mf_v__runtimeInit__mf_v__-!~{008}~.js";

//#region node_modules/__mf__virtual/viteViteHost__loadShare__react__loadShare__.js
var require_viteViteHost__loadShare__react__loadShare__ = __commonJSMin((exports, module) => {
	const { loadShare } = require_index_cjs();
	const { initPromise } = require_viteViteHost__mf_v__runtimeInit__mf_v__();
	const res = initPromise.then((_) => loadShare("react", { customShareInfo: { shareConfig: {
		singleton: false,
		strictVersion: false,
		requiredVersion: "18"
	} } }));
	const exportModule = await res.then((factory) => factory());
	module.exports = exportModule;
});

//#endregion
export { require_viteViteHost__loadShare__react__loadShare__ };

What stands out is the __commonJSMin wrapper being used which is a core entity/mechanism in rolldown https://github.com/rolldown/rolldown/blob/9c158fe6aa9296b0da53ec044dcfa78014e0f629/crates/rolldown/src/runtime/index.js#L22 . Unclear why its getting done like this, but the current approach has some clear issues with v7.

Version

7.0.10

Reproduction

n/a

Relevant log output


Validations

pcfreak30 avatar Jul 23 '25 18:07 pcfreak30

Thanks for your report @pcfreak30 This plugin is not tested with Vite v7 in fact we have another issue similar to this #315

gioboa avatar Jul 23 '25 18:07 gioboa

Thanks for your report @pcfreak30 This plugin is not tested with Vite v7 in fact we have another issue similar to this #315

Yes im aware, but that is just a types issue, not a runtime issue.

pcfreak30 avatar Jul 23 '25 19:07 pcfreak30

This would very likely also make it compatible with rolldown-vite, which will be upon us officially soon enough... After using rolldown-vite it is extremely hard to justify using anything else... Vite is often an order of magnitude faster than other similar tools, and on my relatively complex project production build literally goes from ~2minutes to ~11s with rolldown-vite. So potentially two orders of magnitude faster...

AntonOfTheWoods avatar Sep 21 '25 07:09 AntonOfTheWoods

This would very likely also make it compatible with rolldown-vite, which will be upon us officially soon enough... After using rolldown-vite it is extremely hard to justify using anything else... Vite is often an order of magnitude faster than other similar tools, and on my relatively complex project production build literally goes from ~2minutes to ~11s with rolldown-vite. So potentially two orders of magnitude faster...

Which is likely that as soon as rolldowns MF is feature-competitive with this plugin I will likely jump ship.

pcfreak30 avatar Sep 21 '25 10:09 pcfreak30

"vite": "7.1.7" works fine, everything above breaks

0-don avatar Oct 16 '25 13:10 0-don

may switch to the default @vite/plugin-react helps, opt to plugin-react-swc, plugin-react-oxc

songlairui avatar Oct 29 '25 11:10 songlairui

Additional Analysis & Workaround

I've been debugging this issue extensively with Vite 7.2.7 and @module-federation/vite 1.9.2. Here's what I found:

Two Related Issues

Issue 1: Syntax Error (what this issue describes) Vite 7's Rolldown bundler wraps CommonJS modules with __commonJSMin((exports, module) => { ... }). The generated code in virtualShared_preBuild.ts uses: const exportModule = await res.then((factory) => factory()); module.exports = exportModule;This puts await inside a non-async arrow function → syntax error.

Issue 2: Circular Deadlock (even if syntax issue is fixed) When React/ReactDOM are in shared, the build creates a circular dependency:

  1. hostInit uses Vite's preload helper to import("remoteEntry.js")
  2. The preload helper gets bundled into the React chunk (common dependency)
  3. React chunk has top-level await: await initPromise.then(runtime => runtime.loadShare("react"))
  4. initPromise is only resolved when remoteEntry.init() is called
  5. DEADLOCK: React waits for remoteEntry → hostInit can't load remoteEntry until React finishes

The app shows a blank page with no console errors because the deadlock happens silently.

Workaround

Setting shared: {} bypasses both issues:

federation({
  name: 'my_app',
  remotes: { ... },
  shared: {},  // Workaround: empty shared config
})

The MFE still loads via registerRemotes() at runtime - each app just bundles its own React. Not ideal for optimization, but functional.

The generated code in virtualShared_preBuild.ts needs to:

  1. Use ES module syntax instead of CommonJS (export instead of module.exports)
  2. OR wrap in an async IIFE
  3. OR use a lazy initialization pattern that doesn't block module execution

Happy to help with a PR if maintainers can provide guidance on preferred approach.

Environment

  • Vite: 7.2.7
  • @module-federation/vite: 1.9.2
  • React: 19.2.0
  • Node: 22.x

DallasCarraher avatar Dec 10 '25 19:12 DallasCarraher

5. DEADLOCK: React waits for remoteEntry → hostInit can't load remoteEntry until React finishes

Ive hit this type of thing before myself as I think it can happen in other cases but its, in effect, a circular dependency on the promise loading of the module system. The MFE still loads via registerRemotes() at runtime - each app just bundles its own React. For me thats a deal breaker, as I cant have that and would need to debug the import loop if it happened to me...

The generated code in virtualShared_preBuild.ts needs to:

  1. Use ES module syntax instead of CommonJS (export instead of module.exports)
  2. OR wrap in an async IIFE
  3. OR use a lazy initialization pattern that doesn't block module execution

We need to be sure it stays working in vite 6 as well.

pcfreak30 avatar Dec 11 '25 02:12 pcfreak30