Skip to content

Commit

Permalink
feat: added client.reconnect option (#3912)
Browse files Browse the repository at this point in the history
  • Loading branch information
snitin315 committed Oct 9, 2021
1 parent 7298114 commit 5edad76
Show file tree
Hide file tree
Showing 27 changed files with 543 additions and 23 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -93,6 +93,8 @@ Options:
--client-logging <value> Allows to specify options for client script in the browser or disable client script.
--client-progress Prints compilation progress in percentage in the browser.
--no-client-progress Does not print compilation progress in percentage in the browser.
--client-reconnect [value] Tells dev-server the number of times it should try to reconnect the client.
--no-client-reconnect Tells dev-server to not to try to connect the client.
--client-overlay Enables a full-screen overlay in the browser when there are compiler errors or warnings.
--no-client-overlay Disables a full-screen overlay in the browser when there are compiler errors or warnings.
--client-overlay-errors Enables a full-screen overlay in the browser when there are compiler errors.
Expand Down
23 changes: 23 additions & 0 deletions bin/cli-flags.js
Expand Up @@ -174,6 +174,29 @@ module.exports = {
simpleType: "boolean",
multiple: false,
},
"client-reconnect": {
configs: [
{
type: "boolean",
multiple: false,
description:
"Tells dev-server the number of times it should try to reconnect the client.",
path: "client.reconnect",
},
{
type: "number",
multiple: false,
description:
"Tells dev-server the number of times it should try to reconnect the client.",
path: "client.reconnect",
},
],
description:
"Tells dev-server the number of times it should try to reconnect the client.",
negatedDescription: "Tells dev-server to not to try to connect the client.",
simpleType: "string",
multiple: false,
},
"client-web-socket-url": {
configs: [
{
Expand Down
13 changes: 12 additions & 1 deletion client-src/index.js
Expand Up @@ -41,6 +41,10 @@ if (parsedResourceQuery.logging) {
options.logging = parsedResourceQuery.logging;
}

if (typeof parsedResourceQuery.reconnect !== "undefined") {
options.reconnect = Number(parsedResourceQuery.reconnect);
}

function setAllLogLevel(level) {
// This is needed because the HMR logger operate separately from dev server logger
webpackHotLog.setLogLevel(
Expand Down Expand Up @@ -98,6 +102,13 @@ const onSocketMessage = {

options.overlay = value;
},
reconnect(value) {
if (parsedResourceQuery.reconnect === "false") {
return;
}

options.reconnect = value;
},
progress(progress) {
options.progress = progress;
},
Expand Down Expand Up @@ -215,4 +226,4 @@ const onSocketMessage = {

const socketURL = createSocketURL(parsedResourceQuery);

socket(socketURL, onSocketMessage);
socket(socketURL, onSocketMessage, options.reconnect);
9 changes: 7 additions & 2 deletions client-src/socket.js
@@ -1,6 +1,7 @@
/* global __webpack_dev_server_client__ */

import WebSocketClient from "./clients/WebSocketClient.js";
import { log } from "./utils/log.js";

// this WebsocketClient is here as a default fallback, in case the client is not injected
/* eslint-disable camelcase */
Expand All @@ -15,13 +16,15 @@ const Client =
/* eslint-enable camelcase */

let retries = 0;
let maxRetries = 10;
let client = null;

const socket = function initSocket(url, handlers) {
const socket = function initSocket(url, handlers, reconnect) {
client = new Client(url);

client.onOpen(() => {
retries = 0;
maxRetries = reconnect;
});

client.onClose(() => {
Expand All @@ -33,14 +36,16 @@ const socket = function initSocket(url, handlers) {
client = null;

// After 10 retries stop trying, to prevent logspam.
if (retries <= 10) {
if (retries < maxRetries) {
// Exponentially increase timeout to reconnect.
// Respectfully copied from the package `got`.
// eslint-disable-next-line no-mixed-operators, no-restricted-properties
const retryInMs = 1000 * Math.pow(2, retries) + Math.random() * 100;

retries += 1;

log.info("Trying to reconnect...");

setTimeout(() => {
socket(url, handlers);
}, retryInMs);
Expand Down
16 changes: 16 additions & 0 deletions lib/Server.js
Expand Up @@ -258,6 +258,10 @@ class Server {
searchParams.set("logging", this.options.client.logging);
}

if (typeof this.options.client.reconnect !== "undefined") {
searchParams.set("reconnect", this.options.client.reconnect);
}

webSocketURL = searchParams.toString();
}

Expand Down Expand Up @@ -474,6 +478,14 @@ class Server {
};
}

if (typeof options.client.reconnect === "undefined") {
options.client.reconnect = 10;
} else if (options.client.reconnect === true) {
options.client.reconnect = Infinity;
} else if (options.client.reconnect === false) {
options.client.reconnect = 0;
}

// Respect infrastructureLogging.level
if (typeof options.client.logging === "undefined") {
options.client.logging = compilerOptions.infrastructureLogging
Expand Down Expand Up @@ -1627,6 +1639,10 @@ class Server {
this.sendMessage([client], "progress", this.options.client.progress);
}

if (this.options.client && this.options.client.reconnect) {
this.sendMessage([client], "reconnect", this.options.client.reconnect);
}

if (this.options.client && this.options.client.overlay) {
this.sendMessage([client], "overlay", this.options.client.overlay);
}
Expand Down
16 changes: 16 additions & 0 deletions lib/options.json
Expand Up @@ -59,6 +59,9 @@
"progress": {
"$ref": "#/definitions/ClientProgress"
},
"reconnect": {
"$ref": "#/definitions/ClientReconnect"
},
"webSocketTransport": {
"$ref": "#/definitions/ClientWebSocketTransport"
},
Expand Down Expand Up @@ -102,6 +105,19 @@
"link": "https://webpack.js.org/configuration/dev-server/#progress",
"type": "boolean"
},
"ClientReconnect": {
"description": "Tells dev-server the number of times it should try to reconnect the client.",
"link": "https://webpack.js.org/configuration/dev-server/#reconnect",
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"minimum": 0
}
]
},
"ClientWebSocketTransport": {
"anyOf": [
{
Expand Down
30 changes: 23 additions & 7 deletions test/__snapshots__/validate-options.test.js.snap.webpack4
Expand Up @@ -83,7 +83,7 @@ exports[`options validate should throw an error on the "client" option with '{"l
exports[`options validate should throw an error on the "client" option with '{"overlay":""}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand Down Expand Up @@ -122,16 +122,32 @@ exports[`options validate should throw an error on the "client" option with '{"p
-> Read more at https://webpack.js.org/configuration/dev-server/#progress"
`;

exports[`options validate should throw an error on the "client" option with '{"reconnect":""}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
* options.client.reconnect should be one of these:
boolean | number (should be >= 0)
-> Tells dev-server the number of times it should try to reconnect the client.
-> Read more at https://webpack.js.org/configuration/dev-server/#reconnect
Details:
* options.client.reconnect should be a boolean.
* options.client.reconnect should be a number (should be >= 0)."
`;

exports[`options validate should throw an error on the "client" option with '{"unknownOption":true}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client has an unknown property 'unknownOption'. These properties are valid:
object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }"
object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }"
`;

exports[`options validate should throw an error on the "client" option with '{"webSocketTransport":true}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand Down Expand Up @@ -171,7 +187,7 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand All @@ -186,7 +202,7 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"username":123,"password":976}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand All @@ -199,13 +215,13 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
* options.client should be false.
* options.client should be an object:
object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }"
object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }"
`;

exports[`options validate should throw an error on the "compress" option with '' value 1`] = `
Expand Down
30 changes: 23 additions & 7 deletions test/__snapshots__/validate-options.test.js.snap.webpack5
Expand Up @@ -83,7 +83,7 @@ exports[`options validate should throw an error on the "client" option with '{"l
exports[`options validate should throw an error on the "client" option with '{"overlay":""}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand Down Expand Up @@ -122,16 +122,32 @@ exports[`options validate should throw an error on the "client" option with '{"p
-> Read more at https://webpack.js.org/configuration/dev-server/#progress"
`;

exports[`options validate should throw an error on the "client" option with '{"reconnect":""}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
* options.client.reconnect should be one of these:
boolean | number (should be >= 0)
-> Tells dev-server the number of times it should try to reconnect the client.
-> Read more at https://webpack.js.org/configuration/dev-server/#reconnect
Details:
* options.client.reconnect should be a boolean.
* options.client.reconnect should be a number (should be >= 0)."
`;

exports[`options validate should throw an error on the "client" option with '{"unknownOption":true}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client has an unknown property 'unknownOption'. These properties are valid:
object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }"
object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }"
`;

exports[`options validate should throw an error on the "client" option with '{"webSocketTransport":true}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand Down Expand Up @@ -171,7 +187,7 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand All @@ -186,7 +202,7 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"username":123,"password":976}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
Expand All @@ -199,13 +215,13 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be one of these:
false | object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }
false | object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }
-> Allows to specify options for client script in the browser or disable client script.
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverclient
Details:
* options.client should be false.
* options.client should be an object:
object { logging?, overlay?, progress?, webSocketTransport?, webSocketURL? }"
object { logging?, overlay?, progress?, reconnect?, webSocketTransport?, webSocketURL? }"
`;

exports[`options validate should throw an error on the "compress" option with '' value 1`] = `
Expand Down
2 changes: 2 additions & 0 deletions test/cli/__snapshots__/basic.test.js.snap.webpack4
Expand Up @@ -69,6 +69,8 @@ Options:
--no-client-overlay-errors Negative 'client-overlay-errors' option.
--client-overlay-warnings Enables a full-screen overlay in the browser when there are compiler warnings.
--no-client-overlay-warnings Negative 'client-overlay-warnings' option.
--client-reconnect [value] Tells dev-server the number of times it should try to reconnect the client.
--no-client-reconnect Tells dev-server to not to try to connect the client.
--client-web-socket-url <value> Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).
--client-web-socket-url-hostname <value> Tells clients connected to devServer to use the provided hostname.
--client-web-socket-url-port <value> Tells clients connected to devServer to use the provided port.
Expand Down
2 changes: 2 additions & 0 deletions test/cli/__snapshots__/basic.test.js.snap.webpack5
Expand Up @@ -69,6 +69,8 @@ Options:
--no-client-overlay-warnings Negative 'client-overlay-warnings' option.
--client-progress Prints compilation progress in percentage in the browser.
--no-client-progress Negative 'client-progress' option.
--client-reconnect [value] Tells dev-server the number of times it should try to reconnect the client.
--no-client-reconnect Negative 'client-reconnect' option.
--client-web-socket-transport <value> Allows to set custom web socket transport to communicate with dev server.
--client-web-socket-url <value> Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).
--client-web-socket-url-hostname <value> Tells clients connected to devServer to use the provided hostname.
Expand Down

0 comments on commit 5edad76

Please sign in to comment.