feat: process HMR registerBundle calls from same origin only (#51821)

Summary:
Part of https://github.com/facebook/metro/issues/1480

This PR adds a check in `HMRClient.js` that prevents processing `registerBundle` calls coming from different origin than the one declared in HMR `setup()`.

This is useful in a Module Federation setup, where we have multiple HMRClients present in runtime - when Host loads external remote, the requestURL will have different origin, but it will be processed by the HMRClient from the Host which in turn causes a runtime error.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[GENERAL] [ADDED] - Process HMR registerBundle calls from the same origin only

Pull Request resolved: https://github.com/facebook/react-native/pull/51821

Test Plan: TBD

Reviewed By: christophpurrer

Differential Revision: D76044353

Pulled By: huntie

fbshipit-source-id: 3928347b1e9a90355d02b87b07fde812479bcb67
This commit is contained in:
Jakub Romanczyk
2025-06-06 02:54:04 -07:00
committed by Facebook GitHub Bot
parent e17eab4947
commit a9007ea586
+12 -2
View File
@@ -23,6 +23,7 @@ const prettyFormat = require('pretty-format');
const pendingEntryPoints = [];
let hmrClient = null;
let hmrUnavailableReason: string | null = null;
let hmrOrigin: string | null = null;
let currentCompileErrorMessage: string | null = null;
let didConnect: boolean = false;
let pendingLogs: Array<[LogLevel, $ReadOnlyArray<mixed>]> = [];
@@ -100,7 +101,14 @@ const HMRClient: HMRClientNativeInterface = {
},
registerBundle(requestUrl: string) {
invariant(hmrClient, 'Expected HMRClient.setup() call at startup.');
invariant(
hmrOrigin != null && hmrClient != null,
'Expected HMRClient.setup() call at startup.',
);
// only process registerBundle calls from the same origin
if (!requestUrl.startsWith(hmrOrigin)) {
return;
}
pendingEntryPoints.push(requestUrl);
registerBundleEntryPoints(hmrClient);
},
@@ -162,8 +170,10 @@ const HMRClient: HMRClientNativeInterface = {
const serverScheme = scheme;
const client = new MetroHMRClient(`${serverScheme}://${serverHost}/hot`);
const origin = `${serverScheme}://${serverHost}`;
const client = new MetroHMRClient(`${origin}/hot`);
hmrOrigin = origin;
hmrClient = client;
const {fullBundleUrl} = getDevServer();