Skip to content

feat: add remoteHmrStrategy option to control cross-federation HMR#654

Merged
gioboa merged 6 commits intomodule-federation:mainfrom
spralle:feat/native-hmr-strategy
May 3, 2026
Merged

feat: add remoteHmrStrategy option to control cross-federation HMR#654
gioboa merged 6 commits intomodule-federation:mainfrom
spralle:feat/native-hmr-strategy

Conversation

@spralle
Copy link
Copy Markdown
Contributor

@spralle spralle commented Apr 26, 2026

Close #592

Summary

Addresses #592 — auto-detects React and suppresses the broadcast/relay mechanism so Vite's native HMR (React Fast Refresh) handles cross-federation updates instead of full page reloads.

Problem

When dev.remoteHmr is enabled, pluginDevRemoteHmr unconditionally relays remote file changes as { type: 'full-reload' } to the host browser. With React Fast Refresh (and the shared /@react-refresh proxy from #653), the component updates fine via native HMR — then the relay immediately nukes it with a full page reload.

Solution

Auto-detect React from the Vite plugin pipeline. When vite:react-refresh or vite:react-swc:refresh is present, suppress the broadcast (remote side) and relay (host side) so React Fast Refresh handles it.

Only React is supported for now — it's the only framework with cross-federation HMR plumbing (the shared /@react-refresh proxy from #653). Vue, Svelte, Solid have native HMR but no equivalent shared-runtime proxy yet, so they stay on full-reload. Easy to extend once the plumbing exists.

An explicit dev.remoteHmrStrategy escape hatch is available:

  • 'full-reload': Force broadcast/relay even with React
  • 'native': Force native HMR even without a detected framework
  • undefined (default): Auto-detect

Backwards compatibility

  • No React plugin → unchanged (full-reload)
  • React plugin detected → suppressed (native HMR)
  • Explicit config overrides auto-detection

Testing

  • 3 tests: React suppresses broadcast, no-React broadcasts, explicit override
  • All 279 tests pass
  • Format check passes

Comment thread src/utils/normalizeModuleFederationOptions.ts Outdated
@spralle spralle force-pushed the feat/native-hmr-strategy branch from 7a86c48 to 64b6ca2 Compare April 26, 2026 20:05
Auto-detect frameworks with native HMR support (React, Vue, Svelte,
Solid) from the Vite plugin pipeline. When detected, suppress the
broadcast/relay mechanism and let Vite's native HMR handle updates.

Detection checks plugin names: vite:react-refresh, vite:react-swc:refresh,
vite:vue, vite-plugin-svelte, solid. The explicit remoteHmrStrategy
config option is kept as an override for edge cases.

Default behavior for setups without a recognized framework plugin is
unchanged (full-reload).
@spralle spralle force-pushed the feat/native-hmr-strategy branch from 64b6ca2 to 6a4d369 Compare April 26, 2026 20:47
spralle added 2 commits April 26, 2026 22:59
Only React has cross-federation HMR plumbing (the shared /@react-refresh
proxy from module-federation#653). Vue, Svelte, and Solid have native HMR but no
equivalent cross-federation mechanism — suppressing broadcast/relay for
them would leave users with no HMR at all. Trimmed tests accordingly.
Framework-agnostic name so adding Vue/Svelte/Solid later is just
appending to the supportedPlugins list.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 27, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@module-federation/vite@654

commit: bdb0516

Merge remoteHmrStrategy into remoteHmr per review feedback. true enables auto-detected native HMR, 'full-reload' forces broadcast/relay.
@spralle
Copy link
Copy Markdown
Contributor Author

spralle commented Apr 28, 2026

Good idea, have changed it accordingly.

Comment thread src/utils/normalizeModuleFederationOptions.ts
Copy link
Copy Markdown
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.

Image

I tested this PR with this repo, HMR is not working though. Can you double check it please?

@spralle
Copy link
Copy Markdown
Contributor Author

spralle commented Apr 30, 2026

showcase_hmr

I seem to have not posted my response. From what I know (not an expert) react fast refresh doesn't like anonymous default exports, it can't track them then you get a state reset like what you see. Also your repo didn't target the right PR? (654?)

@gioboa
Copy link
Copy Markdown
Collaborator

gioboa commented Apr 30, 2026

I'm testing different versions on that repo. I run my test with the correct one.

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

Nice call btw. I am wondering if we can patch that plug-in somehow 🤔

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

Tests With Different Frameworks

Image

Copy link
Copy Markdown
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 that's great 👏 @spralle

@gioboa gioboa merged commit 6c3e053 into module-federation:main May 3, 2026
19 checks passed
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.

feat: support real HMR rather than live reload

2 participants