Skip to content

Commit 190b4ba

Browse files
Merge branch 'master' into docs/open-target
2 parents 7ff1c46 + 67aaaf7 commit 190b4ba

24 files changed

+905
-668
lines changed

lib/Server.js

Lines changed: 145 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ const killable = require('killable');
1010
const express = require('express');
1111
const { validate } = require('schema-utils');
1212
const normalizeOptions = require('./utils/normalizeOptions');
13-
const colors = require('./utils/colors');
14-
const routes = require('./utils/routes');
15-
const getSocketServerImplementation = require('./utils/getSocketServerImplementation');
1613
const getCompilerConfigArray = require('./utils/getCompilerConfigArray');
17-
const getStatsOption = require('./utils/getStatsOption');
1814
const schema = require('./options.json');
1915

2016
if (!process.env.WEBPACK_SERVE) {
@@ -49,10 +45,6 @@ class Server {
4945
initialize() {
5046
this.applyDevServerPlugin();
5147

52-
this.webSocketServerImplementation = getSocketServerImplementation(
53-
this.options
54-
);
55-
5648
if (this.options.client.progress) {
5749
this.setupProgressPlugin();
5850
}
@@ -61,10 +53,8 @@ class Server {
6153
this.setupApp();
6254
this.setupHostHeaderCheck();
6355
this.setupDevMiddleware();
64-
6556
// Should be after `webpack-dev-middleware`, otherwise other middlewares might rewrite response
66-
routes(this);
67-
57+
this.setupBuiltInRoutes();
6858
this.setupWatchFiles();
6959
this.setupFeatures();
7060
this.createServer();
@@ -262,6 +252,71 @@ class Server {
262252
);
263253
}
264254

255+
setupBuiltInRoutes() {
256+
const { app, middleware } = this;
257+
258+
app.get('/__webpack_dev_server__/sockjs.bundle.js', (req, res) => {
259+
res.setHeader('Content-Type', 'application/javascript');
260+
261+
const { createReadStream } = require('graceful-fs');
262+
const clientPath = path.join(__dirname, '..', 'client');
263+
264+
createReadStream(
265+
path.join(clientPath, 'modules/sockjs-client/index.js')
266+
).pipe(res);
267+
});
268+
269+
app.get('/webpack-dev-server/invalidate', (_req, res) => {
270+
this.invalidate();
271+
272+
res.end();
273+
});
274+
275+
app.get('/webpack-dev-server', (req, res) => {
276+
middleware.waitUntilValid((stats) => {
277+
res.setHeader('Content-Type', 'text/html');
278+
res.write(
279+
'<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>'
280+
);
281+
282+
const statsForPrint =
283+
typeof stats.stats !== 'undefined'
284+
? stats.toJson().children
285+
: [stats.toJson()];
286+
287+
res.write(`<h1>Assets Report:</h1>`);
288+
289+
statsForPrint.forEach((item, index) => {
290+
res.write('<div>');
291+
292+
const name =
293+
item.name || (stats.stats ? `unnamed[${index}]` : 'unnamed');
294+
295+
res.write(`<h2>Compilation: ${name}</h2>`);
296+
res.write('<ul>');
297+
298+
const publicPath = item.publicPath === 'auto' ? '' : item.publicPath;
299+
300+
for (const asset of item.assets) {
301+
const assetName = asset.name;
302+
const assetURL = `${publicPath}${assetName}`;
303+
304+
res.write(
305+
`<li>
306+
<strong><a href="${assetURL}" target="_blank">${assetName}</a></strong>
307+
</li>`
308+
);
309+
}
310+
311+
res.write('</ul>');
312+
res.write('</div>');
313+
});
314+
315+
res.end('</body></html>');
316+
});
317+
});
318+
}
319+
265320
setupCompressFeature() {
266321
const compress = require('compression');
267322

@@ -574,7 +629,47 @@ class Server {
574629
});
575630
}
576631

632+
getWebSocketServerImplementation() {
633+
let implementation;
634+
let implementationFound = true;
635+
636+
switch (typeof this.options.webSocketServer.type) {
637+
case 'string':
638+
// Could be 'sockjs', in the future 'ws', or a path that should be required
639+
if (this.options.webSocketServer.type === 'sockjs') {
640+
implementation = require('./servers/SockJSServer');
641+
} else if (this.options.webSocketServer.type === 'ws') {
642+
implementation = require('./servers/WebsocketServer');
643+
} else {
644+
try {
645+
// eslint-disable-next-line import/no-dynamic-require
646+
implementation = require(this.options.webSocketServer.type);
647+
} catch (error) {
648+
implementationFound = false;
649+
}
650+
}
651+
break;
652+
case 'function':
653+
implementation = this.options.webSocketServer.type;
654+
break;
655+
default:
656+
implementationFound = false;
657+
}
658+
659+
if (!implementationFound) {
660+
throw new Error(
661+
"webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws', 'sockjs'), a full path to " +
662+
'a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js) ' +
663+
'via require.resolve(...), or the class itself which extends BaseServer'
664+
);
665+
}
666+
667+
return implementation;
668+
}
669+
577670
createWebSocketServer() {
671+
this.webSocketServerImplementation =
672+
this.getWebSocketServerImplementation();
578673
// eslint-disable-next-line new-cap
579674
this.webSocketServer = new this.webSocketServerImplementation(this);
580675

@@ -697,7 +792,7 @@ class Server {
697792

698793
logStatus() {
699794
const getColorsOption = (configArray) => {
700-
const statsOption = getStatsOption(configArray);
795+
const statsOption = this.getStatsOption(configArray);
701796

702797
let colorsEnabled = false;
703798

@@ -708,6 +803,25 @@ class Server {
708803
return colorsEnabled;
709804
};
710805

806+
// TODO change it on https://www.npmjs.com/package/colorette
807+
const colors = {
808+
info(useColor, msg) {
809+
if (useColor) {
810+
// Make text blue and bold, so it *pops*
811+
return `\u001b[1m\u001b[34m${msg}\u001b[39m\u001b[22m`;
812+
}
813+
814+
return msg;
815+
},
816+
error(useColor, msg) {
817+
if (useColor) {
818+
// Make text red and bold, so it *pops*
819+
return `\u001b[1m\u001b[31m${msg}\u001b[39m\u001b[22m`;
820+
}
821+
822+
return msg;
823+
},
824+
};
711825
const useColor = getColorsOption(getCompilerConfigArray(this.compiler));
712826

713827
if (this.options.ipc) {
@@ -979,11 +1093,28 @@ class Server {
9791093
}
9801094
}
9811095

1096+
// eslint-disable-next-line class-methods-use-this
1097+
getStatsOption(configArray) {
1098+
const isEmptyObject = (val) =>
1099+
typeof val === 'object' && Object.keys(val).length === 0;
1100+
1101+
// in webpack@4 stats will not be defined if not provided,
1102+
// but in webpack@5 it will be an empty object
1103+
const statsConfig = configArray.find(
1104+
(configuration) =>
1105+
typeof configuration === 'object' &&
1106+
configuration.stats &&
1107+
!isEmptyObject(configuration.stats)
1108+
);
1109+
1110+
return statsConfig ? statsConfig.stats : {};
1111+
}
1112+
9821113
getStats(statsObj) {
9831114
const stats = Server.DEFAULT_STATS;
9841115

985-
const configArr = getCompilerConfigArray(this.compiler);
986-
const statsOption = getStatsOption(configArr);
1116+
const configArray = getCompilerConfigArray(this.compiler);
1117+
const statsOption = this.getStatsOption(configArray);
9871118

9881119
if (typeof statsOption === 'object' && statsOption.warningsFilter) {
9891120
stats.warningsFilter = statsOption.warningsFilter;

lib/utils/colors.js

Lines changed: 0 additions & 22 deletions
This file was deleted.

lib/utils/findPort.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

lib/utils/getSocketServerImplementation.js

Lines changed: 0 additions & 42 deletions
This file was deleted.

lib/utils/getStatsOption.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

lib/utils/routes.js

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)