Skip to content

Commit

Permalink
feat: allow to disable web socket server
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Jul 19, 2021
1 parent 4a48ae6 commit f62f20f
Show file tree
Hide file tree
Showing 17 changed files with 153 additions and 87 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -159,6 +159,7 @@ Options:
--watch-files-reset Clear all items provided in 'watchFiles' configuration. Allows to configure list of globs/directories/files
to watch for file changes.
--web-socket-server <value> Allows to set web socket server and options (by default 'ws').
--no-web-socket-server Negative 'web-socket-server' option.
Global options:
--color Enable colors on console.
Expand Down
2 changes: 1 addition & 1 deletion bin/cli-flags.js
Expand Up @@ -298,7 +298,7 @@ module.exports = {
configs: [
{
type: 'enum',
values: ['sockjs', 'ws'],
values: [false, 'sockjs', 'ws'],
multiple: false,
description:
"Allows to set web socket server and options (by default 'ws').",
Expand Down
16 changes: 9 additions & 7 deletions lib/Server.js
Expand Up @@ -671,11 +671,7 @@ class Server {
}

createWebSocketServer() {
this.webSocketServerImplementation =
this.getWebSocketServerImplementation();
// eslint-disable-next-line new-cap
this.webSocketServer = new this.webSocketServerImplementation(this);

this.webSocketServer = new (this.getWebSocketServerImplementation())(this);
this.webSocketServer.implementation.on('connection', (client, request) => {
const headers =
// eslint-disable-next-line no-nested-ternary
Expand Down Expand Up @@ -1037,8 +1033,14 @@ class Server {
fs.chmodSync(this.options.ipc, READ_WRITE);
}

if (Boolean(this.options.hot) || this.options.liveReload) {
this.createWebSocketServer();
if (this.options.webSocketServer) {
try {
this.createWebSocketServer();
} catch (webSocketServerError) {
fn.call(this.server, webSocketServerError);

return;
}
}

if (this.options.bonjour) {
Expand Down
2 changes: 1 addition & 1 deletion lib/options.json
Expand Up @@ -635,7 +635,7 @@
"link": "https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver"
},
"WebSocketServerEnum": {
"enum": ["sockjs", "ws"]
"enum": [false, "sockjs", "ws"]
},
"WebSocketServerFunction": {
"instanceof": "Function"
Expand Down
14 changes: 8 additions & 6 deletions lib/utils/DevServerPlugin.js
Expand Up @@ -18,6 +18,7 @@ class DevServerPlugin {
let clientImplementationFound = true;

const isKnownWebSocketServerImplementation =
this.options.webSocketServer &&
typeof this.options.webSocketServer.type === 'string' &&
(this.options.webSocketServer.type === 'ws' ||
this.options.webSocketServer.type === 'sockjs');
Expand All @@ -29,6 +30,8 @@ class DevServerPlugin {
clientTransport = this.options.client.webSocketTransport;
} else if (isKnownWebSocketServerImplementation) {
clientTransport = this.options.webSocketServer.type;
} else {
clientTransport = 'ws';
}
} else {
clientTransport = 'ws';
Expand Down Expand Up @@ -186,8 +189,10 @@ class DevServerPlugin {
* @returns {string}
*/
getClientEntry() {
const webSocketURL = this.getWebSocketURL();
/** @type {string} */
const webSocketURL = this.options.webSocketServer
? this.getWebSocketURL()
: '';

return `${require.resolve('../../client/index.js')}?${webSocketURL}`;
}
Expand Down Expand Up @@ -243,11 +248,8 @@ class DevServerPlugin {

const additionalEntries = [];

if (
this.options.client &&
this.isWebTarget(compiler.options) &&
(Boolean(this.options.hot) || this.options.liveReload)
) {
// TODO maybe empty empty client
if (this.options.client && this.isWebTarget(compiler.options)) {
const clientEntry = this.getClientEntry();

additionalEntries.push(clientEntry);
Expand Down
5 changes: 5 additions & 0 deletions lib/utils/normalizeOptions.js
Expand Up @@ -409,6 +409,11 @@ function normalizeOptions(compiler, options, logger, cacheDir) {
type: defaultWebSocketServerType,
options: defaultWebSocketServerOptions,
};
} else if (
typeof options.webSocketServer === 'boolean' &&
!options.webSocketServer
) {
options.webSocketServer = false;
} else if (
typeof options.webSocketServer === 'string' ||
typeof options.webSocketServer === 'function'
Expand Down
18 changes: 9 additions & 9 deletions test/__snapshots__/validate-options.test.js.snap.webpack4
Expand Up @@ -666,43 +666,43 @@ exports[`options validate should throw an error on the "webSocketServer" option
exports[`options validate should throw an error on the "webSocketServer" option with '{"type":true}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
-> Allows to set web socket server and options (by default 'ws').
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver
Details:
* options.webSocketServer.type should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function
Details:
* options.webSocketServer.type should be one of these:
\\"sockjs\\" | \\"ws\\"
false | \\"sockjs\\" | \\"ws\\"
* options.webSocketServer.type should be a non-empty string.
* options.webSocketServer.type should be an instance of function."
`;

exports[`options validate should throw an error on the "webSocketServer" option with 'false' value 1`] = `
exports[`options validate should throw an error on the "webSocketServer" option with 'null' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
-> Allows to set web socket server and options (by default 'ws').
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver
Details:
* options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\"
false | \\"sockjs\\" | \\"ws\\"
* options.webSocketServer should be a non-empty string.
* options.webSocketServer should be an instance of function.
* options.webSocketServer should be an object:
object { type?, options? }"
`;

exports[`options validate should throw an error on the "webSocketServer" option with 'null' value 1`] = `
exports[`options validate should throw an error on the "webSocketServer" option with 'true' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
-> Allows to set web socket server and options (by default 'ws').
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver
Details:
* options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\"
false | \\"sockjs\\" | \\"ws\\"
* options.webSocketServer should be a non-empty string.
* options.webSocketServer should be an instance of function.
* options.webSocketServer should be an object:
Expand Down
18 changes: 9 additions & 9 deletions test/__snapshots__/validate-options.test.js.snap.webpack5
Expand Up @@ -666,43 +666,43 @@ exports[`options validate should throw an error on the "webSocketServer" option
exports[`options validate should throw an error on the "webSocketServer" option with '{"type":true}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
-> Allows to set web socket server and options (by default 'ws').
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver
Details:
* options.webSocketServer.type should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function
Details:
* options.webSocketServer.type should be one of these:
\\"sockjs\\" | \\"ws\\"
false | \\"sockjs\\" | \\"ws\\"
* options.webSocketServer.type should be a non-empty string.
* options.webSocketServer.type should be an instance of function."
`;

exports[`options validate should throw an error on the "webSocketServer" option with 'false' value 1`] = `
exports[`options validate should throw an error on the "webSocketServer" option with 'null' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
-> Allows to set web socket server and options (by default 'ws').
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver
Details:
* options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\"
false | \\"sockjs\\" | \\"ws\\"
* options.webSocketServer should be a non-empty string.
* options.webSocketServer should be an instance of function.
* options.webSocketServer should be an object:
object { type?, options? }"
`;

exports[`options validate should throw an error on the "webSocketServer" option with 'null' value 1`] = `
exports[`options validate should throw an error on the "webSocketServer" option with 'true' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
false | \\"sockjs\\" | \\"ws\\" | non-empty string | function | object { type?, options? }
-> Allows to set web socket server and options (by default 'ws').
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver
Details:
* options.webSocketServer should be one of these:
\\"sockjs\\" | \\"ws\\"
false | \\"sockjs\\" | \\"ws\\"
* options.webSocketServer should be a non-empty string.
* options.webSocketServer should be an instance of function.
* options.webSocketServer should be an object:
Expand Down
1 change: 1 addition & 0 deletions test/cli/__snapshots__/basic.test.js.snap.webpack4
Expand Up @@ -61,6 +61,7 @@ Options:
--client-web-socket-url-username <value> Tells clients connected to devServer to use the provided username to authenticate.
--client-web-socket-url-password <value> Tells clients connected to devServer to use the provided password to authenticate.
--web-socket-server <value> Allows to set web socket server and options (by default 'ws').
--no-web-socket-server Negative 'web-socket-server' option.
--compress Enables gzip compression for everything served.
--no-compress Disables gzip compression for everything served.
--history-api-fallback Allows to proxy requests through a specified index page (by default 'index.html'), useful for Single Page Applications that utilise the HTML5 History API.
Expand Down
1 change: 1 addition & 0 deletions test/cli/__snapshots__/basic.test.js.snap.webpack5
Expand Up @@ -104,6 +104,7 @@ Options:
--watch-files <value...> Allows to configure list of globs/directories/files to watch for file changes.
--watch-files-reset Clear all items provided in 'watchFiles' configuration. Allows to configure list of globs/directories/files to watch for file changes.
--web-socket-server <value> Allows to set web socket server and options (by default 'ws').
--no-web-socket-server Negative 'web-socket-server' option.

Global options:
--color Enable colors on console.
Expand Down
29 changes: 26 additions & 3 deletions test/e2e/__snapshots__/hot-and-live-reload.test.js.snap.webpack4
@@ -1,14 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`hot and live reload should not refresh content when hot and no live reload disabled (default): console messages 1`] = `Array []`;
exports[`hot and live reload should not refresh content when hot and no live reload disabled (default): console messages 1`] = `
Array [
"[webpack-dev-server] App updated. Recompiling...",
]
`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (default): page errors 1`] = `Array []`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (sockjs): console messages 1`] = `Array []`;
exports[`hot and live reload should not refresh content when hot and no live reload disabled (sockjs): console messages 1`] = `
Array [
"[webpack-dev-server] App updated. Recompiling...",
]
`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (sockjs): page errors 1`] = `Array []`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (ws): console messages 1`] = `Array []`;
exports[`hot and live reload should not refresh content when hot and no live reload disabled (ws): console messages 1`] = `
Array [
"[webpack-dev-server] App updated. Recompiling...",
]
`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (ws): page errors 1`] = `Array []`;

Expand Down Expand Up @@ -47,6 +59,17 @@ Array [

exports[`hot and live reload should work and allow to disable live reload using the "webpack-dev-server-live-reload=false" (default): page errors 1`] = `Array []`;

exports[`hot and live reload should work and do nothing when web socket server disabled (default): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"WebSocket connection to 'ws://localhost:8095/ws' failed: Error during WebSocket handshake: Unexpected response code: 404",
"[webpack-dev-server] JSHandle@object",
"[webpack-dev-server] Disconnected!",
]
`;

exports[`hot and live reload should work and do nothing when web socket server disabled (default): page errors 1`] = `Array []`;

exports[`hot and live reload should work and refresh content using hot module replacement (default): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
Expand Down
29 changes: 26 additions & 3 deletions test/e2e/__snapshots__/hot-and-live-reload.test.js.snap.webpack5
@@ -1,14 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`hot and live reload should not refresh content when hot and no live reload disabled (default): console messages 1`] = `Array []`;
exports[`hot and live reload should not refresh content when hot and no live reload disabled (default): console messages 1`] = `
Array [
"[webpack-dev-server] App updated. Recompiling...",
]
`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (default): page errors 1`] = `Array []`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (sockjs): console messages 1`] = `Array []`;
exports[`hot and live reload should not refresh content when hot and no live reload disabled (sockjs): console messages 1`] = `
Array [
"[webpack-dev-server] App updated. Recompiling...",
]
`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (sockjs): page errors 1`] = `Array []`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (ws): console messages 1`] = `Array []`;
exports[`hot and live reload should not refresh content when hot and no live reload disabled (ws): console messages 1`] = `
Array [
"[webpack-dev-server] App updated. Recompiling...",
]
`;

exports[`hot and live reload should not refresh content when hot and no live reload disabled (ws): page errors 1`] = `Array []`;

Expand Down Expand Up @@ -47,6 +59,17 @@ Array [

exports[`hot and live reload should work and allow to disable live reload using the "webpack-dev-server-live-reload=false" (default): page errors 1`] = `Array []`;

exports[`hot and live reload should work and do nothing when web socket server disabled (default): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"WebSocket connection to 'ws://localhost:8095/ws' failed: Error during WebSocket handshake: Unexpected response code: 404",
"[webpack-dev-server] JSHandle@object",
"[webpack-dev-server] Disconnected!",
]
`;

exports[`hot and live reload should work and do nothing when web socket server disabled (default): page errors 1`] = `Array []`;

exports[`hot and live reload should work and refresh content using hot module replacement (default): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
Expand Down
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`web socket server and transport should throw an error on wrong path 1`] = `"When you use custom web socket implementation you must explicitly specify client.webSocketTransport. client.webSocketTransport must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to a JS file via require.resolve(...) which exports a class "`;
exports[`web socket server and transport should throw an error on wrong path 1`] = `"webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws', 'sockjs'), a full path to a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js) via require.resolve(...), or the class itself which extends BaseServer"`;

exports[`web socket server and transport should use "sockjs" transport and "sockjs" web socket server 1`] = `
Array [
Expand Down
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`web socket server and transport should throw an error on wrong path 1`] = `"When you use custom web socket implementation you must explicitly specify client.webSocketTransport. client.webSocketTransport must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to a JS file via require.resolve(...) which exports a class "`;
exports[`web socket server and transport should throw an error on wrong path 1`] = `"webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws', 'sockjs'), a full path to a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js) via require.resolve(...), or the class itself which extends BaseServer"`;

exports[`web socket server and transport should use "sockjs" transport and "sockjs" web socket server 1`] = `
Array [
Expand Down

0 comments on commit f62f20f

Please sign in to comment.