diff --git a/Libraries/Utilities/HMRClient.js b/Libraries/Utilities/HMRClient.js index daae39571d174f..2574897a578732 100644 --- a/Libraries/Utilities/HMRClient.js +++ b/Libraries/Utilities/HMRClient.js @@ -18,12 +18,15 @@ import NativeRedBox from '../NativeModules/specs/NativeRedBox'; import type {ExtendedError} from '../Core/Devtools/parseErrorStack'; +const pendingEntryPoints = []; let hmrClient = null; let hmrUnavailableReason: string | null = null; +let isRegisteringEntryPoints = false; export type HMRClientNativeInterface = {| enable(): void, disable(): void, + registerBundle(requestUrl: string): void, setup( platform: string, bundleEntry: string, @@ -70,6 +73,8 @@ const HMRClient: HMRClientNativeInterface = { // Don't warn about the same modules twice. hmrClient.outdatedModules.clear(); } + + registerBundleEntryPoints(hmrClient); }, disable() { @@ -81,6 +86,12 @@ const HMRClient: HMRClientNativeInterface = { hmrClient.shouldApplyUpdates = false; }, + registerBundle(requestUrl: string) { + invariant(hmrClient, 'Expected HMRClient.setup() call at startup.'); + pendingEntryPoints.push(requestUrl); + registerBundleEntryPoints(hmrClient); + }, + // Called once by the bridge on startup, even if Fast Refresh is off. // It creates the HMR client but doesn't actually set up the socket yet. setup( @@ -99,10 +110,12 @@ const HMRClient: HMRClientNativeInterface = { const HMRLoadingView = require('./HMRLoadingView'); const wsHost = port !== null && port !== '' ? `${host}:${port}` : host; - const client = new MetroHMRClient( + const client = new MetroHMRClient(`ws://${wsHost}/hot`); + hmrClient = client; + + pendingEntryPoints.push( `ws://${wsHost}/hot?bundleEntry=${bundleEntry}&platform=${platform}`, ); - hmrClient = client; client.on('connection-error', e => { let error = `Fast Refresh isn't working because it cannot connect to the development server. @@ -129,22 +142,18 @@ Error: ${e.message}`; setHMRUnavailableReason(error); }); - let didFinishInitialUpdate = false; - client.on('connection-done', () => { - // Don't show the loading view during the initial update. - didFinishInitialUpdate = true; - }); - // This is intentionally called lazily, as these values change. function isFastRefreshActive() { return ( - // Until we get "connection-done", messages aren't real edits. - didFinishInitialUpdate && // If HMR is disabled by the user, we're ignoring updates. - client.shouldApplyUpdates + client.shouldApplyUpdates && !isRegisteringEntryPoints ); } + client.on('bundle-registered', () => { + isRegisteringEntryPoints = false; + }); + function dismissRedbox() { if ( Platform.OS === 'ios' && @@ -257,4 +266,17 @@ function getShortModuleName(fullName) { return shortName; } +function registerBundleEntryPoints(client) { + if (pendingEntryPoints.length > 0) { + isRegisteringEntryPoints = true; + client.send( + JSON.stringify({ + type: 'register-entrypoints', + entryPoints: pendingEntryPoints, + }), + ); + pendingEntryPoints.length = 0; + } +} + module.exports = HMRClient; diff --git a/Libraries/Utilities/HMRClientProdShim.js b/Libraries/Utilities/HMRClientProdShim.js index b802fe8f9d4221..1ad8d433f85c26 100644 --- a/Libraries/Utilities/HMRClientProdShim.js +++ b/Libraries/Utilities/HMRClientProdShim.js @@ -22,6 +22,7 @@ const HMRClientProdShim: HMRClientNativeInterface = { ); }, disable() {}, + registerBundle() {}, }; module.exports = HMRClientProdShim;