Skip to content

Commit f90e6ab

Browse files
authored
BUG: Handle large webpack stats bundles without socket.io client disconnect. (#281)
- Limits the webpack stats messaged object to just errors and warnings. Fixes #279 - Add client disconnect / error messages to help analogous issues in the future.
1 parent db6d14b commit f90e6ab

File tree

5 files changed

+69
-30
lines changed

5 files changed

+69
-30
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ yarn-error.log
1010
package-lock.json
1111
dist-*
1212
.vscode
13+
.lankrc.js

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
# Change Log
22

3-
This project adheres to [Semantic Versioning](http://semver.org/).
3+
This project adheres to [Semantic Versioning](http://semver.org/).
44
Every release, along with the migration instructions, is documented on the Github [Releases](https://github.com/FormidableLabs/webpack-dashboard/releases) page.
55

6+
## UNRELEASED
7+
8+
### Bugs
9+
10+
- **Socket.io disconnects / large stats object size**: Dramatically reduce the size of the webpack stats object being sent from client (webpack plugin) to server (CLI). Add client error/disconnect information for better future debugging. Original issue: https://github.com/FormidableLabs/inspectpack/issues/279 and fix: https://github.com/FormidableLabs/inspectpack/pull/281
11+
612
## [3.0.2] - 2019-03-28
713

814
### Features

bin/webpack-dashboard.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ const main = (module.exports = opts => {
6565
server.on("connection", socket => {
6666
socket.emit("mode", { minimal: program.minimal || false });
6767

68-
socket.on("message", message => {
68+
socket.on("message", (message, ack) => {
6969
if (message.type !== "log") {
70-
dashboard.setData(message);
70+
dashboard.setData(message, ack);
7171
}
7272
});
7373
});
@@ -95,8 +95,8 @@ const main = (module.exports = opts => {
9595
});
9696
} else {
9797
server.on("connection", socket => {
98-
socket.on("message", message => {
99-
dashboard.setData(message);
98+
socket.on("message", (message, ack) => {
99+
dashboard.setData(message, ack);
100100
});
101101
});
102102
}

dashboard/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class Dashboard {
9191
this.screen.render();
9292
}
9393

94-
setData(dataArray) {
94+
setData(dataArray, ack) {
9595
dataArray
9696
.map(data =>
9797
data.error
@@ -105,6 +105,11 @@ class Dashboard {
105105
});
106106

107107
this.screen.render();
108+
109+
// Send ack back if requested.
110+
if (ack) {
111+
ack();
112+
}
108113
}
109114

110115
setProgress(data) {

plugin/index.js

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class DashboardPlugin {
7272

7373
apply(compiler) {
7474
let handler = this.handler;
75+
let reachedSuccess = false;
7576
let timer;
7677

7778
if (!handler) {
@@ -85,6 +86,16 @@ class DashboardPlugin {
8586
this.socket.once("mode", args => {
8687
this.minimal = args.minimal;
8788
});
89+
this.socket.on("error", err => {
90+
// eslint-disable-next-line no-console
91+
console.log(err);
92+
});
93+
this.socket.on("disconnect", () => {
94+
if (!reachedSuccess) {
95+
// eslint-disable-next-line no-console
96+
console.log("Socket.io disconnected before completing build lifecycle.");
97+
}
98+
});
8899
}
89100

90101
new webpack.ProgressPlugin((percent, msg) => {
@@ -162,32 +173,47 @@ class DashboardPlugin {
162173
const statsOptions = (options.devServer && options.devServer.stats) ||
163174
options.stats || { colors: true };
164175

165-
handler([
166-
{
167-
type: "status",
168-
value: "Success"
169-
},
170-
{
171-
type: "progress",
172-
value: 1
173-
},
174-
{
175-
type: "operations",
176-
value: `idle${getTimeMessage(timer)}`
177-
},
178-
{
179-
type: "stats",
180-
value: {
181-
errors: stats.hasErrors(),
182-
warnings: stats.hasWarnings(),
183-
data: stats.toJson()
176+
// We only need errors/warnings for stats information for finishing up.
177+
// This allows us to avoid sending a full stats object to the CLI which
178+
// can cause socket.io client disconnects for large objects.
179+
// See: https://github.com/FormidableLabs/webpack-dashboard/issues/279
180+
const statsJsonOptions = {
181+
all: false,
182+
errors: true,
183+
warnings: true
184+
};
185+
186+
handler(
187+
[
188+
{
189+
type: "status",
190+
value: "Success"
191+
},
192+
{
193+
type: "progress",
194+
value: 1
195+
},
196+
{
197+
type: "operations",
198+
value: `idle${getTimeMessage(timer)}`
199+
},
200+
{
201+
type: "stats",
202+
value: {
203+
errors: stats.hasErrors(),
204+
warnings: stats.hasWarnings(),
205+
data: stats.toJson(statsJsonOptions)
206+
}
207+
},
208+
{
209+
type: "log",
210+
value: stats.toString(statsOptions)
184211
}
185-
},
186-
{
187-
type: "log",
188-
value: stats.toString(statsOptions)
212+
],
213+
() => {
214+
reachedSuccess = true;
189215
}
190-
]);
216+
);
191217

192218
if (!this.minimal) {
193219
this.observeMetrics(stats).subscribe({
@@ -203,6 +229,7 @@ class DashboardPlugin {
203229
}
204230

205231
observeMetrics(statsObj) {
232+
// Get the **full** stats object here for `inspectpack` analysis.
206233
const statsToObserve = statsObj.toJson();
207234

208235
const getSizes = stats =>

0 commit comments

Comments
 (0)