Skip to content

Commit b986a51

Browse files
committed
Apply HMR updates via node worker thread
1 parent e3a2b72 commit b986a51

File tree

4 files changed

+193
-134
lines changed

4 files changed

+193
-134
lines changed

packages/reporters/dev-server/src/HMRServer.js

+7-8
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,16 @@ export default class HMRServer {
160160
this.broadcast(this.unresolvedError);
161161
}
162162

163-
async emitUpdate(event: {
163+
async getUpdate(event: {
164164
+bundleGraph: BundleGraph<PackagedBundle> | BundleGraph<NamedBundle>,
165165
+changedAssets: Map<string, Asset>,
166166
...
167-
}) {
167+
}): Promise<?HMRMessage> {
168168
this.unresolvedError = null;
169169
this.bundleGraph = event.bundleGraph;
170170

171171
let changedAssets = new Set(event.changedAssets.values());
172-
if (changedAssets.size === 0) return;
172+
if (changedAssets.size === 0) return Promise.resolve(null);
173173

174174
let queue = new PromiseQueue({maxConcurrent: FS_CONCURRENCY});
175175
for (let asset of changedAssets) {
@@ -227,15 +227,14 @@ export default class HMRServer {
227227
}
228228

229229
let assets = await queue.run();
230-
231230
if (assets.length >= BROADCAST_MAX_ASSETS) {
232231
// Too many assets to send via an update without errors, just reload instead
233-
this.broadcast({type: 'reload'});
234-
} else {
235-
this.broadcast({
232+
return {type: 'reload'};
233+
} else if (assets.length > 0) {
234+
return {
236235
type: 'update',
237236
assets,
238-
});
237+
};
239238
}
240239
}
241240

packages/reporters/dev-server/src/NodeRunner.js

+32-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {md, errorToDiagnostic} from '@parcel/diagnostic';
55
import nullthrows from 'nullthrows';
66
import {Worker} from 'worker_threads';
77
import path from 'path';
8+
import type {HMRMessage} from './HMRServer';
89

910
export type NodeRunnerOptions = {|
1011
hmr: boolean,
@@ -37,7 +38,7 @@ export class NodeRunner {
3738
}
3839
}
3940

40-
startWorker() {
41+
startWorker(): Promise<void> {
4142
let entry = nullthrows(this.bundleGraph)
4243
.getEntryBundles()
4344
.find(b => b.env.isNode() && b.type === 'js');
@@ -54,12 +55,6 @@ export class NodeRunner {
5455
stderr: true,
5556
});
5657

57-
worker.on('message', msg => {
58-
if (msg === 'restart') {
59-
this.restartWorker();
60-
}
61-
});
62-
6358
worker.on('error', (err: Error) => {
6459
this.logger.error(errorToDiagnostic(err));
6560
});
@@ -91,6 +86,12 @@ export class NodeRunner {
9186
});
9287

9388
this.worker = worker;
89+
90+
return new Promise(resolve => {
91+
worker.once('online', () => resolve());
92+
});
93+
} else {
94+
return Promise.resolve();
9495
}
9596
}
9697

@@ -105,7 +106,30 @@ export class NodeRunner {
105106
// HMR updates are sent before packaging is complete.
106107
// If the build is still pending, wait until it completes to restart.
107108
if (!this.pending) {
108-
this.startWorker();
109+
await this.startWorker();
109110
}
110111
}
112+
113+
emitUpdate(update: HMRMessage): Promise<void> {
114+
if (update.type === 'reload') {
115+
return this.restartWorker();
116+
}
117+
118+
return new Promise((resolve, reject) => {
119+
let worker = this.worker;
120+
if (worker) {
121+
worker.once('message', msg => {
122+
if (msg === 'restart') {
123+
this.restartWorker().then(resolve, reject);
124+
} else {
125+
resolve();
126+
}
127+
});
128+
129+
worker.postMessage(update);
130+
} else {
131+
resolve();
132+
}
133+
});
134+
}
111135
}

packages/reporters/dev-server/src/ServerReporter.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,15 @@ export default (new Reporter({
116116
// no stale bundles are served. Otherwise emit it for 'buildSuccess'.
117117
options.serveOptions !== false
118118
) {
119-
await hmrServer.emitUpdate(event);
119+
let update = await hmrServer.getUpdate(event);
120+
if (update) {
121+
// If running in node, wait for the server to update before emitting the update
122+
// on the client. This ensures that when the client reloads the server is ready.
123+
if (nodeRunner) {
124+
await nodeRunner.emitUpdate(update);
125+
}
126+
hmrServer.broadcast(update);
127+
}
120128
}
121129
break;
122130
case 'buildSuccess': {
@@ -131,7 +139,10 @@ export default (new Reporter({
131139
server.buildSuccess(event.bundleGraph, event.requestBundle);
132140
}
133141
if (hmrServer && options.serveOptions === false) {
134-
await hmrServer.emitUpdate(event);
142+
let update = await hmrServer.getUpdate(event);
143+
if (update) {
144+
hmrServer.broadcast(update);
145+
}
135146
}
136147

137148
if (!nodeRunner && options.serveOptions) {

0 commit comments

Comments
 (0)