diff --git a/.cspell.json b/.cspell.json index 75ccb46d8d..817c0ee483 100644 --- a/.cspell.json +++ b/.cspell.json @@ -2,6 +2,7 @@ "version": "0.2", "language": "en,en-gb", "words": [ + "apos", "camelcase", "tapable", "sockjs", diff --git a/client-src/index.js b/client-src/index.js index d6614a7a67..522ae993db 100644 --- a/client-src/index.js +++ b/client-src/index.js @@ -1,14 +1,11 @@ /* global __resourceQuery, __webpack_hash__ */ /// import webpackHotLog from "webpack/hot/log.js"; -import stripAnsi from "./utils/stripAnsi.js"; -import parseURL from "./utils/parseURL.js"; +import hotEmitter from "webpack/hot/emitter.js"; import socket from "./socket.js"; import { formatProblem, createOverlay } from "./overlay.js"; -import { log, logEnabledFeatures, setLogLevel } from "./utils/log.js"; +import { log, setLogLevel } from "./utils/log.js"; import sendMessage from "./utils/sendMessage.js"; -import reloadApp from "./utils/reloadApp.js"; -import createSocketURL from "./utils/createSocketURL.js"; import { isProgressSupported, defineProgressElement } from "./progress.js"; /** @@ -48,13 +45,11 @@ const decodeOverlayOptions = (overlayOptions) => { ); // eslint-disable-next-line no-new-func - const overlayFilterFunction = new Function( + overlayOptions[property] = new Function( "message", `var callback = ${overlayFilterFunctionString} return callback(message)`, ); - - overlayOptions[property] = overlayFilterFunction; } }); } @@ -69,13 +64,75 @@ const status = { currentHash: __webpack_hash__, }; -/** @type {Options} */ -const options = { - hot: false, - liveReload: false, - progress: false, - overlay: false, +/** + * @returns {string} + */ +const getCurrentScriptSource = () => { + // `document.currentScript` is the most accurate way to find the current script, + // but is not supported in all browsers. + if (document.currentScript) { + return document.currentScript.getAttribute("src"); + } + + // Fallback to getting all scripts running in the document. + const scriptElements = document.scripts || []; + const scriptElementsWithSrc = Array.prototype.filter.call( + scriptElements, + (element) => element.getAttribute("src"), + ); + + if (scriptElementsWithSrc.length > 0) { + const currentScript = + scriptElementsWithSrc[scriptElementsWithSrc.length - 1]; + + return currentScript.getAttribute("src"); + } + + // Fail as there was no script to use. + throw new Error("[webpack-dev-server] Failed to get current script source."); }; + +/** + * @param {string} resourceQuery + * @returns {{ [key: string]: string | boolean }} + */ +const parseURL = (resourceQuery) => { + /** @type {{ [key: string]: string }} */ + let result = {}; + + if (typeof resourceQuery === "string" && resourceQuery !== "") { + const searchParams = resourceQuery.slice(1).split("&"); + + for (let i = 0; i < searchParams.length; i++) { + const pair = searchParams[i].split("="); + + result[pair[0]] = decodeURIComponent(pair[1]); + } + } else { + // Else, get the url from the