From b96ddfc2e8c7a51684322a7d4052393f38caaefb Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 18 May 2021 00:07:01 +0530 Subject: [PATCH 01/19] feat: add webSocketURL option --- lib/options.json | 56 +++++++++------ lib/utils/DevServerPlugin.js | 68 ++++++++++-------- .../validate-options.test.js.snap.webpack4 | 53 +++++++------- .../validate-options.test.js.snap.webpack5 | 53 +++++++------- test/validate-options.test.js | 72 +++++++++---------- 5 files changed, 166 insertions(+), 136 deletions(-) diff --git a/lib/options.json b/lib/options.json index 655aabd0da..449a0b7f61 100644 --- a/lib/options.json +++ b/lib/options.json @@ -229,28 +229,6 @@ ], "description": "Allows to set custom transport to communicate with server." }, - "host": { - "type": "string", - "description": "Tells clients connected to devServer to use the provided host." - }, - "path": { - "type": "string", - "description": "Tells clients connected to devServer to use the provided path to connect." - }, - "port": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "enum": ["auto"] - } - ], - "description": "Tells clients connected to devServer to use the provided port." - }, "logging": { "enum": ["none", "error", "warn", "info", "log", "verbose"], "decription": "Log level in the browser." @@ -306,6 +284,40 @@ "description": "Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient", "additionalProperties": false }, + "webSocketURL": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "Tells clients connected to devServer to use the provided host." + }, + "path": { + "type": "string", + "description": "Tells clients connected to devServer to use the provided path to connect." + }, + "port": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "enum": ["auto"] + } + ], + "description": "Tells clients connected to devServer to use the provided path to connect." + } + } + } + ] + }, "webSocketServer": { "anyOf": [ { diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index e92c1ffda1..7f135bf1f3 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -35,36 +35,48 @@ class DevServerPlugin { // TODO show warning about this const isSockJSType = options.webSocketServer.type === 'sockjs'; - /** @type {string} */ - let host = ''; - - if (options.client && options.client.host) { - host = `&host=${options.client.host}`; - } else if (options.webSocketServer.options.host && !isSockJSType) { - host = `&host=${options.webSocketServer.options.host}`; - } + let webSocketURL = ''; + + if (typeof options.webSocketURL === 'string') { + webSocketURL = options.webSocketURL; + } else if (typeof options.webSocketURL === 'object') { + /** @type {string} */ + let host = ''; + + if (options.webSocketURL && options.webSocketURL.host) { + host = `&host=${options.webSocketURL.host}`; + } else if (options.webSocketServer.options.host && !isSockJSType) { + host = `&host=${options.webSocketServer.options.host}`; + } - /** @type {string} */ - let port = ''; - - if (options.client && options.client.port) { - port = `&port=${options.client.port}`; - } else if (options.webSocketServer.options.port && !isSockJSType) { - port = `&port=${options.webSocketServer.options.port}`; - } else if (options.port) { - port = `&port=${options.port}`; - } else { - port = ''; - } + /** @type {string} */ + let port = ''; + + if (options.webSocketURL && options.webSocketURL.port) { + port = `&port=${options.webSocketURL.port}`; + } else if (options.webSocketServer.options.port && !isSockJSType) { + port = `&port=${options.webSocketServer.options.port}`; + } else if (options.port) { + port = `&port=${options.port}`; + } else { + port = ''; + } - /** @type {string} */ - let path = ''; + /** @type {string} */ + let path = ''; + + // Only add the path if it is not default + if ( + options.webSocketURL && + options.webSocketURL.path && + options.webSocketURL.path + ) { + path = `&path=${options.client.path}`; + } else if (options.webSocketServer.options.path) { + path = `&path=${options.webSocketServer.options.path}`; + } - // Only add the path if it is not default - if (options.client && options.client.path && options.client.path) { - path = `&path=${options.client.path}`; - } else if (options.webSocketServer.options.path) { - path = `&path=${options.webSocketServer.options.path}`; + webSocketURL = `${host}${path}${port}`; } /** @type {string} */ @@ -76,7 +88,7 @@ class DevServerPlugin { /** @type {string} */ const clientEntry = `${require.resolve( '../../client/index.js' - )}?${domain}${host}${path}${port}${logging}`; + )}?${domain}${webSocketURL}${logging}`; /** @type {(string[] | string)} */ let hotEntry; diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4 index 5580b1b45f..1c0d0157a4 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack4 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -12,12 +12,6 @@ exports[`options validate should throw an error on the "bonjour" option with '' -> Options for bonjour, description available at https://github.com/watson/bonjour#initializing" `; -exports[`options validate should throw an error on the "client" option with '{"host":true,"path":"","port":8080}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.host should be a string. - -> Tells clients connected to devServer to use the provided host." -`; - exports[`options validate should throw an error on the "client" option with '{"hotEntry":[""]}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.hotEntry should be one of these: @@ -73,23 +67,6 @@ exports[`options validate should throw an error on the "client" option with '{"o -> Show a full-screen overlay in the browser when there are compiler warnings." `; -exports[`options validate should throw an error on the "client" option with '{"path":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.path should be a string. - -> Tells clients connected to devServer to use the provided path to connect." -`; - -exports[`options validate should throw an error on the "client" option with '{"port":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.port should be one of these: - number | string | \\"auto\\" - -> Tells clients connected to devServer to use the provided port. - Details: - * configuration.client.port should be a number. - * configuration.client.port should be a string. - * configuration.client.port should be \\"auto\\"." -`; - exports[`options validate should throw an error on the "client" option with '{"progress":""}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.progress should be a boolean. @@ -110,14 +87,14 @@ exports[`options validate should throw an error on the "client" option with '{"t exports[`options validate should throw an error on the "client" option with '{"unknownOption":true}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client has an unknown property 'unknownOption'. These properties are valid: - object { transport?, host?, path?, port?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client should be an object: - object { transport?, host?, path?, port?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; @@ -587,3 +564,29 @@ exports[`options validate should throw an error on the "webSocketServer" option * configuration.webSocketServer should be an object: object { type?, options? }" `; + +exports[`options validate should throw an error on the "webSocketURL" option with '{"host":true,"path":"","port":8080}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.webSocketURL.host should be a string. + -> Tells clients connected to devServer to use the provided host." +`; + +exports[`options validate should throw an error on the "webSocketURL" option with '{"path":true}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.webSocketURL.path should be a string. + -> Tells clients connected to devServer to use the provided path to connect." +`; + +exports[`options validate should throw an error on the "webSocketURL" option with '{"port":true}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.webSocketURL should be one of these: + string | object { host?, path?, port?, … } + Details: + * configuration.webSocketURL.port should be one of these: + number | string | \\"auto\\" + -> Tells clients connected to devServer to use the provided path to connect. + Details: + * configuration.webSocketURL.port should be a number. + * configuration.webSocketURL.port should be a string. + * configuration.webSocketURL.port should be \\"auto\\"." +`; diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 index 5580b1b45f..1c0d0157a4 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack5 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -12,12 +12,6 @@ exports[`options validate should throw an error on the "bonjour" option with '' -> Options for bonjour, description available at https://github.com/watson/bonjour#initializing" `; -exports[`options validate should throw an error on the "client" option with '{"host":true,"path":"","port":8080}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.host should be a string. - -> Tells clients connected to devServer to use the provided host." -`; - exports[`options validate should throw an error on the "client" option with '{"hotEntry":[""]}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.hotEntry should be one of these: @@ -73,23 +67,6 @@ exports[`options validate should throw an error on the "client" option with '{"o -> Show a full-screen overlay in the browser when there are compiler warnings." `; -exports[`options validate should throw an error on the "client" option with '{"path":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.path should be a string. - -> Tells clients connected to devServer to use the provided path to connect." -`; - -exports[`options validate should throw an error on the "client" option with '{"port":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.port should be one of these: - number | string | \\"auto\\" - -> Tells clients connected to devServer to use the provided port. - Details: - * configuration.client.port should be a number. - * configuration.client.port should be a string. - * configuration.client.port should be \\"auto\\"." -`; - exports[`options validate should throw an error on the "client" option with '{"progress":""}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.progress should be a boolean. @@ -110,14 +87,14 @@ exports[`options validate should throw an error on the "client" option with '{"t exports[`options validate should throw an error on the "client" option with '{"unknownOption":true}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client has an unknown property 'unknownOption'. These properties are valid: - object { transport?, host?, path?, port?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client should be an object: - object { transport?, host?, path?, port?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; @@ -587,3 +564,29 @@ exports[`options validate should throw an error on the "webSocketServer" option * configuration.webSocketServer should be an object: object { type?, options? }" `; + +exports[`options validate should throw an error on the "webSocketURL" option with '{"host":true,"path":"","port":8080}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.webSocketURL.host should be a string. + -> Tells clients connected to devServer to use the provided host." +`; + +exports[`options validate should throw an error on the "webSocketURL" option with '{"path":true}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.webSocketURL.path should be a string. + -> Tells clients connected to devServer to use the provided path to connect." +`; + +exports[`options validate should throw an error on the "webSocketURL" option with '{"port":true}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.webSocketURL should be one of these: + string | object { host?, path?, port?, … } + Details: + * configuration.webSocketURL.port should be one of these: + number | string | \\"auto\\" + -> Tells clients connected to devServer to use the provided path to connect. + Details: + * configuration.webSocketURL.port should be a number. + * configuration.webSocketURL.port should be a string. + * configuration.webSocketURL.port should be \\"auto\\"." +`; diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 32ba0d62a2..de529a3c71 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -28,15 +28,6 @@ const tests = { client: { success: [ {}, - { - host: '', - }, - { - path: '', - }, - { - port: '', - }, { logging: 'none', }, @@ -55,22 +46,6 @@ const tests = { { logging: 'verbose', }, - { - host: '', - path: '', - port: 8080, - logging: 'none', - }, - { - host: '', - path: '', - port: '', - }, - { - host: '', - path: '', - port: 'auto', - }, { progress: false, }, @@ -113,11 +88,6 @@ const tests = { { unknownOption: true, }, - { - host: true, - path: '', - port: 8080, - }, { logging: 'whoops!', }, @@ -146,12 +116,6 @@ const tests = { { hotEntry: [''], }, - { - path: true, - }, - { - port: true, - }, { transport: true, }, @@ -320,6 +284,42 @@ const tests = { }, ], }, + webSocketURL: { + success: [ + { + host: '', + }, + { + path: '', + }, + { + port: '', + }, + { + host: '', + path: '', + port: '', + }, + { + host: '', + path: '', + port: 'auto', + }, + ], + failure: [ + { + host: true, + path: '', + port: 8080, + }, + { + path: true, + }, + { + port: true, + }, + ], + }, webSocketServer: { success: [ 'ws', From 035db27d60883812fe20b6737534882665a4030e Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 18 May 2021 00:10:42 +0530 Subject: [PATCH 02/19] test: update --- test/e2e/ClientOptions.test.js | 12 ++++++------ test/server/utils/normalizeOptions.test.js | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/ClientOptions.test.js index b0fff4eb0e..dfaa3199ea 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/ClientOptions.test.js @@ -196,7 +196,7 @@ for (const webSocketServerType of webSocketServerTypes) { beforeAll((done) => { const options = { - client: { host: devServerHost }, + webSocketUrl: { host: devServerHost }, webSocketServer: webSocketServerType, port: devServerPort, host: devServerHost, @@ -247,7 +247,7 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - client: { + webSocketUrl: { path: '/foo/test/bar/', port: port3, }, @@ -281,7 +281,7 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - client: { + webSocketUrl: { port: port3, }, }; @@ -314,7 +314,7 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - client: { + webSocketUrl: { host: 'myhost.test', }, }; @@ -346,7 +346,7 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - client: { + webSocketUrl: { host: 'myhost', port: port3, path: '/foo/test/bar/', @@ -382,7 +382,7 @@ for (const webSocketServerType of webSocketServerTypes) { port: port2, host: '0.0.0.0', public: 'myhost.test', - client: { + webSocketUrl: { path: '/foo/test/bar/', }, }; diff --git a/test/server/utils/normalizeOptions.test.js b/test/server/utils/normalizeOptions.test.js index 855d09141c..7f5104883f 100644 --- a/test/server/utils/normalizeOptions.test.js +++ b/test/server/utils/normalizeOptions.test.js @@ -73,7 +73,7 @@ describe('normalizeOptions', () => { title: 'client host and port', multiCompiler: false, options: { - client: { + webSocketUrl: { host: 'my.host', port: 9000, }, @@ -84,7 +84,7 @@ describe('normalizeOptions', () => { title: 'client path', multiCompiler: false, options: { - client: { + webSocketUrl: { path: '/custom/path/', }, }, @@ -94,7 +94,7 @@ describe('normalizeOptions', () => { title: 'client path without leading/ending slashes', multiCompiler: false, options: { - client: { + webSocketUrl: { path: 'custom/path', }, }, From 5f49832b70f0be751a96171a24bb8c947022c260 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 18 May 2021 09:18:06 +0530 Subject: [PATCH 03/19] test: update --- lib/utils/DevServerPlugin.js | 12 ++++------- test/e2e/ClientOptions.test.js | 20 ++++++++++--------- .../Server.test.js.snap.webpack4 | 9 +++------ .../Server.test.js.snap.webpack5 | 9 +++------ .../normalizeOptions.test.js.snap.webpack4 | 14 +++++++++---- .../normalizeOptions.test.js.snap.webpack5 | 14 +++++++++---- test/server/utils/normalizeOptions.test.js | 6 +++--- 7 files changed, 44 insertions(+), 40 deletions(-) diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index 7f135bf1f3..45686dee32 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -43,7 +43,7 @@ class DevServerPlugin { /** @type {string} */ let host = ''; - if (options.webSocketURL && options.webSocketURL.host) { + if (options.webSocketURL.host) { host = `&host=${options.webSocketURL.host}`; } else if (options.webSocketServer.options.host && !isSockJSType) { host = `&host=${options.webSocketServer.options.host}`; @@ -52,7 +52,7 @@ class DevServerPlugin { /** @type {string} */ let port = ''; - if (options.webSocketURL && options.webSocketURL.port) { + if (options.webSocketURL.port) { port = `&port=${options.webSocketURL.port}`; } else if (options.webSocketServer.options.port && !isSockJSType) { port = `&port=${options.webSocketServer.options.port}`; @@ -66,12 +66,8 @@ class DevServerPlugin { let path = ''; // Only add the path if it is not default - if ( - options.webSocketURL && - options.webSocketURL.path && - options.webSocketURL.path - ) { - path = `&path=${options.client.path}`; + if (options.webSocketURL.path && options.webSocketURL.path) { + path = `&path=${options.webSocketURL.path}`; } else if (options.webSocketServer.options.path) { path = `&path=${options.webSocketServer.options.path}`; } diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/ClientOptions.test.js index dfaa3199ea..dfe413ee17 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/ClientOptions.test.js @@ -196,10 +196,12 @@ for (const webSocketServerType of webSocketServerTypes) { beforeAll((done) => { const options = { - webSocketUrl: { host: devServerHost }, - webSocketServer: webSocketServerType, + webSocketURL: { + host: devServerHost, + }, port: devServerPort, host: devServerHost, + webSocketServer: webSocketServerType, firewall: false, hot: true, static: true, @@ -247,9 +249,9 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketUrl: { - path: '/foo/test/bar/', - port: port3, + webSocketURL: { + host: '0.0.0.0', + port: port2, }, }; @@ -281,7 +283,7 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketUrl: { + webSocketURL: { port: port3, }, }; @@ -314,7 +316,7 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketUrl: { + webSocketURL: { host: 'myhost.test', }, }; @@ -346,7 +348,7 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketUrl: { + webSocketURL: { host: 'myhost', port: port3, path: '/foo/test/bar/', @@ -382,7 +384,7 @@ for (const webSocketServerType of webSocketServerTypes) { port: port2, host: '0.0.0.0', public: 'myhost.test', - webSocketUrl: { + webSocketURL: { path: '/foo/test/bar/', }, }; diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack4 b/test/server/__snapshots__/Server.test.js.snap.webpack4 index 9cc203a7a1..9609b892f5 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack4 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack4 @@ -5,8 +5,7 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "0.0.0.0", ], Array [ "node_modules", @@ -25,8 +24,7 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "0.0.0.0", ], Array [ "node_modules", @@ -45,8 +43,7 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "0.0.0.0", ], Array [ "node_modules", diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack5 b/test/server/__snapshots__/Server.test.js.snap.webpack5 index 9cc203a7a1..9609b892f5 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack5 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack5 @@ -5,8 +5,7 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "0.0.0.0", ], Array [ "node_modules", @@ -25,8 +24,7 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "0.0.0.0", ], Array [ "node_modules", @@ -45,8 +43,7 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "0.0.0.0", ], Array [ "node_modules", diff --git a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 index 41ed9a2d6d..3d93cb6fc8 100644 --- a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 +++ b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 @@ -38,10 +38,8 @@ Object { exports[`normalizeOptions client host and port should set correct options 1`] = ` Object { "client": Object { - "host": "my.host", "hotEntry": true, "overlay": true, - "port": 9000, }, "compress": true, "devMiddleware": Object {}, @@ -68,6 +66,10 @@ Object { }, "type": "ws", }, + "webSocketURL": Object { + "host": "my.host", + "port": 9000, + }, } `; @@ -76,7 +78,6 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "path": "/custom/path/", }, "compress": true, "devMiddleware": Object {}, @@ -103,6 +104,9 @@ Object { }, "type": "ws", }, + "webSocketURL": Object { + "path": "/custom/path/", + }, } `; @@ -111,7 +115,6 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "path": "custom/path", }, "compress": true, "devMiddleware": Object {}, @@ -138,6 +141,9 @@ Object { }, "type": "ws", }, + "webSocketURL": Object { + "path": "custom/path", + }, } `; diff --git a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 index 41ed9a2d6d..3d93cb6fc8 100644 --- a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 +++ b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 @@ -38,10 +38,8 @@ Object { exports[`normalizeOptions client host and port should set correct options 1`] = ` Object { "client": Object { - "host": "my.host", "hotEntry": true, "overlay": true, - "port": 9000, }, "compress": true, "devMiddleware": Object {}, @@ -68,6 +66,10 @@ Object { }, "type": "ws", }, + "webSocketURL": Object { + "host": "my.host", + "port": 9000, + }, } `; @@ -76,7 +78,6 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "path": "/custom/path/", }, "compress": true, "devMiddleware": Object {}, @@ -103,6 +104,9 @@ Object { }, "type": "ws", }, + "webSocketURL": Object { + "path": "/custom/path/", + }, } `; @@ -111,7 +115,6 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "path": "custom/path", }, "compress": true, "devMiddleware": Object {}, @@ -138,6 +141,9 @@ Object { }, "type": "ws", }, + "webSocketURL": Object { + "path": "custom/path", + }, } `; diff --git a/test/server/utils/normalizeOptions.test.js b/test/server/utils/normalizeOptions.test.js index 7f5104883f..4df2a057cb 100644 --- a/test/server/utils/normalizeOptions.test.js +++ b/test/server/utils/normalizeOptions.test.js @@ -73,7 +73,7 @@ describe('normalizeOptions', () => { title: 'client host and port', multiCompiler: false, options: { - webSocketUrl: { + webSocketURL: { host: 'my.host', port: 9000, }, @@ -84,7 +84,7 @@ describe('normalizeOptions', () => { title: 'client path', multiCompiler: false, options: { - webSocketUrl: { + webSocketURL: { path: '/custom/path/', }, }, @@ -94,7 +94,7 @@ describe('normalizeOptions', () => { title: 'client path without leading/ending slashes', multiCompiler: false, options: { - webSocketUrl: { + webSocketURL: { path: 'custom/path', }, }, From 83a8773b80f6177789d4dcf192086ed300fe347f Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 18 May 2021 10:19:21 +0530 Subject: [PATCH 04/19] test: update --- test/e2e/ClientOptions.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/ClientOptions.test.js index dfe413ee17..b5c2284e3b 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/ClientOptions.test.js @@ -250,8 +250,8 @@ for (const webSocketServerType of webSocketServerTypes) { port: port2, host: '0.0.0.0', webSocketURL: { - host: '0.0.0.0', - port: port2, + path: '/foo/test/bar/', + port: port3, }, }; From 2916cd727c8002382383b55099363d57ea41ff3f Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Fri, 21 May 2021 11:47:39 +0530 Subject: [PATCH 05/19] chore: update --- lib/options.json | 6 ------ .../validate-options.test.js.snap.webpack4 | 18 +++++++++++------- test/validate-options.test.js | 8 +++++--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/options.json b/lib/options.json index 449a0b7f61..97c5df0cfd 100644 --- a/lib/options.json +++ b/lib/options.json @@ -304,12 +304,6 @@ "anyOf": [ { "type": "number" - }, - { - "type": "string" - }, - { - "enum": ["auto"] } ], "description": "Tells clients connected to devServer to use the provided path to connect." diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4 index 1c0d0157a4..872d30c724 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack4 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -577,16 +577,20 @@ exports[`options validate should throw an error on the "webSocketURL" option wit -> Tells clients connected to devServer to use the provided path to connect." `; +exports[`options validate should throw an error on the "webSocketURL" option with '{"port":""}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.webSocketURL should be one of these: + string | object { host?, path?, port?, … } + Details: + * configuration.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided path to connect." +`; + exports[`options validate should throw an error on the "webSocketURL" option with '{"port":true}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.webSocketURL should be one of these: string | object { host?, path?, port?, … } Details: - * configuration.webSocketURL.port should be one of these: - number | string | \\"auto\\" - -> Tells clients connected to devServer to use the provided path to connect. - Details: - * configuration.webSocketURL.port should be a number. - * configuration.webSocketURL.port should be a string. - * configuration.webSocketURL.port should be \\"auto\\"." + * configuration.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided path to connect." `; diff --git a/test/validate-options.test.js b/test/validate-options.test.js index de529a3c71..e107b0583d 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -293,17 +293,16 @@ const tests = { path: '', }, { - port: '', + port: 8080, }, { host: '', path: '', - port: '', }, { host: '', path: '', - port: 'auto', + port: 8080, }, ], failure: [ @@ -318,6 +317,9 @@ const tests = { { port: true, }, + { + port: '', + }, ], }, webSocketServer: { From 9908833a01921865af6920aae97da32ffeb6ad81 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sun, 23 May 2021 15:10:02 +0530 Subject: [PATCH 06/19] fix: code --- lib/options.json | 54 +++++++-------- lib/utils/DevServerPlugin.js | 18 ++--- lib/utils/normalizeOptions.js | 4 ++ .../validate-options.test.js.snap.webpack4 | 64 +++++++++--------- .../validate-options.test.js.snap.webpack5 | 60 +++++++++-------- test/e2e/ClientOptions.test.js | 2 +- .../Server.test.js.snap.webpack4 | 9 ++- .../Server.test.js.snap.webpack5 | 9 ++- .../normalizeOptions.test.js.snap.webpack4 | 37 +++++++++++ .../normalizeOptions.test.js.snap.webpack5 | 37 +++++++++++ test/validate-options.test.js | 65 ++++++++----------- 11 files changed, 218 insertions(+), 141 deletions(-) diff --git a/lib/options.json b/lib/options.json index 97c5df0cfd..bb2363f2a7 100644 --- a/lib/options.json +++ b/lib/options.json @@ -279,38 +279,38 @@ } ], "description": "Tells devServer to inject a Hot Module Replacement entry." - } - }, - "description": "Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient", - "additionalProperties": false - }, - "webSocketURL": { - "anyOf": [ - { - "type": "string" }, - { - "type": "object", - "properties": { - "host": { - "type": "string", - "description": "Tells clients connected to devServer to use the provided host." - }, - "path": { - "type": "string", - "description": "Tells clients connected to devServer to use the provided path to connect." + "webSocketURL": { + "anyOf": [ + { + "type": "string" }, - "port": { - "anyOf": [ - { - "type": "number" + { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "Tells clients connected to devServer to use the provided host." + }, + "path": { + "type": "string", + "description": "Tells clients connected to devServer to use the provided path to connect." + }, + "port": { + "anyOf": [ + { + "type": "number" + } + ], + "description": "Tells clients connected to devServer to use the provided path to connect." } - ], - "description": "Tells clients connected to devServer to use the provided path to connect." + } } - } + ] } - ] + }, + "description": "Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient", + "additionalProperties": false }, "webSocketServer": { "anyOf": [ diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index 45686dee32..397d23f28f 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -37,14 +37,14 @@ class DevServerPlugin { let webSocketURL = ''; - if (typeof options.webSocketURL === 'string') { - webSocketURL = options.webSocketURL; - } else if (typeof options.webSocketURL === 'object') { + if (typeof options.client.webSocketURL === 'string') { + webSocketURL = options.client.webSocketURL; + } else if (typeof options.client.webSocketURL === 'object') { /** @type {string} */ let host = ''; - if (options.webSocketURL.host) { - host = `&host=${options.webSocketURL.host}`; + if (options.client.webSocketURL.host) { + host = `&host=${options.client.webSocketURL.host}`; } else if (options.webSocketServer.options.host && !isSockJSType) { host = `&host=${options.webSocketServer.options.host}`; } @@ -52,8 +52,8 @@ class DevServerPlugin { /** @type {string} */ let port = ''; - if (options.webSocketURL.port) { - port = `&port=${options.webSocketURL.port}`; + if (options.client.webSocketURL.port) { + port = `&port=${options.client.webSocketURL.port}`; } else if (options.webSocketServer.options.port && !isSockJSType) { port = `&port=${options.webSocketServer.options.port}`; } else if (options.port) { @@ -66,8 +66,8 @@ class DevServerPlugin { let path = ''; // Only add the path if it is not default - if (options.webSocketURL.path && options.webSocketURL.path) { - path = `&path=${options.webSocketURL.path}`; + if (options.client.webSocketURL.path) { + path = `&path=${options.client.webSocketURL.path}`; } else if (options.webSocketServer.options.path) { path = `&path=${options.webSocketServer.options.path}`; } diff --git a/lib/utils/normalizeOptions.js b/lib/utils/normalizeOptions.js index 26b92bef71..f92802d566 100644 --- a/lib/utils/normalizeOptions.js +++ b/lib/utils/normalizeOptions.js @@ -104,6 +104,10 @@ function normalizeOptions(compiler, options, logger) { options.client = {}; } + if (typeof options.client.webSocketURL === 'undefined') { + options.client.webSocketURL = {}; + } + // Enable client overlay by default if (typeof options.client.overlay === 'undefined') { options.client.overlay = true; diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4 index 872d30c724..53ff152896 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack4 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -87,14 +87,44 @@ exports[`options validate should throw an error on the "client" option with '{"t exports[`options validate should throw an error on the "client" option with '{"unknownOption":true}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client has an unknown property 'unknownOption'. These properties are valid: - object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry?, webSocketURL? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"host":true,"path":"","port":8080}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL.host should be a string. + -> Tells clients connected to devServer to use the provided host." +`; + +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"path":true}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL.path should be a string. + -> Tells clients connected to devServer to use the provided path to connect." +`; + +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":""}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL should be one of these: + string | object { host?, path?, port?, … } + Details: + * configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided path to connect." +`; + +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL should be one of these: + string | object { host?, path?, port?, … } + Details: + * configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided path to connect." +`; + exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client should be an object: - object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry?, webSocketURL? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; @@ -564,33 +594,3 @@ exports[`options validate should throw an error on the "webSocketServer" option * configuration.webSocketServer should be an object: object { type?, options? }" `; - -exports[`options validate should throw an error on the "webSocketURL" option with '{"host":true,"path":"","port":8080}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.webSocketURL.host should be a string. - -> Tells clients connected to devServer to use the provided host." -`; - -exports[`options validate should throw an error on the "webSocketURL" option with '{"path":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.webSocketURL.path should be a string. - -> Tells clients connected to devServer to use the provided path to connect." -`; - -exports[`options validate should throw an error on the "webSocketURL" option with '{"port":""}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.webSocketURL should be one of these: - string | object { host?, path?, port?, … } - Details: - * configuration.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided path to connect." -`; - -exports[`options validate should throw an error on the "webSocketURL" option with '{"port":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.webSocketURL should be one of these: - string | object { host?, path?, port?, … } - Details: - * configuration.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided path to connect." -`; diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 index 1c0d0157a4..53ff152896 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack5 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -87,14 +87,44 @@ exports[`options validate should throw an error on the "client" option with '{"t exports[`options validate should throw an error on the "client" option with '{"unknownOption":true}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client has an unknown property 'unknownOption'. These properties are valid: - object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry?, webSocketURL? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"host":true,"path":"","port":8080}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL.host should be a string. + -> Tells clients connected to devServer to use the provided host." +`; + +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"path":true}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL.path should be a string. + -> Tells clients connected to devServer to use the provided path to connect." +`; + +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":""}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL should be one of these: + string | object { host?, path?, port?, … } + Details: + * configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided path to connect." +`; + +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL should be one of these: + string | object { host?, path?, port?, … } + Details: + * configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided path to connect." +`; + exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client should be an object: - object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry? } + object { transport?, logging?, progress?, overlay?, needClientEntry?, hotEntry?, webSocketURL? } -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; @@ -564,29 +594,3 @@ exports[`options validate should throw an error on the "webSocketServer" option * configuration.webSocketServer should be an object: object { type?, options? }" `; - -exports[`options validate should throw an error on the "webSocketURL" option with '{"host":true,"path":"","port":8080}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.webSocketURL.host should be a string. - -> Tells clients connected to devServer to use the provided host." -`; - -exports[`options validate should throw an error on the "webSocketURL" option with '{"path":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.webSocketURL.path should be a string. - -> Tells clients connected to devServer to use the provided path to connect." -`; - -exports[`options validate should throw an error on the "webSocketURL" option with '{"port":true}' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.webSocketURL should be one of these: - string | object { host?, path?, port?, … } - Details: - * configuration.webSocketURL.port should be one of these: - number | string | \\"auto\\" - -> Tells clients connected to devServer to use the provided path to connect. - Details: - * configuration.webSocketURL.port should be a number. - * configuration.webSocketURL.port should be a string. - * configuration.webSocketURL.port should be \\"auto\\"." -`; diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/ClientOptions.test.js index b5c2284e3b..b06c359f62 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/ClientOptions.test.js @@ -38,7 +38,7 @@ for (const webSocketServerType of webSocketServerTypes) { }); }; - describe(`should work behind proxy, when hostnames are same and ports are different (${webSocketServerType})`, () => { + describe.only(`should work behind proxy, when hostnames are same and ports are different (${webSocketServerType})`, () => { const devServerHost = '127.0.0.1'; const devServerPort = port1; const proxyHost = devServerHost; diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack4 b/test/server/__snapshots__/Server.test.js.snap.webpack4 index 9609b892f5..9cc203a7a1 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack4 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack4 @@ -5,7 +5,8 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0", + "0.0.0.0&path=", + "ws&port=8100", ], Array [ "node_modules", @@ -24,7 +25,8 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0", + "0.0.0.0&path=", + "ws&port=8100", ], Array [ "node_modules", @@ -43,7 +45,8 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0", + "0.0.0.0&path=", + "ws&port=8100", ], Array [ "node_modules", diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack5 b/test/server/__snapshots__/Server.test.js.snap.webpack5 index 9609b892f5..9cc203a7a1 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack5 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack5 @@ -5,7 +5,8 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0", + "0.0.0.0&path=", + "ws&port=8100", ], Array [ "node_modules", @@ -24,7 +25,8 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0", + "0.0.0.0&path=", + "ws&port=8100", ], Array [ "node_modules", @@ -43,7 +45,8 @@ Array [ Array [ "client", "index.js?http:", - "0.0.0.0", + "0.0.0.0&path=", + "ws&port=8100", ], Array [ "node_modules", diff --git a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 index 3d93cb6fc8..077de4ac31 100644 --- a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 +++ b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 @@ -6,6 +6,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "/path/to/custom/client/", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -40,6 +41,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -78,6 +80,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -115,6 +118,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -153,6 +157,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "sockjs", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -188,6 +193,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "ws", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -223,6 +229,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "ws", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -257,6 +264,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object { @@ -293,6 +301,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -327,6 +336,7 @@ Object { "client": Object { "hotEntry": false, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -361,6 +371,7 @@ Object { "client": Object { "hotEntry": "only", "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -395,6 +406,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -429,6 +441,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -463,6 +476,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -497,6 +511,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -533,6 +548,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -567,6 +583,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -603,6 +620,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -639,6 +657,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -675,6 +694,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -709,6 +729,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -754,6 +775,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -799,6 +821,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -844,6 +867,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -878,6 +902,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -900,6 +925,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -934,6 +960,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -968,6 +995,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1002,6 +1030,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1037,6 +1066,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1071,6 +1101,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1103,6 +1134,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1137,6 +1169,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1173,6 +1206,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1207,6 +1241,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1241,6 +1276,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1275,6 +1311,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, diff --git a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 index 3d93cb6fc8..077de4ac31 100644 --- a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 +++ b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 @@ -6,6 +6,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "/path/to/custom/client/", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -40,6 +41,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -78,6 +80,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -115,6 +118,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -153,6 +157,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "sockjs", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -188,6 +193,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "ws", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -223,6 +229,7 @@ Object { "hotEntry": true, "overlay": true, "transport": "ws", + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -257,6 +264,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object { @@ -293,6 +301,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -327,6 +336,7 @@ Object { "client": Object { "hotEntry": false, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -361,6 +371,7 @@ Object { "client": Object { "hotEntry": "only", "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -395,6 +406,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -429,6 +441,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -463,6 +476,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -497,6 +511,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -533,6 +548,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -567,6 +583,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -603,6 +620,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -639,6 +657,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -675,6 +694,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -709,6 +729,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -754,6 +775,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -799,6 +821,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -844,6 +867,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -878,6 +902,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -900,6 +925,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -934,6 +960,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -968,6 +995,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1002,6 +1030,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1037,6 +1066,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1071,6 +1101,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1103,6 +1134,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1137,6 +1169,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1173,6 +1206,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1207,6 +1241,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1241,6 +1276,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, @@ -1275,6 +1311,7 @@ Object { "client": Object { "hotEntry": true, "overlay": true, + "webSocketURL": Object {}, }, "compress": true, "devMiddleware": Object {}, diff --git a/test/validate-options.test.js b/test/validate-options.test.js index e107b0583d..22b73f2838 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -82,6 +82,21 @@ const tests = { { transport: require.resolve('../client/clients/SockJSClient'), }, + { + webSocketURL: { host: '' }, + }, + { + webSocketURL: { path: '' }, + }, + { + webSocketURL: { port: 8080 }, + }, + { + webSocketURL: { host: '', path: '' }, + }, + { + webSocketURL: { host: '', path: '', port: 8080 }, + }, ], failure: [ 'whoops!', @@ -119,6 +134,18 @@ const tests = { { transport: true, }, + { + webSocketURL: { host: true, path: '', port: 8080 }, + }, + { + webSocketURL: { path: true }, + }, + { + webSocketURL: { port: true }, + }, + { + webSocketURL: { port: '' }, + }, ], }, compress: { @@ -284,44 +311,6 @@ const tests = { }, ], }, - webSocketURL: { - success: [ - { - host: '', - }, - { - path: '', - }, - { - port: 8080, - }, - { - host: '', - path: '', - }, - { - host: '', - path: '', - port: 8080, - }, - ], - failure: [ - { - host: true, - path: '', - port: 8080, - }, - { - path: true, - }, - { - port: true, - }, - { - port: '', - }, - ], - }, webSocketServer: { success: [ 'ws', From b942bf488da8b911b621ad19c7fb3dbb1cc28bf2 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sun, 23 May 2021 15:16:28 +0530 Subject: [PATCH 07/19] fix: code --- test/e2e/ClientOptions.test.js | 42 ++++++++++++------- .../normalizeOptions.test.js.snap.webpack4 | 23 +++++----- .../normalizeOptions.test.js.snap.webpack5 | 23 +++++----- test/server/utils/normalizeOptions.test.js | 20 +++++---- 4 files changed, 60 insertions(+), 48 deletions(-) diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/ClientOptions.test.js index b06c359f62..c0372c7cea 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/ClientOptions.test.js @@ -196,8 +196,10 @@ for (const webSocketServerType of webSocketServerTypes) { beforeAll((done) => { const options = { - webSocketURL: { - host: devServerHost, + client: { + webSocketURL: { + host: devServerHost, + }, }, port: devServerPort, host: devServerHost, @@ -249,9 +251,11 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketURL: { - path: '/foo/test/bar/', - port: port3, + client: { + webSocketURL: { + path: '/foo/test/bar/', + port: port3, + }, }, }; @@ -283,8 +287,10 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketURL: { - port: port3, + client: { + webSocketURL: { + port: port3, + }, }, }; @@ -316,8 +322,10 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketURL: { - host: 'myhost.test', + client: { + webSocketURL: { + host: 'myhost.test', + }, }, }; testServer.startAwaitingCompilation(config, options, done); @@ -348,10 +356,12 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - webSocketURL: { - host: 'myhost', - port: port3, - path: '/foo/test/bar/', + client: { + webSocketURL: { + host: 'myhost', + port: port3, + path: '/foo/test/bar/', + }, }, }; @@ -384,8 +394,10 @@ for (const webSocketServerType of webSocketServerTypes) { port: port2, host: '0.0.0.0', public: 'myhost.test', - webSocketURL: { - path: '/foo/test/bar/', + client: { + webSocketURL: { + path: '/foo/test/bar/', + }, }, }; diff --git a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 index 077de4ac31..eb5c919c00 100644 --- a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 +++ b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4 @@ -41,7 +41,10 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "webSocketURL": Object {}, + "webSocketURL": Object { + "host": "my.host", + "port": 9000, + }, }, "compress": true, "devMiddleware": Object {}, @@ -68,10 +71,6 @@ Object { }, "type": "ws", }, - "webSocketURL": Object { - "host": "my.host", - "port": 9000, - }, } `; @@ -80,7 +79,9 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "webSocketURL": Object {}, + "webSocketURL": Object { + "path": "/custom/path/", + }, }, "compress": true, "devMiddleware": Object {}, @@ -107,9 +108,6 @@ Object { }, "type": "ws", }, - "webSocketURL": Object { - "path": "/custom/path/", - }, } `; @@ -118,7 +116,9 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "webSocketURL": Object {}, + "webSocketURL": Object { + "path": "custom/path", + }, }, "compress": true, "devMiddleware": Object {}, @@ -145,9 +145,6 @@ Object { }, "type": "ws", }, - "webSocketURL": Object { - "path": "custom/path", - }, } `; diff --git a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 index 077de4ac31..eb5c919c00 100644 --- a/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 +++ b/test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack5 @@ -41,7 +41,10 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "webSocketURL": Object {}, + "webSocketURL": Object { + "host": "my.host", + "port": 9000, + }, }, "compress": true, "devMiddleware": Object {}, @@ -68,10 +71,6 @@ Object { }, "type": "ws", }, - "webSocketURL": Object { - "host": "my.host", - "port": 9000, - }, } `; @@ -80,7 +79,9 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "webSocketURL": Object {}, + "webSocketURL": Object { + "path": "/custom/path/", + }, }, "compress": true, "devMiddleware": Object {}, @@ -107,9 +108,6 @@ Object { }, "type": "ws", }, - "webSocketURL": Object { - "path": "/custom/path/", - }, } `; @@ -118,7 +116,9 @@ Object { "client": Object { "hotEntry": true, "overlay": true, - "webSocketURL": Object {}, + "webSocketURL": Object { + "path": "custom/path", + }, }, "compress": true, "devMiddleware": Object {}, @@ -145,9 +145,6 @@ Object { }, "type": "ws", }, - "webSocketURL": Object { - "path": "custom/path", - }, } `; diff --git a/test/server/utils/normalizeOptions.test.js b/test/server/utils/normalizeOptions.test.js index 4df2a057cb..cb655712e8 100644 --- a/test/server/utils/normalizeOptions.test.js +++ b/test/server/utils/normalizeOptions.test.js @@ -73,9 +73,11 @@ describe('normalizeOptions', () => { title: 'client host and port', multiCompiler: false, options: { - webSocketURL: { - host: 'my.host', - port: 9000, + client: { + webSocketURL: { + host: 'my.host', + port: 9000, + }, }, }, optionsResults: null, @@ -84,8 +86,10 @@ describe('normalizeOptions', () => { title: 'client path', multiCompiler: false, options: { - webSocketURL: { - path: '/custom/path/', + client: { + webSocketURL: { + path: '/custom/path/', + }, }, }, optionsResults: null, @@ -94,8 +98,10 @@ describe('normalizeOptions', () => { title: 'client path without leading/ending slashes', multiCompiler: false, options: { - webSocketURL: { - path: 'custom/path', + client: { + webSocketURL: { + path: 'custom/path', + }, }, }, optionsResults: null, From 90e50365557a74ed40f7ca494c0b293e2c066dcf Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Mon, 24 May 2021 21:44:23 +0530 Subject: [PATCH 08/19] fix: improve webSocketURL --- lib/options.json | 3 ++- lib/utils/DevServerPlugin.js | 26 ++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/options.json b/lib/options.json index bb2363f2a7..daa3190b2d 100644 --- a/lib/options.json +++ b/lib/options.json @@ -287,6 +287,7 @@ }, { "type": "object", + "additionalProperties": false, "properties": { "host": { "type": "string", @@ -302,7 +303,7 @@ "type": "number" } ], - "description": "Tells clients connected to devServer to use the provided path to connect." + "description": "Tells clients connected to devServer to use the provided port." } } } diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index 397d23f28f..ef0c2e5217 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -35,10 +35,17 @@ class DevServerPlugin { // TODO show warning about this const isSockJSType = options.webSocketServer.type === 'sockjs'; - let webSocketURL = ''; + /** @type {string} */ + let clientEntry; + + /** @type {string} */ + const logging = + options.client && options.client.logging + ? `&logging=${options.client.logging}` + : ''; if (typeof options.client.webSocketURL === 'string') { - webSocketURL = options.client.webSocketURL; + clientEntry = options.client.webSocketURL; } else if (typeof options.client.webSocketURL === 'object') { /** @type {string} */ let host = ''; @@ -72,20 +79,11 @@ class DevServerPlugin { path = `&path=${options.webSocketServer.options.path}`; } - webSocketURL = `${host}${path}${port}`; + clientEntry = `${require.resolve( + '../../client/index.js' + )}?${domain}${host}${path}${port}${logging}`; } - /** @type {string} */ - const logging = - options.client && options.client.logging - ? `&logging=${options.client.logging}` - : ''; - - /** @type {string} */ - const clientEntry = `${require.resolve( - '../../client/index.js' - )}?${domain}${webSocketURL}${logging}`; - /** @type {(string[] | string)} */ let hotEntry; From 1f2c8268af38679823033083536f7b9f8dab05a6 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Mon, 24 May 2021 22:00:53 +0530 Subject: [PATCH 09/19] fix: improve webSocketURL --- test/__snapshots__/validate-options.test.js.snap.webpack4 | 8 ++++---- test/__snapshots__/validate-options.test.js.snap.webpack5 | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4 index 53ff152896..cfdb8a5fb4 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack4 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -106,19 +106,19 @@ 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":""}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port?, … } + string | object { host?, path?, port? } Details: * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided path to connect." + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port?, … } + string | object { host?, path?, port? } Details: * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided path to connect." + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 index 53ff152896..cfdb8a5fb4 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack5 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -106,19 +106,19 @@ 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":""}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port?, … } + string | object { host?, path?, port? } Details: * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided path to connect." + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port?, … } + string | object { host?, path?, port? } Details: * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided path to connect." + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` From 162923df7971705c82d22ad36949d9eddaa8823f Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Mon, 24 May 2021 22:46:42 +0530 Subject: [PATCH 10/19] fix: improve webSocketURL --- lib/utils/DevServerPlugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index ef0c2e5217..6d3fbeda03 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -36,7 +36,7 @@ class DevServerPlugin { const isSockJSType = options.webSocketServer.type === 'sockjs'; /** @type {string} */ - let clientEntry; + let clientEntry = ''; /** @type {string} */ const logging = From 47162cb8ef6f5513d35f68ddf06fcde18001b9cd Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 25 May 2021 11:09:40 +0530 Subject: [PATCH 11/19] chore: rm public --- .../cli/public-protocol/webpack.config.js | 4 +++- lib/Server.js | 8 ++++---- lib/utils/createDomain.js | 8 ++++---- test/e2e/ClientOptions.test.js | 7 ++----- test/server/Server.test.js | 20 ++++++++++++++----- test/server/utils/createDomain.test.js | 8 ++++++-- 6 files changed, 34 insertions(+), 21 deletions(-) diff --git a/examples/cli/public-protocol/webpack.config.js b/examples/cli/public-protocol/webpack.config.js index 9e557cd40a..12c1fbc509 100644 --- a/examples/cli/public-protocol/webpack.config.js +++ b/examples/cli/public-protocol/webpack.config.js @@ -9,7 +9,9 @@ module.exports = setup({ entry: './app.js', devServer: { host: '0.0.0.0', - public: 'https://localhost:8080', + client: { + webSocketURL: 'https://localhost:8080', + }, firewall: false, }, }); diff --git a/lib/Server.js b/lib/Server.js index 43b88a71e1..cb015ada4e 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -970,12 +970,12 @@ class Server { } // also allow public hostname if provided - if (typeof this.options.public === 'string') { - const idxPublic = this.options.public.indexOf(':'); + if (typeof this.options.client.webSocketURL === 'string') { + const idxPublic = this.options.client.webSocketURL.indexOf(':'); const publicHostname = idxPublic >= 0 - ? this.options.public.substr(0, idxPublic) - : this.options.public; + ? this.options.client.webSocketURL.substr(0, idxPublic) + : this.options.client.webSocketURL; if (hostname === publicHostname) { return true; diff --git a/lib/utils/createDomain.js b/lib/utils/createDomain.js index 58b6523e84..fc8d4a87e9 100644 --- a/lib/utils/createDomain.js +++ b/lib/utils/createDomain.js @@ -18,10 +18,10 @@ function createDomain(options, server) { // use explicitly defined public url // (prefix with protocol if not explicitly given) - if (options.public) { - return /^[a-zA-Z]+:\/\//.test(options.public) - ? `${options.public}` - : `${protocol}://${options.public}`; + if (typeof options.client.webSocketURL === 'string') { + return /^[a-zA-Z]+:\/\//.test(options.client.webSocketURL) + ? `${options.client.webSocketURL}` + : `${protocol}://${options.client.webSocketURL}`; } // the formatted domain (url without path) of the webpack server diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/ClientOptions.test.js index c0372c7cea..d1982cea45 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/ClientOptions.test.js @@ -38,7 +38,7 @@ for (const webSocketServerType of webSocketServerTypes) { }); }; - describe.only(`should work behind proxy, when hostnames are same and ports are different (${webSocketServerType})`, () => { + describe(`should work behind proxy, when hostnames are same and ports are different (${webSocketServerType})`, () => { const devServerHost = '127.0.0.1'; const devServerPort = port1; const proxyHost = devServerHost; @@ -393,11 +393,8 @@ for (const webSocketServerType of webSocketServerTypes) { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', - public: 'myhost.test', client: { - webSocketURL: { - path: '/foo/test/bar/', - }, + webSocketURL: `myhost.test:${port2}/foo/test/bar/`, }, }; diff --git a/test/server/Server.test.js b/test/server/Server.test.js index d192bca202..3e98dde079 100644 --- a/test/server/Server.test.js +++ b/test/server/Server.test.js @@ -302,7 +302,9 @@ describe('Server', () => { it('should always allow any host if options.firewall is disabled', () => { const options = { - public: 'test.host:80', + client: { + webSocketURL: 'test.host:80', + }, firewall: false, }; @@ -319,7 +321,9 @@ describe('Server', () => { it('should allow any valid options.public when host is localhost', () => { const options = { - public: 'test.host:80', + client: { + webSocketURL: 'test.host:80', + }, }; const headers = { host: 'localhost', @@ -332,7 +336,9 @@ describe('Server', () => { it('should allow any valid options.public when host is 127.0.0.1', () => { const options = { - public: 'test.host:80', + client: { + webSocketURL: 'test.host:80', + }, }; const headers = { @@ -371,7 +377,9 @@ describe('Server', () => { it("should not allow hostnames that don't match options.public", () => { const options = { - public: 'test.host:80', + client: { + webSocketURL: 'test.host:80', + }, }; const headers = { @@ -387,7 +395,9 @@ describe('Server', () => { it('should allow urls with scheme for checking origin', () => { const options = { - public: 'test.host:80', + client: { + webSocketURL: 'test.host:80', + }, }; const headers = { origin: 'https://test.host', diff --git a/test/server/utils/createDomain.test.js b/test/server/utils/createDomain.test.js index ba28792255..9aa4c489e9 100644 --- a/test/server/utils/createDomain.test.js +++ b/test/server/utils/createDomain.test.js @@ -57,7 +57,9 @@ describe('createDomain', () => { options: { host: 'localhost', port: port1, - public: 'myhost.test', + client: { + webSocketURL: 'myhost.test', + }, }, expected: ['http://myhost.test'], }, @@ -75,7 +77,9 @@ describe('createDomain', () => { options: { host: 'localhost', port: port1, - public: 'https://myhost.test', + client: { + webSocketURL: 'https://myhost.test', + }, }, expected: ['https://myhost.test'], }, From bddeaa16fd43ffc511faae5b85723e470b47de73 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 25 May 2021 12:19:49 +0530 Subject: [PATCH 12/19] fix: test --- test/server/utils/createDomain.test.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/server/utils/createDomain.test.js b/test/server/utils/createDomain.test.js index 9aa4c489e9..f3b20060c2 100644 --- a/test/server/utils/createDomain.test.js +++ b/test/server/utils/createDomain.test.js @@ -68,7 +68,9 @@ describe('createDomain', () => { options: { host: 'localhost', port: port1, - public: `myhost.test:${port2}`, + client: { + webSocketURL: `myhost.test:${port2}`, + }, }, expected: [`http://myhost.test:${port2}`], }, @@ -88,7 +90,9 @@ describe('createDomain', () => { options: { host: 'localhost', port: port1, - public: `https://myhost.test:${port2}`, + client: { + webSocketURL: `https://myhost.test:${port2}`, + }, }, expected: [`https://myhost.test:${port2}`], }, From be14e573074caf37ce2279c38a1cf41b879479ba Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 25 May 2021 17:01:41 +0300 Subject: [PATCH 13/19] refactor: code --- client-src/utils/createSocketURL.js | 21 +-- client-src/utils/parseURL.js | 17 ++- examples/cli/public-protocol/app.js | 6 - .../{public => web-socket-url-cli}/README.md | 8 +- .../cli/{public => web-socket-url-cli}/app.js | 0 .../webpack.config.js | 0 .../README.md | 0 examples/cli/web-socket-url/app.js | 6 + .../index.html | 0 .../webpack.config.js | 2 +- lib/Server.js | 14 +- lib/options.json | 23 ++- lib/utils/DevServerPlugin.js | 134 ++++++++++++------ lib/utils/createDomain.js | 31 ---- lib/utils/normalizeOptions.js | 8 ++ .../validate-options.test.js.snap.webpack4 | 28 ++-- .../validate-options.test.js.snap.webpack5 | 28 ++-- test/e2e/Client.test.js | 11 +- test/e2e/ClientOptions.test.js | 12 +- test/e2e/DevServer.test.js | 4 +- test/ports-map.js | 1 - test/server/Server.test.js | 39 +++-- .../Server.test.js.snap.webpack4 | 12 +- .../Server.test.js.snap.webpack5 | 12 +- test/server/utils/createDomain.test.js | 123 ---------------- test/validate-options.test.js | 18 +-- 26 files changed, 224 insertions(+), 334 deletions(-) delete mode 100644 examples/cli/public-protocol/app.js rename examples/cli/{public => web-socket-url-cli}/README.md (67%) rename examples/cli/{public => web-socket-url-cli}/app.js (100%) rename examples/cli/{public => web-socket-url-cli}/webpack.config.js (100%) rename examples/cli/{public-protocol => web-socket-url}/README.md (100%) create mode 100644 examples/cli/web-socket-url/app.js rename examples/cli/{public-protocol => web-socket-url}/index.html (100%) rename examples/cli/{public-protocol => web-socket-url}/webpack.config.js (87%) delete mode 100644 lib/utils/createDomain.js delete mode 100644 test/server/utils/createDomain.test.js diff --git a/client-src/utils/createSocketURL.js b/client-src/utils/createSocketURL.js index 40e8cc4970..880e27db9b 100644 --- a/client-src/utils/createSocketURL.js +++ b/client-src/utils/createSocketURL.js @@ -7,14 +7,6 @@ const url = require('url'); function createSocketURL(parsedURL) { let { auth, hostname, protocol, port } = parsedURL; - const getURLSearchParam = (name) => { - if (parsedURL.searchParams) { - return parsedURL.searchParams.get(name); - } - - return parsedURL.query && parsedURL.query[name]; - }; - // Node.js module parses it as `::` // `new URL(urlString, [baseURLstring])` parses it as '[::]' const isInAddrAny = @@ -66,22 +58,21 @@ function createSocketURL(parsedURL) { // // All of these sock url params are optionally passed in through resourceQuery, // so we need to fall back to the default if they are not provided - const socketURLHostname = ( - getURLSearchParam('host') || - hostname || - 'localhost' - ).replace(/^\[(.*)\]$/, '$1'); + const socketURLHostname = (hostname || 'localhost').replace( + /^\[(.*)\]$/, + '$1' + ); if (!port || port === '0') { port = self.location.port; } - const socketURLPort = getURLSearchParam('port') || port; + const socketURLPort = port; // If path is provided it'll be passed in via the resourceQuery as a // query param so it has to be parsed out of the querystring in order for the // client to open the socket to the correct location. - const socketURLPathname = getURLSearchParam('path') || '/ws'; + const socketURLPathname = parsedURL.pathname || '/ws'; return url.format({ protocol: socketURLProtocol, diff --git a/client-src/utils/parseURL.js b/client-src/utils/parseURL.js index da077db269..e65e52083d 100644 --- a/client-src/utils/parseURL.js +++ b/client-src/utils/parseURL.js @@ -8,13 +8,18 @@ function parseURL(resourceQuery) { if (typeof resourceQuery === 'string' && resourceQuery !== '') { // If this bundle is inlined, use the resource query to get the correct url. - // format is like `?http://0.0.0.0:8096&port=8097&host=localhost` + // for backward compatibility we supports: + // - ?ws://0.0.0.0:8096&3Flogging=info + // - ?ws%3A%2F%2F192.168.0.5%3A8080%2F%3Flogging%3Dinfo + // Also we support `http` and `https` for backward compatibility too options = url.parse( - resourceQuery - // strip leading `?` from query string to get a valid URL - .substr(1) - // replace first `&` with `?` to have a valid query string - .replace('&', '?'), + decodeURIComponent( + resourceQuery + // strip leading `?` from query string to get a valid URL + .substr(1) + // replace first `&` with `?` to have a valid query string + .replace('&', '?') + ), true ); } else { diff --git a/examples/cli/public-protocol/app.js b/examples/cli/public-protocol/app.js deleted file mode 100644 index d1a9c0496f..0000000000 --- a/examples/cli/public-protocol/app.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -const target = document.querySelector('#target'); - -target.innerHTML = - 'Please check the sockjs-info request in devtools, it should try to connect to the protocol + server defined in the public setting.'; diff --git a/examples/cli/public/README.md b/examples/cli/web-socket-url-cli/README.md similarity index 67% rename from examples/cli/public/README.md rename to examples/cli/web-socket-url-cli/README.md index f6f654bbe2..650fec3905 100644 --- a/examples/cli/public/README.md +++ b/examples/cli/web-socket-url-cli/README.md @@ -1,14 +1,14 @@ -# CLI: Public Option +# CLI: Web Socket URL ```console -npx webpack serve --open-target --host 0.0.0.0 --public :8080 +npx webpack serve --open-target --host 0.0.0.0 --web-socket-url :8080 ``` _NOTE: replace `` with your local IP Address._ In order to make the server publicly accessible the client needs to know with what host to connect to the server. If `--host 0.0.0.0` is given, the client -would try to connect to `0.0.0.0`. With the `--public` option it is possible to +would try to connect to `0.0.0.0`. With the `--web-socket-url` options it is possible to override this. ## What Should Happen @@ -18,4 +18,4 @@ override this. 3. Open the console in your browser's devtools. 4. Select the 'Network' tab. 5. Select the 'WS' or 'WebSockets' sub-tab. -6. Verify that the WebSocket is connecting to `:8080`. +6. Verify that the WebSocket is connecting to `:8080`. diff --git a/examples/cli/public/app.js b/examples/cli/web-socket-url-cli/app.js similarity index 100% rename from examples/cli/public/app.js rename to examples/cli/web-socket-url-cli/app.js diff --git a/examples/cli/public/webpack.config.js b/examples/cli/web-socket-url-cli/webpack.config.js similarity index 100% rename from examples/cli/public/webpack.config.js rename to examples/cli/web-socket-url-cli/webpack.config.js diff --git a/examples/cli/public-protocol/README.md b/examples/cli/web-socket-url/README.md similarity index 100% rename from examples/cli/public-protocol/README.md rename to examples/cli/web-socket-url/README.md diff --git a/examples/cli/web-socket-url/app.js b/examples/cli/web-socket-url/app.js new file mode 100644 index 0000000000..5184108804 --- /dev/null +++ b/examples/cli/web-socket-url/app.js @@ -0,0 +1,6 @@ +'use strict'; + +const target = document.querySelector('#target'); + +target.innerHTML = + 'Please check the ws request in devtools, it should try to connect to the protocol + server defined in the webSocketURL setting.'; diff --git a/examples/cli/public-protocol/index.html b/examples/cli/web-socket-url/index.html similarity index 100% rename from examples/cli/public-protocol/index.html rename to examples/cli/web-socket-url/index.html diff --git a/examples/cli/public-protocol/webpack.config.js b/examples/cli/web-socket-url/webpack.config.js similarity index 87% rename from examples/cli/public-protocol/webpack.config.js rename to examples/cli/web-socket-url/webpack.config.js index 12c1fbc509..7e519e2876 100644 --- a/examples/cli/public-protocol/webpack.config.js +++ b/examples/cli/web-socket-url/webpack.config.js @@ -10,7 +10,7 @@ module.exports = setup({ devServer: { host: '0.0.0.0', client: { - webSocketURL: 'https://localhost:8080', + webSocketURL: 'ws://localhost:8080', }, firewall: false, }, diff --git a/lib/Server.js b/lib/Server.js index cb015ada4e..a09f7ab94d 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -969,17 +969,9 @@ class Server { } } - // also allow public hostname if provided - if (typeof this.options.client.webSocketURL === 'string') { - const idxPublic = this.options.client.webSocketURL.indexOf(':'); - const publicHostname = - idxPublic >= 0 - ? this.options.client.webSocketURL.substr(0, idxPublic) - : this.options.client.webSocketURL; - - if (hostname === publicHostname) { - return true; - } + // Also allow if `client.webSocketURL.host` provided + if (typeof this.options.client.webSocketURL !== 'undefined') { + return this.options.client.webSocketURL.host === hostname; } // disallow diff --git a/lib/options.json b/lib/options.json index daa3190b2d..f8fb2eb120 100644 --- a/lib/options.json +++ b/lib/options.json @@ -283,7 +283,8 @@ "webSocketURL": { "anyOf": [ { - "type": "string" + "type": "string", + "minLength": 1 }, { "type": "object", @@ -291,23 +292,21 @@ "properties": { "host": { "type": "string", + "minLength": 1, "description": "Tells clients connected to devServer to use the provided host." }, + "port": { + "type": "number", + "description": "Tells clients connected to devServer to use the provided port." + }, "path": { "type": "string", "description": "Tells clients connected to devServer to use the provided path to connect." - }, - "port": { - "anyOf": [ - { - "type": "number" - } - ], - "description": "Tells clients connected to devServer to use the provided port." } } } - ] + ], + "description": "When using dev server and you're proxying dev-server, the client script does not always know where to connect to." } }, "description": "Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient", @@ -547,10 +546,6 @@ ], "description": "Proxying some URLs can be useful when you have a separate API backend development server and you want to send API requests on the same domain. https://webpack.js.org/configuration/dev-server/#devserverproxy" }, - "public": { - "type": "string", - "description": "When using dev server and you're proxying dev-server, the client script does not always know where to connect to. It will try to guess the URL of the server based on window.location, but if that fails you'll need to use this. https://webpack.js.org/configuration/dev-server/#devserverpublic" - }, "setupExitSignals": { "type": "boolean", "description": "It takes a boolean and if true (default on CLI), the server will close and exit the process on SIGINT and SIGTERM. https://webpack.js.org/configuration/dev-server/#devserversetupexitsignals" diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index 6d3fbeda03..97ccc8fd87 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -1,7 +1,6 @@ 'use strict'; const webpack = require('webpack'); -const createDomain = require('./createDomain'); const getSocketClientPath = require('./getSocketClientPath'); // @ts-ignore @@ -28,62 +27,107 @@ class DevServerPlugin { apply(compiler) { const { options } = this; + /** @type {"ws" | "wss"} */ + const protocol = options.https ? 'wss' : 'ws'; + /** @type {string} */ - const domain = createDomain(options); + let host; // SockJS is not supported server mode, so `host` and `port` can't specified, let's ignore them // TODO show warning about this const isSockJSType = options.webSocketServer.type === 'sockjs'; - /** @type {string} */ - let clientEntry = ''; + // We are proxying dev server and need to specify custom `host` + if (typeof options.client.webSocketURL.host !== 'undefined') { + host = options.client.webSocketURL.host; + } + // Web socket server works on custom `host`, only for `ws` because `sock-js` is not support custom `host` + else if ( + typeof options.webSocketServer.options.host !== 'undefined' && + !isSockJSType + ) { + host = options.webSocketServer.options.host; + } + // The `host` option is specified + else if (typeof this.options.host !== 'undefined') { + host = this.options.host; + } + // The `port` option is not specified + else { + host = '0.0.0.0'; + } - /** @type {string} */ - const logging = - options.client && options.client.logging - ? `&logging=${options.client.logging}` - : ''; - - if (typeof options.client.webSocketURL === 'string') { - clientEntry = options.client.webSocketURL; - } else if (typeof options.client.webSocketURL === 'object') { - /** @type {string} */ - let host = ''; - - if (options.client.webSocketURL.host) { - host = `&host=${options.client.webSocketURL.host}`; - } else if (options.webSocketServer.options.host && !isSockJSType) { - host = `&host=${options.webSocketServer.options.host}`; - } + /** @type {number | string} */ + let port; - /** @type {string} */ - let port = ''; - - if (options.client.webSocketURL.port) { - port = `&port=${options.client.webSocketURL.port}`; - } else if (options.webSocketServer.options.port && !isSockJSType) { - port = `&port=${options.webSocketServer.options.port}`; - } else if (options.port) { - port = `&port=${options.port}`; - } else { - port = ''; - } + // We are proxying dev server and need to specify custom `port` + if (typeof options.client.webSocketURL.port !== 'undefined') { + port = options.client.webSocketURL.port; + } + // Web socket server works on custom `port`, only for `ws` because `sock-js` is not support custom `port` + else if ( + typeof options.webSocketServer.options.port !== 'undefined' && + !isSockJSType + ) { + port = options.webSocketServer.options.port; + } + // The `port` option is specified + else if (typeof options.port === 'number') { + port = options.port; + } + // The `port` option is specified using `string` + else if (typeof options.port === 'string' && options.port !== 'auto') { + port = Number(options.port); + } + // The `port` option is not specified or set to `auto` + else { + port = 0; + } - /** @type {string} */ - let path = ''; + /** @type {string} */ + let path = ''; - // Only add the path if it is not default - if (options.client.webSocketURL.path) { - path = `&path=${options.client.webSocketURL.path}`; - } else if (options.webSocketServer.options.path) { - path = `&path=${options.webSocketServer.options.path}`; - } + // We are proxying dev server and need to specify custom `path` + if (typeof options.client.webSocketURL.path !== 'undefined') { + path = options.client.webSocketURL.path; + } + // Web socket server works on custom `path` + else if ( + typeof options.webSocketServer.options.prefix !== 'undefined' || + typeof options.webSocketServer.options.path !== 'undefined' + ) { + path = + options.webSocketServer.options.prefix || + options.webSocketServer.options.path; + } - clientEntry = `${require.resolve( - '../../client/index.js' - )}?${domain}${host}${path}${port}${logging}`; + /** @type {Record} */ + const searchParams = {}; + + if (typeof options.client.logging !== 'undefined') { + searchParams.logging = options.client.logging; } + const webSocketURL = encodeURIComponent( + new URL( + `${protocol}://${host}${port ? `:${port}` : ''}${path || '/'}${ + Object.keys(searchParams).length > 0 + ? `?${Object.entries(searchParams) + .map(([key, value]) => `${key}=${value}`) + .join('&')}` + : '' + }` + ).toString() + ).replace( + /[!'()*]/g, + (character) => `%${character.charCodeAt(0).toString(16)}` + ); + + /** @type {string} */ + const clientEntry = `${require.resolve( + '../../client/index.js' + )}?${webSocketURL}`; + /** @type {(string[] | string)} */ let hotEntry; @@ -123,11 +167,13 @@ class DevServerPlugin { // make sure that we do not add duplicates. /** @type {Entry} */ const entriesClone = additionalEntries.slice(0); + [].concat(originalEntry).forEach((newEntry) => { if (!entriesClone.includes(newEntry)) { entriesClone.push(newEntry); } }); + return entriesClone; }; diff --git a/lib/utils/createDomain.js b/lib/utils/createDomain.js deleted file mode 100644 index fc8d4a87e9..0000000000 --- a/lib/utils/createDomain.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -const url = require('url'); - -function createDomain(options, server) { - const protocol = options.https ? 'https' : 'http'; - // use location hostname and port by default in createSocketURL - // ipv6 detection is not required as 0.0.0.0 is just used as a placeholder - let hostname; - - if (server) { - hostname = server.address().address; - } else { - hostname = '0.0.0.0'; - } - - const port = server ? server.address().port : 0; - - // use explicitly defined public url - // (prefix with protocol if not explicitly given) - if (typeof options.client.webSocketURL === 'string') { - return /^[a-zA-Z]+:\/\//.test(options.client.webSocketURL) - ? `${options.client.webSocketURL}` - : `${protocol}://${options.client.webSocketURL}`; - } - - // the formatted domain (url without path) of the webpack server - return url.format({ protocol, hostname, port }); -} - -module.exports = createDomain; diff --git a/lib/utils/normalizeOptions.js b/lib/utils/normalizeOptions.js index f92802d566..e6ef52c086 100644 --- a/lib/utils/normalizeOptions.js +++ b/lib/utils/normalizeOptions.js @@ -106,6 +106,14 @@ function normalizeOptions(compiler, options, logger) { if (typeof options.client.webSocketURL === 'undefined') { options.client.webSocketURL = {}; + } else if (typeof options.client.webSocketURL === 'string') { + const parsedURL = new URL(options.client.webSocketURL); + + options.client.webSocketURL = { + host: parsedURL.hostname, + port: parsedURL.port, + path: parsedURL.pathname, + }; } // Enable client overlay by default diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4 index cfdb8a5fb4..1aa6a376e2 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack4 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -91,9 +91,15 @@ exports[`options validate should throw an error on the "client" option with '{"u -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"host":""}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL.host should be an non-empty string. + -> Tells clients connected to devServer to use the provided host." +`; + exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"host":true,"path":"","port":8080}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.webSocketURL.host should be a string. + - configuration.client.webSocketURL.host should be a non-empty string. -> Tells clients connected to devServer to use the provided host." `; @@ -105,20 +111,14 @@ 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":""}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port? } - Details: - * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided port." + - configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port? } - Details: - * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided port." + - configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` @@ -427,12 +427,6 @@ exports[`options validate should throw an error on the "proxy" option with 'func [object { … } | function, ...] (should not have fewer than 1 item)" `; -exports[`options validate should throw an error on the "public" option with 'false' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.public should be a string. - -> When using dev server and you're proxying dev-server, the client script does not always know where to connect to. It will try to guess the URL of the server based on window.location, but if that fails you'll need to use this. https://webpack.js.org/configuration/dev-server/#devserverpublic" -`; - exports[`options validate should throw an error on the "static" option with '' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.static should be an non-empty string." diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 index cfdb8a5fb4..1aa6a376e2 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack5 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -91,9 +91,15 @@ exports[`options validate should throw an error on the "client" option with '{"u -> Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient" `; +exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"host":""}}' value 1`] = ` +"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. + - configuration.client.webSocketURL.host should be an non-empty string. + -> Tells clients connected to devServer to use the provided host." +`; + exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"host":true,"path":"","port":8080}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.webSocketURL.host should be a string. + - configuration.client.webSocketURL.host should be a non-empty string. -> Tells clients connected to devServer to use the provided host." `; @@ -105,20 +111,14 @@ 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":""}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port? } - Details: - * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided port." + - configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.client.webSocketURL should be one of these: - string | object { host?, path?, port? } - Details: - * configuration.client.webSocketURL.port should be a number. - -> Tells clients connected to devServer to use the provided port." + - configuration.client.webSocketURL.port should be a number. + -> Tells clients connected to devServer to use the provided port." `; exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = ` @@ -427,12 +427,6 @@ exports[`options validate should throw an error on the "proxy" option with 'func [object { … } | function, ...] (should not have fewer than 1 item)" `; -exports[`options validate should throw an error on the "public" option with 'false' value 1`] = ` -"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.public should be a string. - -> When using dev server and you're proxying dev-server, the client script does not always know where to connect to. It will try to guess the URL of the server based on window.location, but if that fails you'll need to use this. https://webpack.js.org/configuration/dev-server/#devserverpublic" -`; - exports[`options validate should throw an error on the "static" option with '' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration.static should be an non-empty string." diff --git a/test/e2e/Client.test.js b/test/e2e/Client.test.js index 798a43f300..c9e9796823 100644 --- a/test/e2e/Client.test.js +++ b/test/e2e/Client.test.js @@ -27,12 +27,19 @@ describe('reload', () => { shouldRefresh: false, }, { - title: 'hot with transportMode.client sockjs', + title: 'hot with sockjs websocket server', options: { webSocketServer: 'sockjs', }, shouldRefresh: false, }, + { + title: 'hot with ws websocket server', + options: { + webSocketServer: 'ws', + }, + shouldRefresh: false, + }, { title: 'reload without hot', options: { @@ -88,6 +95,7 @@ describe('reload', () => { .then((color) => { page.setRequestInterception(true).then(() => { page.on('request', (req) => { + console.log(req.url()); if ( req.isNavigationRequest() && req.frame() === page.mainFrame() && @@ -95,6 +103,7 @@ describe('reload', () => { ) { refreshed = true; } + req.continue(); }); page.waitForTimeout(reloadReadyDelay).then(() => { diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/ClientOptions.test.js index d1982cea45..9adfcfe5e6 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/ClientOptions.test.js @@ -93,7 +93,7 @@ for (const webSocketServerType of webSocketServerTypes) { runBrowser().then(async ({ page, browser }) => { waitForTest(browser, page, /ws/, (websocketUrl) => { expect(websocketUrl).toContain( - `${websocketUrlProtocol}://${proxyHost}:${devServerPort}/ws` + `${websocketUrlProtocol}://${devServerHost}:${devServerPort}/ws` ); done(); @@ -160,7 +160,7 @@ for (const webSocketServerType of webSocketServerTypes) { runBrowser().then(async ({ page, browser }) => { waitForTest(browser, page, /ws/, (websocketUrl) => { expect(websocketUrl).toContain( - `${websocketUrlProtocol}://${proxyHost}:${proxyPort}/ws` + `${websocketUrlProtocol}://${devServerHost}:${devServerPort}/ws` ); done(); @@ -281,7 +281,7 @@ for (const webSocketServerType of webSocketServerTypes) { }); }); - describe('should work with custom client port and without path', () => { + describe('should work with custom client port', () => { beforeAll((done) => { const options = { webSocketServer: webSocketServerType, @@ -316,7 +316,7 @@ for (const webSocketServerType of webSocketServerTypes) { }); }); - describe('should work with custom client', () => { + describe('should work with custom client host', () => { beforeAll((done) => { const options = { webSocketServer: webSocketServerType, @@ -387,14 +387,14 @@ for (const webSocketServerType of webSocketServerTypes) { }); }); - describe('should work with the "public" option and custom client path', () => { + describe('should work with the "client.webSocketURL" option and custom client path', () => { beforeAll((done) => { const options = { webSocketServer: webSocketServerType, port: port2, host: '0.0.0.0', client: { - webSocketURL: `myhost.test:${port2}/foo/test/bar/`, + webSocketURL: `ws://myhost.test:${port2}/foo/test/bar/`, }, }; diff --git a/test/e2e/DevServer.test.js b/test/e2e/DevServer.test.js index 87e14c269d..dd09b3ff7a 100644 --- a/test/e2e/DevServer.test.js +++ b/test/e2e/DevServer.test.js @@ -96,7 +96,7 @@ describe('DevServer', () => { testBin(null, './test/fixtures/dev-server/client-default-path-config.js') .then((output) => { expect(output.exitCode).toEqual(0); - expect(output.stdout).toContain('&path=/ws'); + expect(output.stdout).toContain('ws%3A%2F%2F0.0.0.0%2Fws'); done(); }) .catch(done); @@ -106,7 +106,7 @@ describe('DevServer', () => { testBin(null, './test/fixtures/dev-server/client-custom-path-config.js') .then((output) => { expect(output.exitCode).toEqual(0); - expect(output.stdout).toContain('&path=/custom/path'); + expect(output.stdout).toContain('ws%3A%2F%2F0.0.0.0%2Fcustom%2Fpath'); done(); }) .catch(done); diff --git a/test/ports-map.js b/test/ports-map.js index 6094b0d8f5..020d25bd2f 100644 --- a/test/ports-map.js +++ b/test/ports-map.js @@ -12,7 +12,6 @@ const portsList = { UniversalCompiler: 1, Server: 1, routes: 1, - createDomain: 2, 'onAfterSetupMiddleware-option': 1, 'onBeforeSetupMiddleware-option': 1, 'compress-option': 1, diff --git a/test/server/Server.test.js b/test/server/Server.test.js index 3e98dde079..aff3f96cf1 100644 --- a/test/server/Server.test.js +++ b/test/server/Server.test.js @@ -303,7 +303,7 @@ describe('Server', () => { it('should always allow any host if options.firewall is disabled', () => { const options = { client: { - webSocketURL: 'test.host:80', + webSocketURL: 'ws://test.host:80', }, firewall: false, }; @@ -319,10 +319,10 @@ describe('Server', () => { } }); - it('should allow any valid options.public when host is localhost', () => { + it('should allow any valid options.client.webSocketURL when host is localhost', () => { const options = { client: { - webSocketURL: 'test.host:80', + webSocketURL: 'ws://test.host:80', }, }; const headers = { @@ -334,10 +334,10 @@ describe('Server', () => { } }); - it('should allow any valid options.public when host is 127.0.0.1', () => { + it('should allow any valid options.client.webSocketURL when host is 127.0.0.1', () => { const options = { client: { - webSocketURL: 'test.host:80', + webSocketURL: 'ws://test.host:80', }, }; @@ -375,10 +375,10 @@ describe('Server', () => { }); }); - it("should not allow hostnames that don't match options.public", () => { + it("should not allow hostnames that don't match options.client.webSocketURL", () => { const options = { client: { - webSocketURL: 'test.host:80', + webSocketURL: 'ws://test.host:80', }, }; @@ -393,16 +393,37 @@ describe('Server', () => { } }); - it('should allow urls with scheme for checking origin', () => { + it('should allow urls with scheme for checking origin when the "option.client.webSocketURL" is string', () => { const options = { client: { - webSocketURL: 'test.host:80', + webSocketURL: 'ws://test.host:80', }, }; const headers = { origin: 'https://test.host', }; + server = createServer(compiler, options); + + if (!server.checkOrigin(headers)) { + throw new Error("Validation didn't fail"); + } + }); + + it('should allow urls with scheme for checking origin when the "option.client.webSocketURL" is object', () => { + const options = { + client: { + webSocketURL: { + host: 'test.host', + }, + }, + }; + const headers = { + origin: 'https://test.host', + }; + + server = createServer(compiler, options); + if (!server.checkOrigin(headers)) { throw new Error("Validation didn't fail"); } diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack4 b/test/server/__snapshots__/Server.test.js.snap.webpack4 index 9cc203a7a1..e3ad8cea6e 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack4 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack4 @@ -4,9 +4,7 @@ exports[`Server DevServerPlugin add hot option 1`] = ` Array [ Array [ "client", - "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", ], Array [ "node_modules", @@ -24,9 +22,7 @@ exports[`Server DevServerPlugin add hot-only option 1`] = ` Array [ Array [ "client", - "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", ], Array [ "node_modules", @@ -44,9 +40,7 @@ exports[`Server DevServerPlugin should create and run server with old parameters Array [ Array [ "client", - "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", ], Array [ "node_modules", diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack5 b/test/server/__snapshots__/Server.test.js.snap.webpack5 index 9cc203a7a1..e3ad8cea6e 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack5 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack5 @@ -4,9 +4,7 @@ exports[`Server DevServerPlugin add hot option 1`] = ` Array [ Array [ "client", - "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", ], Array [ "node_modules", @@ -24,9 +22,7 @@ exports[`Server DevServerPlugin add hot-only option 1`] = ` Array [ Array [ "client", - "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", ], Array [ "node_modules", @@ -44,9 +40,7 @@ exports[`Server DevServerPlugin should create and run server with old parameters Array [ Array [ "client", - "index.js?http:", - "0.0.0.0&path=", - "ws&port=8100", + "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", ], Array [ "node_modules", diff --git a/test/server/utils/createDomain.test.js b/test/server/utils/createDomain.test.js deleted file mode 100644 index f3b20060c2..0000000000 --- a/test/server/utils/createDomain.test.js +++ /dev/null @@ -1,123 +0,0 @@ -'use strict'; - -const webpack = require('webpack'); -const Server = require('../../../lib/Server'); -const createDomain = require('../../../lib/utils/createDomain'); -const [port1, port2] = require('../../ports-map').createDomain; -const config = require('./../../fixtures/simple-config/webpack.config'); - -describe('createDomain', () => { - let compiler; - let server; - - beforeEach(() => { - compiler = webpack(config); - }); - - afterEach((done) => { - server.close(done); - }); - - const tests = [ - { - name: 'default', - options: { - host: 'localhost', - port: port1, - }, - expected: [ - `http://localhost:${port1}`, - `http://127.0.0.1:${port1}`, - `http://[::1]:${port1}`, - ], - }, - { - name: 'no host option', - options: { - port: port1, - }, - expected: [`http://0.0.0.0:${port1}`, `http://[::]:${port1}`], - }, - { - name: 'https', - options: { - host: 'localhost', - port: port1, - https: true, - }, - expected: [ - `https://localhost:${port1}`, - `https://127.0.0.1:${port1}`, - `https://[::1]:${port1}`, - ], - timeout: 60000, - }, - { - name: 'override with public', - options: { - host: 'localhost', - port: port1, - client: { - webSocketURL: 'myhost.test', - }, - }, - expected: ['http://myhost.test'], - }, - { - name: 'override with public (port)', - options: { - host: 'localhost', - port: port1, - client: { - webSocketURL: `myhost.test:${port2}`, - }, - }, - expected: [`http://myhost.test:${port2}`], - }, - { - name: 'override with public (protocol)', - options: { - host: 'localhost', - port: port1, - client: { - webSocketURL: 'https://myhost.test', - }, - }, - expected: ['https://myhost.test'], - }, - { - name: 'override with public (protocol + port)', - options: { - host: 'localhost', - port: port1, - client: { - webSocketURL: `https://myhost.test:${port2}`, - }, - }, - expected: [`https://myhost.test:${port2}`], - }, - ]; - - tests.forEach((test) => { - it(`test createDomain '${test.name}'`, (done) => { - const { options, expected } = test; - options.static = false; - - server = new Server(options, compiler); - - server.listen(options.port, options.host, (err) => { - if (err) { - done(err); - } - - const domain = createDomain(options, server.server); - - if (!expected.includes(domain)) { - done(`generated domain ${domain} doesn't match expected ${expected}`); - } else { - done(); - } - }); - }); - }); -}); diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 22b73f2838..90dfe14bb0 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -83,19 +83,22 @@ const tests = { transport: require.resolve('../client/clients/SockJSClient'), }, { - webSocketURL: { host: '' }, + webSocketURL: 'ws://localhost:8080', }, { - webSocketURL: { path: '' }, + webSocketURL: { host: 'localhost' }, }, { webSocketURL: { port: 8080 }, }, { - webSocketURL: { host: '', path: '' }, + webSocketURL: { path: '' }, + }, + { + webSocketURL: { path: '/my-path/' }, }, { - webSocketURL: { host: '', path: '', port: 8080 }, + webSocketURL: { host: 'localhost', port: 8080, path: '/my-path/' }, }, ], failure: [ @@ -143,6 +146,9 @@ const tests = { { webSocketURL: { port: true }, }, + { + webSocketURL: { host: '' }, + }, { webSocketURL: { port: '' }, }, @@ -260,10 +266,6 @@ const tests = { ], failure: [[], () => {}, false], }, - public: { - success: ['', 'foo', 'auto'], - failure: [false], - }, static: { success: [ 'path', From 92402e3f82e16d598aa938caa87753042a150120 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 25 May 2021 18:03:10 +0300 Subject: [PATCH 14/19] refactor: cli flags --- bin/cli-flags.js | 10 ---------- lib/utils/DevServerPlugin.js | 5 ++++- test/cli/__snapshots__/cli.test.js.snap.webpack4 | 13 ++++++------- test/cli/__snapshots__/cli.test.js.snap.webpack5 | 2 -- test/cli/cli.test.js | 10 ++++++++-- 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/bin/cli-flags.js b/bin/cli-flags.js index 36986734b9..c500b9524b 100644 --- a/bin/cli-flags.js +++ b/bin/cli-flags.js @@ -394,16 +394,6 @@ module.exports = { negatedDescription: 'Disable gzip compression.', negative: true, }, - { - name: 'public', - type: String, - configs: [ - { - type: 'string', - }, - ], - description: 'The public hostname/ip address of the server.', - }, { name: 'firewall', type: [Boolean, String], diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index 97ccc8fd87..2df1f3e2f0 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -1,6 +1,7 @@ 'use strict'; const webpack = require('webpack'); +const ipaddr = require('ipaddr.js'); const getSocketClientPath = require('./getSocketClientPath'); // @ts-ignore @@ -110,7 +111,9 @@ class DevServerPlugin { const webSocketURL = encodeURIComponent( new URL( - `${protocol}://${host}${port ? `:${port}` : ''}${path || '/'}${ + `${protocol}://${ipaddr.IPv6.isIPv6(host) ? `[${host}]` : host}${ + port ? `:${port}` : '' + }${path || '/'}${ Object.keys(searchParams).length > 0 ? `?${Object.entries(searchParams) .map(([key, value]) => `${key}=${value}`) diff --git a/test/cli/__snapshots__/cli.test.js.snap.webpack4 b/test/cli/__snapshots__/cli.test.js.snap.webpack4 index 917825ddfd..4773f47bdb 100644 --- a/test/cli/__snapshots__/cli.test.js.snap.webpack4 +++ b/test/cli/__snapshots__/cli.test.js.snap.webpack4 @@ -197,19 +197,20 @@ Options: value. --progress [value] Print compilation progress during build. -j, --json [value] Prints result as JSON or store it in a file. - --entry The entry point(s) of your application e.g. - ./src/main.js. - -o, --output-path Output location of the file generated by - webpack e.g. ./dist/. - -t, --target Sets the build target e.g. node. -d, --devtool Determine source maps to use. --no-devtool Do not generate source maps. + --entry The entry point(s) of your application e.g. + ./src/main.js. --mode Defines the mode to pass to webpack. --name Name of the configuration. Used when loading multiple configurations. + -o, --output-path Output location of the file generated by + webpack e.g. ./dist/. --stats [value] It instructs webpack on how to treat the stats e.g. verbose. --no-stats Disable stats output. + -t, --target Sets the build target e.g. node. + --no-target Negative 'target' option. --watch-options-stdin Stop watching when stdin stream has ended. --no-watch-options-stdin Do not stop watching when stdin stream has ended. @@ -271,8 +272,6 @@ Options: Page Applications. --compress Enable gzip compression. --no-compress Disable gzip compression. - --public The public hostname/ip address of the - server. --firewall [value...] Enable firewall or set hosts that are allowed to access the dev server. --no-firewall Disable firewall. diff --git a/test/cli/__snapshots__/cli.test.js.snap.webpack5 b/test/cli/__snapshots__/cli.test.js.snap.webpack5 index ffad849682..4773f47bdb 100644 --- a/test/cli/__snapshots__/cli.test.js.snap.webpack5 +++ b/test/cli/__snapshots__/cli.test.js.snap.webpack5 @@ -272,8 +272,6 @@ Options: Page Applications. --compress Enable gzip compression. --no-compress Disable gzip compression. - --public The public hostname/ip address of the - server. --firewall [value...] Enable firewall or set hosts that are allowed to access the dev server. --no-firewall Disable firewall. diff --git a/test/cli/cli.test.js b/test/cli/cli.test.js index bc25838300..af3484bdf3 100644 --- a/test/cli/cli.test.js +++ b/test/cli/cli.test.js @@ -723,7 +723,10 @@ describe('CLI', () => { it('should exit the process when SIGINT is detected', (done) => { const cliPath = path.resolve(__dirname, '../../bin/webpack-dev-server.js'); - const examplePath = path.resolve(__dirname, '../../examples/cli/public'); + const examplePath = path.resolve( + __dirname, + '../../examples/cli/web-socket-url' + ); const cp = execa('node', [cliPath], { cwd: examplePath }); cp.stdout.on('data', (data) => { @@ -765,7 +768,10 @@ describe('CLI', () => { it('should exit the process when stdin ends if --watch-options-stdin', (done) => { const cliPath = path.resolve(__dirname, '../../bin/webpack-dev-server.js'); - const examplePath = path.resolve(__dirname, '../../examples/cli/public'); + const examplePath = path.resolve( + __dirname, + '../../examples/cli/web-socket-url' + ); const cp = execa('node', [cliPath, '--watch-options-stdin'], { cwd: examplePath, }); From e5e378a93af0a0fcc4cd50f79cb0db005ab542fa Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 25 May 2021 18:56:26 +0300 Subject: [PATCH 15/19] refactor: code --- client-src/utils/createSocketURL.js | 6 +- client-src/utils/parseURL.js | 2 + lib/utils/DevServerPlugin.js | 2 +- test/client/utils/createSocketURL.test.js | 94 +++++++------------ .../WebsocketServer.test.js.snap.webpack4 | 2 +- .../WebsocketServer.test.js.snap.webpack5 | 2 +- test/server/utils/DevServerPlugin.test.js | 8 ++ test/validate-options.test.js | 2 +- 8 files changed, 55 insertions(+), 63 deletions(-) diff --git a/client-src/utils/createSocketURL.js b/client-src/utils/createSocketURL.js index 880e27db9b..67c5cabf16 100644 --- a/client-src/utils/createSocketURL.js +++ b/client-src/utils/createSocketURL.js @@ -72,7 +72,11 @@ function createSocketURL(parsedURL) { // If path is provided it'll be passed in via the resourceQuery as a // query param so it has to be parsed out of the querystring in order for the // client to open the socket to the correct location. - const socketURLPathname = parsedURL.pathname || '/ws'; + let socketURLPathname = '/ws'; + + if (parsedURL.pathname && !parsedURL.fromCurrentScript) { + socketURLPathname = parsedURL.pathname; + } return url.format({ protocol: socketURLProtocol, diff --git a/client-src/utils/parseURL.js b/client-src/utils/parseURL.js index e65e52083d..d40db3c2b1 100644 --- a/client-src/utils/parseURL.js +++ b/client-src/utils/parseURL.js @@ -41,9 +41,11 @@ function parseURL(resourceQuery) { if (scriptSourceURL) { options = scriptSourceURL; + options.fromCurrentScript = true; } } else { options = url.parse(self.location.href, true, true); + options.fromCurrentScript = true; } } diff --git a/lib/utils/DevServerPlugin.js b/lib/utils/DevServerPlugin.js index 2df1f3e2f0..b57b132c04 100644 --- a/lib/utils/DevServerPlugin.js +++ b/lib/utils/DevServerPlugin.js @@ -50,7 +50,7 @@ class DevServerPlugin { host = options.webSocketServer.options.host; } // The `host` option is specified - else if (typeof this.options.host !== 'undefined') { + else if (typeof this.options.host !== 'undefined' && this.options.host) { host = this.options.host; } // The `port` option is not specified diff --git a/test/client/utils/createSocketURL.test.js b/test/client/utils/createSocketURL.test.js index 81ac0c3d6e..2da4114039 100644 --- a/test/client/utils/createSocketURL.test.js +++ b/test/client/utils/createSocketURL.test.js @@ -3,30 +3,35 @@ describe("'createSocketURL' function ", () => { const samples = [ // __resourceQuery, location and socket URL - ['?http://example.com', 'http://example.com', 'ws://example.com/ws'], - ['?http://example.com', 'http://something.com', 'ws://example.com/ws'], - [null, 'http://example.com', 'ws://example.com/ws'], - ['?https://example.com', 'https://example.com', 'wss://example.com/ws'], - [null, 'https://example.com', 'wss://example.com/ws'], + ['?http://example.com/ws', 'http://example.com', 'ws://example.com/ws'], [ - '?http://example.com&port=8080', - 'http://example.com:8080', - 'ws://example.com:8080/ws', + `?${encodeURIComponent('http://example.com/ws')}`, + 'http://example.com', + 'ws://example.com/ws', + ], + [ + `?${encodeURIComponent('http://example.com/ws?foo=bar')}`, + 'http://example.com', + 'ws://example.com/ws', ], + ['?http://example.com/ws', 'http://something.com', 'ws://example.com/ws'], + [null, 'http://example.com', 'ws://example.com/ws'], + ['?https://example.com/ws', 'https://example.com', 'wss://example.com/ws'], + [null, 'https://example.com', 'wss://example.com/ws'], [ - '?http://example.com:0', + '?http://example.com:0/ws', 'http://example.com:8080', 'ws://example.com:8080/ws', ], [null, 'http://example.com:8080', 'ws://example.com:8080/ws'], [ - '?http://example.com/path/foo.js', + '?http://example.com/custom-path/', 'http://example.com/foo/bar', - 'ws://example.com/ws', + 'ws://example.com/custom-path/', ], [null, 'http://example.com/foo/bar', 'ws://example.com/ws'], [ - '?http://user:password@localhost/', + '?http://user:password@localhost/ws', 'http://user:password@localhost/', 'ws://user:password@localhost/ws', ], @@ -36,7 +41,7 @@ describe("'createSocketURL' function ", () => { 'ws://user:password@localhost/ws', ], [ - '?http://user:password@localhost:8080/', + '?http://user:password@localhost:8080/ws', 'http://user:password@localhost/', 'ws://user:password@localhost:8080/ws', ], @@ -46,71 +51,44 @@ describe("'createSocketURL' function ", () => { 'http://user:password@localhost:8080/', 'ws://user:password@localhost:8080/ws', ], - ['?http://0.0.0.0', 'http://127.0.0.1', 'ws://127.0.0.1/ws'], - ['?http://0.0.0.0', 'http://192.168.0.1', 'ws://192.168.0.1/ws'], - ['?http://0.0.0.0', 'https://192.168.0.1', 'wss://192.168.0.1/ws'], - ['?http://0.0.0.0', 'https://example.com', 'wss://example.com/ws'], + ['?http://0.0.0.0/ws', 'http://127.0.0.1', 'ws://127.0.0.1/ws'], + ['?http://0.0.0.0/ws', 'http://192.168.0.1', 'ws://192.168.0.1/ws'], + ['?http://0.0.0.0/ws', 'https://192.168.0.1', 'wss://192.168.0.1/ws'], + ['?http://0.0.0.0/ws', 'https://example.com', 'wss://example.com/ws'], [ - '?http://0.0.0.0', + '?http://0.0.0.0/ws', 'https://example.com:8080', 'wss://example.com:8080/ws', ], [ - '?https://0.0.0.0', + '?https://0.0.0.0/ws', 'https://example.com:8080', 'wss://example.com:8080/ws', ], + ['?http://localhost/ws', 'http://localhost', 'ws://localhost/ws'], [ - '?http://0.0.0.0&port=9090', - 'https://example.com', - 'wss://example.com:9090/ws', - ], - [ - '?http://0.0.0.0&port=9090', - 'https://example.com:8080', - 'wss://example.com:9090/ws', - ], - ['?http://localhost', 'http://localhost', 'ws://localhost/ws'], - [ - '?http://localhost:8080', + '?http://localhost:8080/ws', 'http://localhost:8080', 'ws://localhost:8080/ws', ], [ - '?https://localhost:8080', + '?https://localhost:8080/ws', 'https://localhost:8080', 'wss://localhost:8080/ws', ], [null, 'https://localhost:8080', 'wss://localhost:8080/ws'], - ['?http://127.0.0.1', 'http://something.com', 'ws://127.0.0.1/ws'], - - ['?http://127.0.0.1', 'https://something.com', 'ws://127.0.0.1/ws'], - - ['?https://127.0.0.1', 'http://something.com', 'wss://127.0.0.1/ws'], + ['?http://127.0.0.1/ws', 'http://something.com', 'ws://127.0.0.1/ws'], + ['?http://127.0.0.1/ws', 'https://something.com', 'ws://127.0.0.1/ws'], + ['?https://127.0.0.1/ws', 'http://something.com', 'wss://127.0.0.1/ws'], [null, 'http://127.0.0.1', 'ws://127.0.0.1/ws'], [null, 'http://127.0.0.1:8080', 'ws://127.0.0.1:8080/ws'], [null, 'https://127.0.0.1', 'wss://127.0.0.1/ws'], - [ - '?https://example.com&host=example.com', - 'http://something.com', - 'wss://example.com/ws', - ], - [ - '?https://example.com&path=custom', - 'http://something.com', - 'wss://example.com/custom', - ], - [ - '?https://example.com&path=/custom', - 'http://something.com', - 'wss://example.com/custom', - ], - ['?http://[::]', 'http://something.com', 'ws://something.com/ws'], - ['?http://[::]', 'https://something.com', 'wss://something.com/ws'], - ['?http://[::1]:8080/', 'http://[::1]:8080/', 'ws://[::1]:8080/ws'], - ['?https://[::1]:8080/', 'http://[::1]:8080/', 'wss://[::1]:8080/ws'], - [null, 'http://[::1]:8080/', 'ws://[::1]:8080/ws'], - [null, 'https://[::1]:8080/', 'wss://[::1]:8080/ws'], + ['?http://[::]/ws', 'http://something.com', 'ws://something.com/ws'], + ['?http://[::]/ws', 'https://something.com', 'wss://something.com/ws'], + ['?http://[::1]:8080/ws', 'http://[::1]:8080/', 'ws://[::1]:8080/ws'], + ['?https://[::1]:8080/ws', 'http://[::1]:8080/', 'wss://[::1]:8080/ws'], + [null, 'http://[::1]:8080/ws', 'ws://[::1]:8080/ws'], + [null, 'https://[::1]:8080/ws', 'wss://[::1]:8080/ws'], [null, 'file:///home/user/project/index.html', 'ws://localhost/ws'], [null, 'chrome-extension://localhost/', 'ws://localhost/ws'], [null, 'file://localhost/', 'ws://localhost/ws'], diff --git a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 index 59934d06dd..7fc420f665 100644 --- a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 +++ b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8128"`; +exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8126"`; exports[`WebsocketServer should receive connection, send message, and close client 2`] = ` Array [ diff --git a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 index 59934d06dd..7fc420f665 100644 --- a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 +++ b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8128"`; +exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8126"`; exports[`WebsocketServer should receive connection, send message, and close client 2`] = ` Array [ diff --git a/test/server/utils/DevServerPlugin.test.js b/test/server/utils/DevServerPlugin.test.js index 081a7ba2bd..53a4965cfa 100644 --- a/test/server/utils/DevServerPlugin.test.js +++ b/test/server/utils/DevServerPlugin.test.js @@ -27,6 +27,7 @@ describe('DevServerPlugin util', () => { const devServerOptions = { client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', @@ -79,6 +80,7 @@ describe('DevServerPlugin util', () => { const devServerOptions = { client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', @@ -122,6 +124,7 @@ describe('DevServerPlugin util', () => { const devServerOptions = { client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', @@ -143,6 +146,7 @@ describe('DevServerPlugin util', () => { const devServerOptions = { client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', @@ -168,6 +172,7 @@ describe('DevServerPlugin util', () => { const devServerOptions = { client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', @@ -193,6 +198,7 @@ describe('DevServerPlugin util', () => { hot: true, client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', @@ -220,6 +226,7 @@ describe('DevServerPlugin util', () => { hot: true, client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', @@ -249,6 +256,7 @@ describe('DevServerPlugin util', () => { const devServerOptions = { client: { transport: 'sockjs', + webSocketURL: {}, }, webSocketServer: { type: 'sockjs', diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 90dfe14bb0..9b7455fce3 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -175,7 +175,7 @@ const tests = { failure: [''], }, host: { - success: ['', 'localhost', null], + success: ['', 'localhost', '::', '::1', null], failure: [false], }, hot: { From cd6b45a9e2f5bacf466d9b555dcd4b9e4e963d48 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 25 May 2021 19:52:52 +0300 Subject: [PATCH 16/19] test: refactor --- .../parseURL.test.js.snap.webpack4 | 2 + .../parseURL.test.js.snap.webpack5 | 2 + ...webpack4 => logging.test.js.snap.webpack4} | 44 +-- ...webpack5 => logging.test.js.snap.webpack5} | 44 +-- ...nt.test.js => hot-and-live-reload.test.js} | 5 +- test/e2e/logging.test.js | 94 ++++++ ...t.js => web-socket-server-and-url.test.js} | 87 ------ test/ports-map.js | 1 + test/server/open-option.test.js | 271 ++++++++++-------- 9 files changed, 295 insertions(+), 255 deletions(-) rename test/e2e/__snapshots__/{ClientOptions.test.js.snap.webpack4 => logging.test.js.snap.webpack4} (64%) rename test/e2e/__snapshots__/{ClientOptions.test.js.snap.webpack5 => logging.test.js.snap.webpack5} (64%) rename test/e2e/{Client.test.js => hot-and-live-reload.test.js} (98%) create mode 100644 test/e2e/logging.test.js rename test/e2e/{ClientOptions.test.js => web-socket-server-and-url.test.js} (85%) diff --git a/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack4 b/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack4 index 04816ac822..fff30d1ae3 100644 --- a/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack4 +++ b/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack4 @@ -190,6 +190,7 @@ Url { exports[`'parseURL' function should return the url when __resourceQuery is 'undefined' 1`] = ` Url { "auth": null, + "fromCurrentScript": true, "hash": null, "host": "localhost", "hostname": "localhost", @@ -229,6 +230,7 @@ exports[`'parseURL' function should return the url when the current script sourc exports[`'parseURL' function should return the url when the current script source is 'undefined' 1`] = ` Url { "auth": null, + "fromCurrentScript": true, "hash": null, "host": "localhost", "hostname": "localhost", diff --git a/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack5 b/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack5 index 04816ac822..fff30d1ae3 100644 --- a/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack5 +++ b/test/client/utils/__snapshots__/parseURL.test.js.snap.webpack5 @@ -190,6 +190,7 @@ Url { exports[`'parseURL' function should return the url when __resourceQuery is 'undefined' 1`] = ` Url { "auth": null, + "fromCurrentScript": true, "hash": null, "host": "localhost", "hostname": "localhost", @@ -229,6 +230,7 @@ exports[`'parseURL' function should return the url when the current script sourc exports[`'parseURL' function should return the url when the current script source is 'undefined' 1`] = ` Url { "auth": null, + "fromCurrentScript": true, "hash": null, "host": "localhost", "hostname": "localhost", diff --git a/test/e2e/__snapshots__/ClientOptions.test.js.snap.webpack4 b/test/e2e/__snapshots__/logging.test.js.snap.webpack4 similarity index 64% rename from test/e2e/__snapshots__/ClientOptions.test.js.snap.webpack4 rename to test/e2e/__snapshots__/logging.test.js.snap.webpack4 index 92abcfef92..4ce374ca58 100644 --- a/test/e2e/__snapshots__/ClientOptions.test.js.snap.webpack4 +++ b/test/e2e/__snapshots__/logging.test.js.snap.webpack4 @@ -1,45 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Client console.log client logging is none (default) 1`] = ` +exports[`logging client logging is none (default) 1`] = ` Array [ "Hey.", ] `; -exports[`Client console.log client logging is none (sockjs) 1`] = ` +exports[`logging client logging is none (sockjs) 1`] = ` Array [ "Hey.", ] `; -exports[`Client console.log client logging is none (ws) 1`] = ` +exports[`logging client logging is none (ws) 1`] = ` Array [ "Hey.", ] `; -exports[`Client console.log hot disabled (default) 1`] = ` +exports[`logging hot disabled (default) 1`] = ` Array [ "Hey.", "[webpack-dev-server] Live Reloading enabled.", ] `; -exports[`Client console.log hot disabled (sockjs) 1`] = ` +exports[`logging hot disabled (sockjs) 1`] = ` Array [ "Hey.", "[webpack-dev-server] Live Reloading enabled.", ] `; -exports[`Client console.log hot disabled (ws) 1`] = ` +exports[`logging hot disabled (ws) 1`] = ` Array [ "Hey.", "[webpack-dev-server] Live Reloading enabled.", ] `; -exports[`Client console.log hot enabled (default) 1`] = ` +exports[`logging hot enabled (default) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -48,7 +48,7 @@ Array [ ] `; -exports[`Client console.log hot enabled (sockjs) 1`] = ` +exports[`logging hot enabled (sockjs) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -57,7 +57,7 @@ Array [ ] `; -exports[`Client console.log hot enabled (ws) 1`] = ` +exports[`logging hot enabled (ws) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -66,18 +66,18 @@ Array [ ] `; -exports[`Client console.log liveReload & hot are disabled (default) 1`] = ` +exports[`logging liveReload & hot are disabled (default) 1`] = ` Array [ "Hey.", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", "[webpack-dev-server] Disconnected!", "[webpack-dev-server] JSHandle@object", "[webpack-dev-server] JSHandle@object", ] `; -exports[`Client console.log liveReload & hot are disabled (sockjs) 1`] = ` +exports[`logging liveReload & hot are disabled (sockjs) 1`] = ` Array [ "Failed to load resource: the server responded with a status of 404 (Not Found)", "Failed to load resource: the server responded with a status of 404 (Not Found)", @@ -86,18 +86,18 @@ Array [ ] `; -exports[`Client console.log liveReload & hot are disabled (ws) 1`] = ` +exports[`logging liveReload & hot are disabled (ws) 1`] = ` Array [ "Hey.", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", "[webpack-dev-server] Disconnected!", "[webpack-dev-server] JSHandle@object", "[webpack-dev-server] JSHandle@object", ] `; -exports[`Client console.log liveReload disabled (default) 1`] = ` +exports[`logging liveReload disabled (default) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -105,7 +105,7 @@ Array [ ] `; -exports[`Client console.log liveReload disabled (sockjs) 1`] = ` +exports[`logging liveReload disabled (sockjs) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -113,7 +113,7 @@ Array [ ] `; -exports[`Client console.log liveReload disabled (ws) 1`] = ` +exports[`logging liveReload disabled (ws) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -121,7 +121,7 @@ Array [ ] `; -exports[`Client console.log liveReload enabled (default) 1`] = ` +exports[`logging liveReload enabled (default) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -130,7 +130,7 @@ Array [ ] `; -exports[`Client console.log liveReload enabled (sockjs) 1`] = ` +exports[`logging liveReload enabled (sockjs) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -139,7 +139,7 @@ Array [ ] `; -exports[`Client console.log liveReload enabled (ws) 1`] = ` +exports[`logging liveReload enabled (ws) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", diff --git a/test/e2e/__snapshots__/ClientOptions.test.js.snap.webpack5 b/test/e2e/__snapshots__/logging.test.js.snap.webpack5 similarity index 64% rename from test/e2e/__snapshots__/ClientOptions.test.js.snap.webpack5 rename to test/e2e/__snapshots__/logging.test.js.snap.webpack5 index 92abcfef92..4ce374ca58 100644 --- a/test/e2e/__snapshots__/ClientOptions.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/logging.test.js.snap.webpack5 @@ -1,45 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Client console.log client logging is none (default) 1`] = ` +exports[`logging client logging is none (default) 1`] = ` Array [ "Hey.", ] `; -exports[`Client console.log client logging is none (sockjs) 1`] = ` +exports[`logging client logging is none (sockjs) 1`] = ` Array [ "Hey.", ] `; -exports[`Client console.log client logging is none (ws) 1`] = ` +exports[`logging client logging is none (ws) 1`] = ` Array [ "Hey.", ] `; -exports[`Client console.log hot disabled (default) 1`] = ` +exports[`logging hot disabled (default) 1`] = ` Array [ "Hey.", "[webpack-dev-server] Live Reloading enabled.", ] `; -exports[`Client console.log hot disabled (sockjs) 1`] = ` +exports[`logging hot disabled (sockjs) 1`] = ` Array [ "Hey.", "[webpack-dev-server] Live Reloading enabled.", ] `; -exports[`Client console.log hot disabled (ws) 1`] = ` +exports[`logging hot disabled (ws) 1`] = ` Array [ "Hey.", "[webpack-dev-server] Live Reloading enabled.", ] `; -exports[`Client console.log hot enabled (default) 1`] = ` +exports[`logging hot enabled (default) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -48,7 +48,7 @@ Array [ ] `; -exports[`Client console.log hot enabled (sockjs) 1`] = ` +exports[`logging hot enabled (sockjs) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -57,7 +57,7 @@ Array [ ] `; -exports[`Client console.log hot enabled (ws) 1`] = ` +exports[`logging hot enabled (ws) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -66,18 +66,18 @@ Array [ ] `; -exports[`Client console.log liveReload & hot are disabled (default) 1`] = ` +exports[`logging liveReload & hot are disabled (default) 1`] = ` Array [ "Hey.", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", "[webpack-dev-server] Disconnected!", "[webpack-dev-server] JSHandle@object", "[webpack-dev-server] JSHandle@object", ] `; -exports[`Client console.log liveReload & hot are disabled (sockjs) 1`] = ` +exports[`logging liveReload & hot are disabled (sockjs) 1`] = ` Array [ "Failed to load resource: the server responded with a status of 404 (Not Found)", "Failed to load resource: the server responded with a status of 404 (Not Found)", @@ -86,18 +86,18 @@ Array [ ] `; -exports[`Client console.log liveReload & hot are disabled (ws) 1`] = ` +exports[`logging liveReload & hot are disabled (ws) 1`] = ` Array [ "Hey.", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", - "WebSocket connection to 'ws://localhost:8096/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", + "WebSocket connection to 'ws://localhost:8098/ws' failed: Error during WebSocket handshake: Unexpected response code: 404", "[webpack-dev-server] Disconnected!", "[webpack-dev-server] JSHandle@object", "[webpack-dev-server] JSHandle@object", ] `; -exports[`Client console.log liveReload disabled (default) 1`] = ` +exports[`logging liveReload disabled (default) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -105,7 +105,7 @@ Array [ ] `; -exports[`Client console.log liveReload disabled (sockjs) 1`] = ` +exports[`logging liveReload disabled (sockjs) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -113,7 +113,7 @@ Array [ ] `; -exports[`Client console.log liveReload disabled (ws) 1`] = ` +exports[`logging liveReload disabled (ws) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -121,7 +121,7 @@ Array [ ] `; -exports[`Client console.log liveReload enabled (default) 1`] = ` +exports[`logging liveReload enabled (default) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -130,7 +130,7 @@ Array [ ] `; -exports[`Client console.log liveReload enabled (sockjs) 1`] = ` +exports[`logging liveReload enabled (sockjs) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", @@ -139,7 +139,7 @@ Array [ ] `; -exports[`Client console.log liveReload enabled (ws) 1`] = ` +exports[`logging liveReload enabled (ws) 1`] = ` Array [ "Hey.", "[HMR] Waiting for update signal from WDS...", diff --git a/test/e2e/Client.test.js b/test/e2e/hot-and-live-reload.test.js similarity index 98% rename from test/e2e/Client.test.js rename to test/e2e/hot-and-live-reload.test.js index c9e9796823..c2a21fbd76 100644 --- a/test/e2e/Client.test.js +++ b/test/e2e/hot-and-live-reload.test.js @@ -59,9 +59,9 @@ describe('reload', () => { const options = Object.assign( {}, { - static: false, - port, host: '0.0.0.0', + port, + static: false, }, mode.options ); @@ -95,7 +95,6 @@ describe('reload', () => { .then((color) => { page.setRequestInterception(true).then(() => { page.on('request', (req) => { - console.log(req.url()); if ( req.isNavigationRequest() && req.frame() === page.mainFrame() && diff --git a/test/e2e/logging.test.js b/test/e2e/logging.test.js new file mode 100644 index 0000000000..a3f877f7c9 --- /dev/null +++ b/test/e2e/logging.test.js @@ -0,0 +1,94 @@ +'use strict'; + +const testServer = require('../helpers/test-server'); +const config = require('../fixtures/client-config/webpack.config'); +const runBrowser = require('../helpers/run-browser'); +const port = require('../ports-map').logging; +const { beforeBrowserCloseDelay } = require('../helpers/puppeteer-constants'); + +describe('logging', () => { + const baseOptions = { + host: '0.0.0.0', + port, + }; + const webSocketServerTypesLog = [ + {}, + { webSocketServer: 'sockjs' }, + { webSocketServer: 'ws' }, + ]; + + const cases = [ + { + title: 'hot disabled', + options: { + hot: false, + }, + }, + { + title: 'hot enabled', + options: { + hot: true, + }, + }, + { + title: 'liveReload disabled', + options: { + liveReload: false, + }, + }, + { + title: 'liveReload enabled', + options: { + liveReload: true, + }, + }, + { + title: 'liveReload & hot are disabled', + options: { + liveReload: false, + hot: false, + }, + }, + { + title: 'client logging is none', + options: { + client: { + logging: 'none', + }, + }, + }, + ]; + + webSocketServerTypesLog.forEach(async (mode) => { + cases.forEach(async ({ title, options }) => { + title += ` (${ + Object.keys(mode).length ? mode.webSocketServer : 'default' + })`; + + options = { ...mode, ...options }; + + const testOptions = Object.assign({}, baseOptions, options); + + it(title, (done) => { + testServer.startAwaitingCompilation(config, testOptions, async () => { + const res = []; + const { page, browser } = await runBrowser(); + + page.goto(`http://localhost:${port}/main`); + page.on('console', ({ _text }) => { + res.push(_text); + }); + + // wait for load before closing the browser + await page.waitForNavigation({ waitUntil: 'load' }); + await page.waitForTimeout(beforeBrowserCloseDelay); + await browser.close(); + + // Order doesn't matter, maybe we should improve that in future + await expect(res.sort()).toMatchSnapshot(); + await testServer.close(done); + }); + }); + }); + }); +}); diff --git a/test/e2e/ClientOptions.test.js b/test/e2e/web-socket-server-and-url.test.js similarity index 85% rename from test/e2e/ClientOptions.test.js rename to test/e2e/web-socket-server-and-url.test.js index 9adfcfe5e6..79b9eac55e 100644 --- a/test/e2e/ClientOptions.test.js +++ b/test/e2e/web-socket-server-and-url.test.js @@ -420,90 +420,3 @@ for (const webSocketServerType of webSocketServerTypes) { }); }); } - -describe('Client console.log', () => { - const baseOptions = { - port: port2, - host: '0.0.0.0', - }; - const webSocketServerTypesLog = [ - {}, - { webSocketServer: 'sockjs' }, - { webSocketServer: 'ws' }, - ]; - - const cases = [ - { - title: 'hot disabled', - options: { - hot: false, - }, - }, - { - title: 'hot enabled', - options: { - hot: true, - }, - }, - { - title: 'liveReload disabled', - options: { - liveReload: false, - }, - }, - { - title: 'liveReload enabled', - options: { - liveReload: true, - }, - }, - { - title: 'liveReload & hot are disabled', - options: { - liveReload: false, - hot: false, - }, - }, - { - title: 'client logging is none', - options: { - client: { - logging: 'none', - }, - }, - }, - ]; - - webSocketServerTypesLog.forEach(async (mode) => { - cases.forEach(async ({ title, options }) => { - title += ` (${ - Object.keys(mode).length ? mode.webSocketServer : 'default' - })`; - - options = { ...mode, ...options }; - - const testOptions = Object.assign({}, baseOptions, options); - - it(title, (done) => { - testServer.startAwaitingCompilation(config, testOptions, async () => { - const res = []; - const { page, browser } = await runBrowser(); - - page.goto(`http://localhost:${port2}/main`); - page.on('console', ({ _text }) => { - res.push(_text); - }); - - // wait for load before closing the browser - await page.waitForNavigation({ waitUntil: 'load' }); - await page.waitForTimeout(beforeBrowserCloseDelay); - await browser.close(); - - // Order doesn't matter, maybe we should improve that in future - await expect(res.sort()).toMatchSnapshot(); - await testServer.close(done); - }); - }); - }); - }); -}); diff --git a/test/ports-map.js b/test/ports-map.js index 020d25bd2f..29b8fa2bd1 100644 --- a/test/ports-map.js +++ b/test/ports-map.js @@ -8,6 +8,7 @@ const portsList = { SockJSServer: 1, Client: 1, ClientOptions: 3, + logging: 1, MultiCompiler: 1, UniversalCompiler: 1, Server: 1, diff --git a/test/server/open-option.test.js b/test/server/open-option.test.js index 7d229b08de..0f6f42af44 100644 --- a/test/server/open-option.test.js +++ b/test/server/open-option.test.js @@ -35,7 +35,7 @@ describe('"open" option', () => { compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://localhost:${port}/`, { wait: false, }); @@ -58,7 +58,7 @@ describe('"open" option', () => { compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('https://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`https://localhost:${port}/`, { wait: false, }); @@ -72,16 +72,17 @@ describe('"open" option', () => { it("should work with '0.0.0.0' host", (done) => { const compiler = webpack(config); + const host = '0.0.0.0'; const server = createServer(compiler, { - open: true, + host, port, - host: '0.0.0.0', + open: true, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://0.0.0.0:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { wait: false, }); @@ -90,21 +91,22 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, '0.0.0.0'); + server.listen(port, host); }); it("should work with '::' host", (done) => { const compiler = webpack(config); + const host = '::'; const server = createServer(compiler, { - open: true, + host, port, - host: '::', + open: true, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://[::]:8117/', { + expect(open).toHaveBeenCalledWith(`http://[${host}]:${port}/`, { wait: false, }); @@ -113,21 +115,22 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, '::'); + server.listen(port, host); }); it("should work with 'localhost' host", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: true, + host, port, - host: 'localhost', + open: true, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { wait: false, }); @@ -136,21 +139,22 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with '127.0.0.1' host", (done) => { const compiler = webpack(config); + const host = '127.0.0.1'; const server = createServer(compiler, { - open: true, + host, port, - host: '127.0.0.1', + open: true, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://127.0.0.1:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { wait: false, }); @@ -159,21 +163,22 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, '127.0.0.1'); + server.listen(port, host); }); it("should work with '::1' host", (done) => { const compiler = webpack(config); + const host = '::1'; const server = createServer(compiler, { - open: true, + host, port, - host: '::1', + open: true, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://[::1]:8117/', { + expect(open).toHaveBeenCalledWith(`http://[${host}]:${port}/`, { wait: false, }); @@ -182,21 +187,21 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, '::1'); + server.listen(port, host); }); it(`should work with '${internalIPv4}' host`, (done) => { const compiler = webpack(config); const server = createServer(compiler, { - open: true, - port, host: internalIPv4, + port, + open: true, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith(`http://${internalIPv4}:8117/`, { + expect(open).toHaveBeenCalledWith(`http://${internalIPv4}:${port}/`, { wait: false, }); @@ -235,16 +240,17 @@ describe('"open" option', () => { it('should work with boolean', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: true, + host, port, - host: 'localhost', + open: true, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { wait: false, }); @@ -253,15 +259,16 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with boolean but don't close with 'false' value", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: false, + host, port, - host: 'localhost', + open: false, static: false, }); @@ -274,21 +281,22 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it('should work with relative string', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: 'index.html', + host, port, - host: 'localhost', + open: 'index.html', static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/index.html`, { wait: false, }); @@ -297,21 +305,22 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it('should work with relative string starting with "/"', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: '/index.html', + host, port, - host: 'localhost', + open: '/index.html', static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/index.html`, { wait: false, }); @@ -320,13 +329,14 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it('should work with absolute string', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: 'http://localhost:8117/index.html', + open: `http://${host}:${port}/index.html`, port, host: 'localhost', static: false, @@ -334,7 +344,7 @@ describe('"open" option', () => { compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/index.html`, { wait: false, }); @@ -343,15 +353,16 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it('should work with multiple relative strings', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: ['first.html', 'second.html'], - port, host: 'localhost', + port, + open: ['first.html', 'second.html'], static: false, }); @@ -359,14 +370,14 @@ describe('"open" option', () => { server.close(() => { expect(open).toHaveBeenNthCalledWith( 1, - 'http://localhost:8117/first.html', + `http://${host}:${port}/first.html`, { wait: false, } ); expect(open).toHaveBeenNthCalledWith( 2, - 'http://localhost:8117/second.html', + `http://${host}:${port}/second.html`, { wait: false, } @@ -377,18 +388,19 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it('should work with multiple absolute strings', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host: 'localhost', + port, open: [ - 'http://localhost:8117/first.html', - 'http://localhost:8117/second.html', + `http://${host}:${port}/first.html`, + `http://${host}:${port}/second.html`, ], - port, - host: 'localhost', static: false, }); @@ -396,14 +408,14 @@ describe('"open" option', () => { server.close(() => { expect(open).toHaveBeenNthCalledWith( 1, - 'http://localhost:8117/first.html', + `http://${host}:${port}/first.html`, { wait: false, } ); expect(open).toHaveBeenNthCalledWith( 2, - 'http://localhost:8117/second.html', + `http://${host}:${port}/second.html`, { wait: false, } @@ -414,21 +426,22 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it('should work with empty object', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { - open: {}, + host, port, - host: 'localhost', + open: {}, static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { wait: false, }); @@ -437,23 +450,24 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with object and with the boolean value of 'target' option", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { target: true, }, - port, - host: 'localhost', static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { wait: false, }); @@ -462,23 +476,24 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with object and with the 'target' option", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { target: 'index.html', }, - port, - host: 'localhost', static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/index.html`, { wait: false, }); @@ -487,17 +502,18 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with object and with multiple values of the 'target' option", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { target: ['first.html', 'second.html'], }, - port, - host: 'localhost', static: false, }); @@ -505,14 +521,14 @@ describe('"open" option', () => { server.close(() => { expect(open).toHaveBeenNthCalledWith( 1, - 'http://localhost:8117/first.html', + `http://${host}:${port}/first.html`, { wait: false, } ); expect(open).toHaveBeenNthCalledWith( 2, - 'http://localhost:8117/second.html', + `http://${host}:${port}/second.html`, { wait: false, } @@ -523,23 +539,24 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with object and with the 'app' option", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { app: 'google-chrome', }, - port, - host: 'localhost', static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { app: { name: 'google-chrome' }, wait: false, }); @@ -549,23 +566,24 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with object and with the 'app' and 'arguments' options", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { app: { name: 'google-chrome', arguments: ['--incognito'] }, }, - port, - host: 'localhost', static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/`, { app: { name: 'google-chrome', arguments: ['--incognito'] }, wait: false, }); @@ -575,24 +593,25 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it('should work with object with "target" and "app" options', (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { target: 'index.html', app: 'google-chrome', }, - port, - host: 'localhost', static: false, }); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { + expect(open).toHaveBeenCalledWith(`http://${host}:${port}/index.html`, { app: { name: 'google-chrome' }, wait: false, }); @@ -602,18 +621,19 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with object, with multiple value of the 'target' option and with the 'app' and 'arguments' options", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { target: ['first.html', 'second.html'], app: { name: 'google-chrome', arguments: ['--incognito'] }, }, - port, - host: 'localhost', static: false, }); @@ -621,7 +641,7 @@ describe('"open" option', () => { server.close(() => { expect(open).toHaveBeenNthCalledWith( 1, - 'http://localhost:8117/first.html', + `http://${host}:${port}/first.html`, { wait: false, app: { name: 'google-chrome', arguments: ['--incognito'] }, @@ -629,7 +649,7 @@ describe('"open" option', () => { ); expect(open).toHaveBeenNthCalledWith( 2, - 'http://localhost:8117/second.html', + `http://${host}:${port}/second.html`, { wait: false, app: { name: 'google-chrome', arguments: ['--incognito'] }, @@ -641,18 +661,19 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should work with object, with multiple value of the 'target' option (relative and absolute URLs) and with the 'app' option with arguments", (done) => { const compiler = webpack(config); + const host = 'localhost'; const server = createServer(compiler, { + host, + port, open: { - target: ['first.html', 'http://localhost:8117/second.html'], + target: ['first.html', `http://${host}:${port}/second.html`], app: { name: 'google-chrome', arguments: ['--incognito'] }, }, - port, - host: 'localhost', static: false, }); @@ -660,7 +681,7 @@ describe('"open" option', () => { server.close(() => { expect(open).toHaveBeenNthCalledWith( 1, - 'http://localhost:8117/first.html', + `http://${host}:${port}/first.html`, { wait: false, app: { name: 'google-chrome', arguments: ['--incognito'] }, @@ -668,7 +689,7 @@ describe('"open" option', () => { ); expect(open).toHaveBeenNthCalledWith( 2, - 'http://localhost:8117/second.html', + `http://${host}:${port}/second.html`, { wait: false, app: { name: 'google-chrome', arguments: ['--incognito'] }, @@ -680,7 +701,7 @@ describe('"open" option', () => { }); compiler.run(() => {}); - server.listen(port, 'localhost'); + server.listen(port, host); }); it("should log warning when can't open", (done) => { @@ -688,20 +709,19 @@ describe('"open" option', () => { const compiler = webpack(config); const server = createServer(compiler, { - open: true, port, - host: 'localhost', + open: true, static: false, }); const loggerWarnSpy = jest.spyOn(server.logger, 'warn'); compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/', { + expect(open).toHaveBeenCalledWith(`http://localhost:${port}/`, { wait: false, }); expect(loggerWarnSpy).toHaveBeenCalledWith( - 'Unable to open "http://localhost:8117/" page. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".' + `Unable to open "http://localhost:${port}/" page. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".` ); loggerWarnSpy.mockRestore(); @@ -726,11 +746,14 @@ describe('"open" option', () => { compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { - wait: false, - }); + expect(open).toHaveBeenCalledWith( + `http://localhost:${port}/index.html`, + { + wait: false, + } + ); expect(loggerWarnSpy).toHaveBeenCalledWith( - 'Unable to open "http://localhost:8117/index.html" page. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".' + `Unable to open "http://localhost:${port}/index.html" page. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".` ); loggerWarnSpy.mockRestore(); @@ -758,12 +781,15 @@ describe('"open" option', () => { compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { - app: { name: 'google-chrome' }, - wait: false, - }); + expect(open).toHaveBeenCalledWith( + `http://localhost:${port}/index.html`, + { + app: { name: 'google-chrome' }, + wait: false, + } + ); expect(loggerWarnSpy).toHaveBeenCalledWith( - 'Unable to open "http://localhost:8117/index.html" page in "google-chrome" app. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".' + `Unable to open "http://localhost:${port}/index.html" page in "google-chrome" app. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".` ); loggerWarnSpy.mockRestore(); @@ -794,15 +820,18 @@ describe('"open" option', () => { compiler.hooks.done.tap('webpack-dev-server', () => { server.close(() => { - expect(open).toHaveBeenCalledWith('http://localhost:8117/index.html', { - app: { - name: 'google-chrome', - arguments: ['--incognito', '--new-window'], - }, - wait: false, - }); + expect(open).toHaveBeenCalledWith( + `http://localhost:${port}/index.html`, + { + app: { + name: 'google-chrome', + arguments: ['--incognito', '--new-window'], + }, + wait: false, + } + ); expect(loggerWarnSpy).toHaveBeenCalledWith( - 'Unable to open "http://localhost:8117/index.html" page in "google-chrome" app with "--incognito --new-window" arguments. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".' + `Unable to open "http://localhost:${port}/index.html" page in "google-chrome" app with "--incognito --new-window" arguments. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".` ); loggerWarnSpy.mockRestore(); @@ -820,7 +849,7 @@ describe('"open" option', () => { const compiler = webpack(config); const server = createServer(compiler, { open: { - target: ['first.html', 'http://localhost:8117/second.html'], + target: ['first.html', `http://localhost:${port}/second.html`], app: { name: 'google-chrome', arguments: ['--incognito', '--new-window'], @@ -835,7 +864,7 @@ describe('"open" option', () => { server.close(() => { expect(open).toHaveBeenNthCalledWith( 1, - 'http://localhost:8117/first.html', + `http://localhost:${port}/first.html`, { wait: false, app: { @@ -846,7 +875,7 @@ describe('"open" option', () => { ); expect(open).toHaveBeenNthCalledWith( 2, - 'http://localhost:8117/second.html', + `http://localhost:${port}/second.html`, { wait: false, app: { @@ -857,11 +886,11 @@ describe('"open" option', () => { ); expect(loggerWarnSpy).toHaveBeenNthCalledWith( 1, - 'Unable to open "http://localhost:8117/first.html" page in "google-chrome" app with "--incognito --new-window" arguments. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".' + `Unable to open "http://localhost:${port}/first.html" page in "google-chrome" app with "--incognito --new-window" arguments. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".` ); expect(loggerWarnSpy).toHaveBeenNthCalledWith( 2, - 'Unable to open "http://localhost:8117/second.html" page in "google-chrome" app with "--incognito --new-window" arguments. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".' + `Unable to open "http://localhost:${port}/second.html" page in "google-chrome" app with "--incognito --new-window" arguments. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".` ); loggerWarnSpy.mockRestore(); From dc2fb506109dab1a632b0f3cd419effb8acea110 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 25 May 2021 20:04:44 +0300 Subject: [PATCH 17/19] test: update snapshots --- test/server/Server.test.js | 1 + test/server/__snapshots__/Server.test.js.snap.webpack4 | 6 +++--- test/server/__snapshots__/Server.test.js.snap.webpack5 | 6 +++--- .../__snapshots__/WebsocketServer.test.js.snap.webpack4 | 2 +- .../__snapshots__/WebsocketServer.test.js.snap.webpack5 | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/test/server/Server.test.js b/test/server/Server.test.js index aff3f96cf1..186961043e 100644 --- a/test/server/Server.test.js +++ b/test/server/Server.test.js @@ -12,6 +12,7 @@ const port = require('../ports-map').Server; const isWebpack5 = require('../helpers/isWebpack5'); const getFreePort = Server.getFreePort; + jest.mock('sockjs/lib/transport'); const baseDevConfig = { diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack4 b/test/server/__snapshots__/Server.test.js.snap.webpack4 index e3ad8cea6e..009429125f 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack4 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack4 @@ -4,7 +4,7 @@ exports[`Server DevServerPlugin add hot option 1`] = ` Array [ Array [ "client", - "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", + "index.js?ws%3A%2F%2Flocalhost%3A8101%2Fws", ], Array [ "node_modules", @@ -22,7 +22,7 @@ exports[`Server DevServerPlugin add hot-only option 1`] = ` Array [ Array [ "client", - "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", + "index.js?ws%3A%2F%2Flocalhost%3A8101%2Fws", ], Array [ "node_modules", @@ -40,7 +40,7 @@ exports[`Server DevServerPlugin should create and run server with old parameters Array [ Array [ "client", - "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", + "index.js?ws%3A%2F%2Flocalhost%3A8101%2Fws", ], Array [ "node_modules", diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack5 b/test/server/__snapshots__/Server.test.js.snap.webpack5 index e3ad8cea6e..009429125f 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack5 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack5 @@ -4,7 +4,7 @@ exports[`Server DevServerPlugin add hot option 1`] = ` Array [ Array [ "client", - "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", + "index.js?ws%3A%2F%2Flocalhost%3A8101%2Fws", ], Array [ "node_modules", @@ -22,7 +22,7 @@ exports[`Server DevServerPlugin add hot-only option 1`] = ` Array [ Array [ "client", - "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", + "index.js?ws%3A%2F%2Flocalhost%3A8101%2Fws", ], Array [ "node_modules", @@ -40,7 +40,7 @@ exports[`Server DevServerPlugin should create and run server with old parameters Array [ Array [ "client", - "index.js?ws%3A%2F%2Flocalhost%3A8100%2Fws", + "index.js?ws%3A%2F%2Flocalhost%3A8101%2Fws", ], Array [ "node_modules", diff --git a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 index 7fc420f665..c056d6dab1 100644 --- a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 +++ b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack4 @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8126"`; +exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8127"`; exports[`WebsocketServer should receive connection, send message, and close client 2`] = ` Array [ diff --git a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 index 7fc420f665..c056d6dab1 100644 --- a/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 +++ b/test/server/servers/__snapshots__/WebsocketServer.test.js.snap.webpack5 @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8126"`; +exports[`WebsocketServer should receive connection, send message, and close client 1`] = `"localhost:8127"`; exports[`WebsocketServer should receive connection, send message, and close client 2`] = ` Array [ From 89e30763c3c878725bcfc4aa9ad60c619b13aed5 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 25 May 2021 20:34:09 +0300 Subject: [PATCH 18/19] test: update snapshots --- test/cli/__snapshots__/cli.test.js.snap.webpack4 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/cli/__snapshots__/cli.test.js.snap.webpack4 b/test/cli/__snapshots__/cli.test.js.snap.webpack4 index 4773f47bdb..93bd1ca052 100644 --- a/test/cli/__snapshots__/cli.test.js.snap.webpack4 +++ b/test/cli/__snapshots__/cli.test.js.snap.webpack4 @@ -10,7 +10,8 @@ exports[`CLI --bonjour 1`] = ` `; exports[`CLI --bonjour and --https 1`] = ` -" [webpack-dev-server] Project is running at: +" [webpack-dev-server] Generating SSL Certificate + [webpack-dev-server] Project is running at: [webpack-dev-server] Loopback: https://localhost:/ [webpack-dev-server] On Your Network (IPv4): https://:/ [webpack-dev-server] On Your Network (IPv6): https://[]:/ @@ -197,20 +198,19 @@ Options: value. --progress [value] Print compilation progress during build. -j, --json [value] Prints result as JSON or store it in a file. - -d, --devtool Determine source maps to use. - --no-devtool Do not generate source maps. --entry The entry point(s) of your application e.g. ./src/main.js. + -o, --output-path Output location of the file generated by + webpack e.g. ./dist/. + -t, --target Sets the build target e.g. node. + -d, --devtool Determine source maps to use. + --no-devtool Do not generate source maps. --mode Defines the mode to pass to webpack. --name Name of the configuration. Used when loading multiple configurations. - -o, --output-path Output location of the file generated by - webpack e.g. ./dist/. --stats [value] It instructs webpack on how to treat the stats e.g. verbose. --no-stats Disable stats output. - -t, --target Sets the build target e.g. node. - --no-target Negative 'target' option. --watch-options-stdin Stop watching when stdin stream has ended. --no-watch-options-stdin Do not stop watching when stdin stream has ended. From b5e2227d8bee41518f8e4dea93114f3df8cf1d42 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 25 May 2021 20:57:19 +0300 Subject: [PATCH 19/19] test: update snapshots --- test/cli/__snapshots__/cli.test.js.snap.webpack4 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/cli/__snapshots__/cli.test.js.snap.webpack4 b/test/cli/__snapshots__/cli.test.js.snap.webpack4 index 93bd1ca052..01d2abf391 100644 --- a/test/cli/__snapshots__/cli.test.js.snap.webpack4 +++ b/test/cli/__snapshots__/cli.test.js.snap.webpack4 @@ -10,8 +10,7 @@ exports[`CLI --bonjour 1`] = ` `; exports[`CLI --bonjour and --https 1`] = ` -" [webpack-dev-server] Generating SSL Certificate - [webpack-dev-server] Project is running at: +" [webpack-dev-server] Project is running at: [webpack-dev-server] Loopback: https://localhost:/ [webpack-dev-server] On Your Network (IPv4): https://:/ [webpack-dev-server] On Your Network (IPv6): https://[]:/