Skip to content

Commit 93bebf1

Browse files
cpojerfacebook-github-bot
authored andcommitted
Switch HMR connection to register bundle entry points via a message
Summary: This diff builds on the previous ones and changes the setup process from using the WebSocket URL to using a message that is sent after the connection is established. It also exposes a function on the HMRClient that allows registering more bundles, which I will make use of in the next (and hopefully final :D ) diff. I was initially planning on using structured data, like `{bundleName, platform}` but decided to keep using URLs as that is the format used throughout Metro. In fact, when we parse the options from the URL, we need to re-encode the input URL to create the `sourceMapUrl`. I thought it doesn't make sense to write more code to send structured data over the connection only to re-construct a URL on the server manually. Finally, I also slightly modified the "Internal Bundler" error that is shown in a RedBox (now used by the websocket connection if an invalid message is received). I removed the "internal" wording from the message and I'm actually attaching the failure message to the error instead of directing users to the Terminal. Reviewed By: gaearon Differential Revision: D16162729 fbshipit-source-id: 977fde5f6c2f1c14efb4fd99ed30a6bf95a3b13e
1 parent c8ec2ae commit 93bebf1

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

Libraries/Utilities/HMRClient.js

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ import NativeRedBox from '../NativeModules/specs/NativeRedBox';
1818

1919
import type {ExtendedError} from '../Core/Devtools/parseErrorStack';
2020

21+
const pendingEntryPoints = [];
2122
let hmrClient = null;
2223
let hmrUnavailableReason: string | null = null;
24+
let isRegisteringEntryPoints = false;
2325

2426
export type HMRClientNativeInterface = {|
2527
enable(): void,
2628
disable(): void,
29+
registerBundle(requestUrl: string): void,
2730
setup(
2831
platform: string,
2932
bundleEntry: string,
@@ -70,6 +73,8 @@ const HMRClient: HMRClientNativeInterface = {
7073
// Don't warn about the same modules twice.
7174
hmrClient.outdatedModules.clear();
7275
}
76+
77+
registerBundleEntryPoints(hmrClient);
7378
},
7479

7580
disable() {
@@ -81,6 +86,12 @@ const HMRClient: HMRClientNativeInterface = {
8186
hmrClient.shouldApplyUpdates = false;
8287
},
8388

89+
registerBundle(requestUrl: string) {
90+
invariant(hmrClient, 'Expected HMRClient.setup() call at startup.');
91+
pendingEntryPoints.push(requestUrl);
92+
registerBundleEntryPoints(hmrClient);
93+
},
94+
8495
// Called once by the bridge on startup, even if Fast Refresh is off.
8596
// It creates the HMR client but doesn't actually set up the socket yet.
8697
setup(
@@ -99,10 +110,12 @@ const HMRClient: HMRClientNativeInterface = {
99110
const HMRLoadingView = require('./HMRLoadingView');
100111

101112
const wsHost = port !== null && port !== '' ? `${host}:${port}` : host;
102-
const client = new MetroHMRClient(
113+
const client = new MetroHMRClient(`ws://${wsHost}/hot`);
114+
hmrClient = client;
115+
116+
pendingEntryPoints.push(
103117
`ws://${wsHost}/hot?bundleEntry=${bundleEntry}&platform=${platform}`,
104118
);
105-
hmrClient = client;
106119

107120
client.on('connection-error', e => {
108121
let error = `Fast Refresh isn't working because it cannot connect to the development server.
@@ -129,22 +142,18 @@ Error: ${e.message}`;
129142
setHMRUnavailableReason(error);
130143
});
131144

132-
let didFinishInitialUpdate = false;
133-
client.on('connection-done', () => {
134-
// Don't show the loading view during the initial update.
135-
didFinishInitialUpdate = true;
136-
});
137-
138145
// This is intentionally called lazily, as these values change.
139146
function isFastRefreshActive() {
140147
return (
141-
// Until we get "connection-done", messages aren't real edits.
142-
didFinishInitialUpdate &&
143148
// If HMR is disabled by the user, we're ignoring updates.
144-
client.shouldApplyUpdates
149+
client.shouldApplyUpdates && !isRegisteringEntryPoints
145150
);
146151
}
147152

153+
client.on('bundle-registered', () => {
154+
isRegisteringEntryPoints = false;
155+
});
156+
148157
function dismissRedbox() {
149158
if (
150159
Platform.OS === 'ios' &&
@@ -257,4 +266,17 @@ function getShortModuleName(fullName) {
257266
return shortName;
258267
}
259268

269+
function registerBundleEntryPoints(client) {
270+
if (pendingEntryPoints.length > 0) {
271+
isRegisteringEntryPoints = true;
272+
client.send(
273+
JSON.stringify({
274+
type: 'register-entrypoints',
275+
entryPoints: pendingEntryPoints,
276+
}),
277+
);
278+
pendingEntryPoints.length = 0;
279+
}
280+
}
281+
260282
module.exports = HMRClient;

Libraries/Utilities/HMRClientProdShim.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const HMRClientProdShim: HMRClientNativeInterface = {
2222
);
2323
},
2424
disable() {},
25+
registerBundle() {},
2526
};
2627

2728
module.exports = HMRClientProdShim;

0 commit comments

Comments
 (0)