From 7520e8fcc7448e78d5e66551db9efc4cbccd2aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Fri, 5 Jun 2020 10:22:29 +0300 Subject: [PATCH 1/4] fix: do not use URLSearchParams to support IE 11 without polyfill --- src/runtime/ErrorOverlayEntry.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/runtime/ErrorOverlayEntry.js b/src/runtime/ErrorOverlayEntry.js index 3b2e855f..fdc5d3a2 100644 --- a/src/runtime/ErrorOverlayEntry.js +++ b/src/runtime/ErrorOverlayEntry.js @@ -69,8 +69,17 @@ function compileMessageHandler(message) { let overrides = {}; if (__resourceQuery) { - const searchParams = new URLSearchParams(__resourceQuery.slice(1)); - searchParams.forEach(function (value, key) { + // Decode any possible encoded characters and remove `?` from start + const query = decodeURIComponent(__resourceQuery).slice(1); + // Split string like `key=value&foo=bar`, first from &, and then = + // The structure will be `[['key', 'value'], ['foo', 'bar']]` + const entries = query.split('&').map(function (entry) { + return entry.split('='); + }); + // Add all entries to the overrides object + entries.forEach(function (entry) { + const key = entry[0]; + const value = entry[1]; overrides[key] = value; }); } From 50749be4e0926547b3d72111c03bb787169c7032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 7 Jun 2020 15:46:52 +0300 Subject: [PATCH 2/4] refactor: removed unused argument --- src/runtime/sockets/WHMEventSource.js | 4 +--- src/runtime/sockets/WPSSocket.js | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/runtime/sockets/WHMEventSource.js b/src/runtime/sockets/WHMEventSource.js index e446c9e6..9632eeef 100644 --- a/src/runtime/sockets/WHMEventSource.js +++ b/src/runtime/sockets/WHMEventSource.js @@ -8,11 +8,9 @@ const singletonKey = '__webpack_hot_middleware_reporter__'; /** * Initializes a socket server for HMR for webpack-hot-middleware. * @param {function(message: *): void} messageHandler A handler to consume Webpack compilation messages. - * @param {*} overrides Socket integration overrides to change the connection URL. * @returns {void} */ -// eslint-disable-next-line no-unused-vars -function initWHMEventSource(messageHandler, overrides) { +function initWHMEventSource(messageHandler) { const client = window[singletonKey] || require('webpack-hot-middleware/client'); client.useCustomOverlay({ diff --git a/src/runtime/sockets/WPSSocket.js b/src/runtime/sockets/WPSSocket.js index 85cd88bd..fcd853c4 100644 --- a/src/runtime/sockets/WPSSocket.js +++ b/src/runtime/sockets/WPSSocket.js @@ -3,11 +3,9 @@ /** * Initializes a socket server for HMR for webpack-plugin-serve. * @param {function(message: *): void} messageHandler A handler to consume Webpack compilation messages. - * @param {*} overrides Socket integration overrides to change the connection URL. * @returns {void} */ -// eslint-disable-next-line no-unused-vars -function initWPSSocket(messageHandler, overrides) { +function initWPSSocket(messageHandler) { /** * The hard-coded options injection key from webpack-plugin-serve. * From fe34ad76e703119257ffd0f0564ab777fb23519a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 7 Jun 2020 15:47:38 +0300 Subject: [PATCH 3/4] refactor: move parsing of webpack __resourceQuery to where it's used --- src/runtime/ErrorOverlayEntry.js | 21 ++------------ src/runtime/sockets/WDSSocket.js | 9 ++++-- .../sockets/utils/parseURLSearchParams.js | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 src/runtime/sockets/utils/parseURLSearchParams.js diff --git a/src/runtime/ErrorOverlayEntry.js b/src/runtime/ErrorOverlayEntry.js index fdc5d3a2..371b44c0 100644 --- a/src/runtime/ErrorOverlayEntry.js +++ b/src/runtime/ErrorOverlayEntry.js @@ -1,4 +1,4 @@ -/* global __resourceQuery, __react_refresh_error_overlay__, __react_refresh_init_socket__ */ +/* global __react_refresh_error_overlay__, __react_refresh_init_socket__ */ const registerErrorEventHandlers = require('./errorEventHandlers'); const formatWebpackErrors = require('./formatWebpackErrors'); @@ -67,25 +67,8 @@ function compileMessageHandler(message) { } } -let overrides = {}; -if (__resourceQuery) { - // Decode any possible encoded characters and remove `?` from start - const query = decodeURIComponent(__resourceQuery).slice(1); - // Split string like `key=value&foo=bar`, first from &, and then = - // The structure will be `[['key', 'value'], ['foo', 'bar']]` - const entries = query.split('&').map(function (entry) { - return entry.split('='); - }); - // Add all entries to the overrides object - entries.forEach(function (entry) { - const key = entry[0]; - const value = entry[1]; - overrides[key] = value; - }); -} - // Registers handlers for compile errors -__react_refresh_init_socket__(compileMessageHandler, overrides); +__react_refresh_init_socket__(compileMessageHandler); // Registers handlers for runtime errors registerErrorEventHandlers.error(function handleError(error) { hasRuntimeErrors = true; diff --git a/src/runtime/sockets/WDSSocket.js b/src/runtime/sockets/WDSSocket.js index df87afc7..e5cee8b5 100644 --- a/src/runtime/sockets/WDSSocket.js +++ b/src/runtime/sockets/WDSSocket.js @@ -1,15 +1,18 @@ -/* global __webpack_dev_server_client__ */ +/* global __resourceQuery, __webpack_dev_server_client__ */ const url = require('native-url'); +const parseURLSearchParams = require('./utils/parseURLSearchParams'); + /** * Initializes a socket server for HMR for webpack-dev-server. * @param {function(message: *): void} messageHandler A handler to consume Webpack compilation messages. - * @param {*} overrides Socket integration overrides to change the connection URL. * @returns {void} */ -function initWDSSocket(messageHandler, overrides) { +function initWDSSocket(messageHandler) { if (typeof __webpack_dev_server_client__ !== 'undefined') { + // Get config overrides from webpack __resourceQuery global + const overrides = parseURLSearchParams(__resourceQuery); const SocketClient = __webpack_dev_server_client__; // TODO: Support usage of custom sockets after WDS 4.0 is released // Ref: https://github.com/webpack/webpack-dev-server/pull/2055 diff --git a/src/runtime/sockets/utils/parseURLSearchParams.js b/src/runtime/sockets/utils/parseURLSearchParams.js new file mode 100644 index 00000000..8dedc36f --- /dev/null +++ b/src/runtime/sockets/utils/parseURLSearchParams.js @@ -0,0 +1,28 @@ +/** + * Parse URLSearchParams from a string like `?key=value&foo=ba` + * @param {string} queryString + * @returns {*} + */ +function parseURLSearchParams(queryString) { + const params = {}; + + // Decode any possible encoded characters and remove `?` from start + const query = decodeURIComponent(queryString).replace(/^\?/, ''); + + // Split string like `key=value&foo=bar`, first from &, and then = + // The structure will be `[['key', 'value'], ['foo', 'bar']]` + const entries = query.split('&').map(function (entry) { + return entry.split('='); + }); + + // Add all entries to the overrides object + entries.forEach(function (entry) { + const key = entry[0]; + const value = entry[1]; + params[key] = value; + }); + + return params; +} + +module.exports = parseURLSearchParams; From 8a5f6dacbebf5fef25bc001a9b644d905381950d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Fri, 12 Jun 2020 10:02:23 +0300 Subject: [PATCH 4/4] refactor: rework less generic getResourceQuery instead of parseURLSearchParams --- src/runtime/sockets/WDSSocket.js | 12 +++--- src/runtime/sockets/utils/getResourceQuery.js | 41 +++++++++++++++++++ .../sockets/utils/parseURLSearchParams.js | 28 ------------- test/unit/getResourceQuery.test.js | 32 +++++++++++++++ 4 files changed, 79 insertions(+), 34 deletions(-) create mode 100644 src/runtime/sockets/utils/getResourceQuery.js delete mode 100644 src/runtime/sockets/utils/parseURLSearchParams.js create mode 100644 test/unit/getResourceQuery.test.js diff --git a/src/runtime/sockets/WDSSocket.js b/src/runtime/sockets/WDSSocket.js index e5cee8b5..eba422e8 100644 --- a/src/runtime/sockets/WDSSocket.js +++ b/src/runtime/sockets/WDSSocket.js @@ -1,8 +1,8 @@ -/* global __resourceQuery, __webpack_dev_server_client__ */ +/* global __webpack_dev_server_client__ */ const url = require('native-url'); -const parseURLSearchParams = require('./utils/parseURLSearchParams'); +const getResourceQuery = require('./utils/getResourceQuery'); /** * Initializes a socket server for HMR for webpack-dev-server. @@ -12,16 +12,16 @@ const parseURLSearchParams = require('./utils/parseURLSearchParams'); function initWDSSocket(messageHandler) { if (typeof __webpack_dev_server_client__ !== 'undefined') { // Get config overrides from webpack __resourceQuery global - const overrides = parseURLSearchParams(__resourceQuery); + const query = getResourceQuery(); const SocketClient = __webpack_dev_server_client__; // TODO: Support usage of custom sockets after WDS 4.0 is released // Ref: https://github.com/webpack/webpack-dev-server/pull/2055 const connection = new SocketClient( url.format({ protocol: window.location.protocol, - hostname: overrides.sockHost || window.location.hostname, - port: overrides.sockPort || window.location.port, - pathname: overrides.sockPath || '/sockjs-node', + hostname: query.sockHost || window.location.hostname, + port: query.sockPort || window.location.port, + pathname: query.sockPath || '/sockjs-node', }) ); diff --git a/src/runtime/sockets/utils/getResourceQuery.js b/src/runtime/sockets/utils/getResourceQuery.js new file mode 100644 index 00000000..4bbe045d --- /dev/null +++ b/src/runtime/sockets/utils/getResourceQuery.js @@ -0,0 +1,41 @@ +/* global __resourceQuery */ + +/** + * Parse webpack `__resourceQuery` string into an object. + * @see https://webpack.js.org/api/module-variables/#__resourcequery-webpack-specific + * @param {string} [__resourceQuery] + * @returns {*} + */ +function getResourceQuery() { + const params = {}; + + var query = ''; + if (typeof __resourceQuery === 'string') { + query = __resourceQuery; + } + + /** + * Map __resourceQuery string such as `?foo1=bar1&foo2=bar2`: + * - remove `?` from the start + * - split from `&` + * - split from `=` + * The mapped format will be [['foo1', 'bar1'], ['foo2', 'bar2']] + */ + const entries = query + .replace(/^\?/, '') + .split('&') + .map(function (entry) { + return entry.split('='); + }); + + // Add all entries to the overrides object + entries.forEach(function (entry) { + const key = entry[0]; + const value = entry[1]; + params[key] = value; + }); + + return params; +} + +module.exports = getResourceQuery; diff --git a/src/runtime/sockets/utils/parseURLSearchParams.js b/src/runtime/sockets/utils/parseURLSearchParams.js deleted file mode 100644 index 8dedc36f..00000000 --- a/src/runtime/sockets/utils/parseURLSearchParams.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Parse URLSearchParams from a string like `?key=value&foo=ba` - * @param {string} queryString - * @returns {*} - */ -function parseURLSearchParams(queryString) { - const params = {}; - - // Decode any possible encoded characters and remove `?` from start - const query = decodeURIComponent(queryString).replace(/^\?/, ''); - - // Split string like `key=value&foo=bar`, first from &, and then = - // The structure will be `[['key', 'value'], ['foo', 'bar']]` - const entries = query.split('&').map(function (entry) { - return entry.split('='); - }); - - // Add all entries to the overrides object - entries.forEach(function (entry) { - const key = entry[0]; - const value = entry[1]; - params[key] = value; - }); - - return params; -} - -module.exports = parseURLSearchParams; diff --git a/test/unit/getResourceQuery.test.js b/test/unit/getResourceQuery.test.js new file mode 100644 index 00000000..8a396a61 --- /dev/null +++ b/test/unit/getResourceQuery.test.js @@ -0,0 +1,32 @@ +const getResourceQuery = require('../../src/runtime/sockets/utils/getResourceQuery'); + +describe('getResourceQuery', () => { + let previousQuery; + + beforeEach(() => { + previousQuery = global.__resourceQuery; + }); + + afterEach(() => { + global.__resourceQuery = previousQuery; + }); + + it('should parse __resourceQuery', () => { + global.__resourceQuery = '?sockHost=localhost&sockPort=8080&sockPath=/__socket'; + expect(getResourceQuery()).toEqual({ + sockHost: 'localhost', + sockPath: '/__socket', + sockPort: '8080', + }); + }); + + it('should handle undefined __resourceQuery', () => { + delete global.__resourceQuery; + expect(getResourceQuery()).toEqual({}); + }); + + it('should handle empty string __resourceQuery', () => { + global.__resourceQuery = ''; + expect(getResourceQuery()).toEqual({}); + }); +});