123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 |
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
- /* global __resourceQuery, __webpack_hash__ */
- /// <reference types="webpack/module" />
- import webpackHotLog from "webpack/hot/log.js";
- import hotEmitter from "webpack/hot/emitter.js";
- import socket from "./socket.js";
- import { formatProblem, createOverlay } from "./overlay.js";
- import { log, setLogLevel } from "./utils/log.js";
- import sendMessage from "./utils/sendMessage.js";
- import { isProgressSupported, defineProgressElement } from "./progress.js";
- /**
- * @typedef {Object} OverlayOptions
- * @property {boolean | (error: Error) => boolean} [warnings]
- * @property {boolean | (error: Error) => boolean} [errors]
- * @property {boolean | (error: Error) => boolean} [runtimeErrors]
- * @property {string} [trustedTypesPolicyName]
- */
- /**
- * @typedef {Object} Options
- * @property {boolean} hot
- * @property {boolean} liveReload
- * @property {boolean} progress
- * @property {boolean | OverlayOptions} overlay
- * @property {string} [logging]
- * @property {number} [reconnect]
- */
- /**
- * @typedef {Object} Status
- * @property {boolean} isUnloading
- * @property {string} currentHash
- * @property {string} [previousHash]
- */
- /**
- * @param {boolean | { warnings?: boolean | string; errors?: boolean | string; runtimeErrors?: boolean | string; }} overlayOptions
- */
- var decodeOverlayOptions = function decodeOverlayOptions(overlayOptions) {
- if (typeof overlayOptions === "object") {
- ["warnings", "errors", "runtimeErrors"].forEach(function (property) {
- if (typeof overlayOptions[property] === "string") {
- var overlayFilterFunctionString = decodeURIComponent(overlayOptions[property]);
- // eslint-disable-next-line no-new-func
- overlayOptions[property] = new Function("message", "var callback = ".concat(overlayFilterFunctionString, "\n return callback(message)"));
- }
- });
- }
- };
- /**
- * @type {Status}
- */
- var status = {
- isUnloading: false,
- // eslint-disable-next-line camelcase
- currentHash: __webpack_hash__
- };
- /**
- * @returns {string}
- */
- var getCurrentScriptSource = function 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.
- var scriptElements = document.scripts || [];
- var scriptElementsWithSrc = Array.prototype.filter.call(scriptElements, function (element) {
- return element.getAttribute("src");
- });
- if (scriptElementsWithSrc.length > 0) {
- var 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 }}
- */
- var parseURL = function parseURL(resourceQuery) {
- /** @type {{ [key: string]: string }} */
- var result = {};
- if (typeof resourceQuery === "string" && resourceQuery !== "") {
- var searchParams = resourceQuery.slice(1).split("&");
- for (var i = 0; i < searchParams.length; i++) {
- var pair = searchParams[i].split("=");
- result[pair[0]] = decodeURIComponent(pair[1]);
- }
- } else {
- // Else, get the url from the <script> this file was called with.
- var scriptSource = getCurrentScriptSource();
- var scriptSourceURL;
- try {
- // The placeholder `baseURL` with `window.location.href`,
- // is to allow parsing of path-relative or protocol-relative URLs,
- // and will have no effect if `scriptSource` is a fully valid URL.
- scriptSourceURL = new URL(scriptSource, self.location.href);
- } catch (error) {
- // URL parsing failed, do nothing.
- // We will still proceed to see if we can recover using `resourceQuery`
- }
- if (scriptSourceURL) {
- result = scriptSourceURL;
- result.fromCurrentScript = true;
- }
- }
- return result;
- };
- var parsedResourceQuery = parseURL(__resourceQuery);
- var enabledFeatures = {
- "Hot Module Replacement": false,
- "Live Reloading": false,
- Progress: false,
- Overlay: false
- };
- /** @type {Options} */
- var options = {
- hot: false,
- liveReload: false,
- progress: false,
- overlay: false
- };
- if (parsedResourceQuery.hot === "true") {
- options.hot = true;
- enabledFeatures["Hot Module Replacement"] = true;
- }
- if (parsedResourceQuery["live-reload"] === "true") {
- options.liveReload = true;
- enabledFeatures["Live Reloading"] = true;
- }
- if (parsedResourceQuery.progress === "true") {
- options.progress = true;
- enabledFeatures.Progress = true;
- }
- if (parsedResourceQuery.overlay) {
- try {
- options.overlay = JSON.parse(parsedResourceQuery.overlay);
- } catch (e) {
- log.error("Error parsing overlay options from resource query:", e);
- }
- // Fill in default "true" params for partially-specified objects.
- if (typeof options.overlay === "object") {
- options.overlay = _objectSpread({
- errors: true,
- warnings: true,
- runtimeErrors: true
- }, options.overlay);
- decodeOverlayOptions(options.overlay);
- }
- enabledFeatures.Overlay = true;
- }
- if (parsedResourceQuery.logging) {
- options.logging = parsedResourceQuery.logging;
- }
- if (typeof parsedResourceQuery.reconnect !== "undefined") {
- options.reconnect = Number(parsedResourceQuery.reconnect);
- }
- /**
- * @param {string} level
- */
- var setAllLogLevel = function setAllLogLevel(level) {
- // This is needed because the HMR logger operate separately from dev server logger
- webpackHotLog.setLogLevel(level === "verbose" || level === "log" ? "info" : level);
- setLogLevel(level);
- };
- if (options.logging) {
- setAllLogLevel(options.logging);
- }
- var logEnabledFeatures = function logEnabledFeatures(features) {
- var listEnabledFeatures = Object.keys(features);
- if (!features || listEnabledFeatures.length === 0) {
- return;
- }
- var logString = "Server started:";
- // Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
- for (var i = 0; i < listEnabledFeatures.length; i++) {
- var key = listEnabledFeatures[i];
- logString += " ".concat(key, " ").concat(features[key] ? "enabled" : "disabled", ",");
- }
- // replace last comma with a period
- logString = logString.slice(0, -1).concat(".");
- log.info(logString);
- };
- logEnabledFeatures(enabledFeatures);
- self.addEventListener("beforeunload", function () {
- status.isUnloading = true;
- });
- var overlay = typeof window !== "undefined" ? createOverlay(typeof options.overlay === "object" ? {
- trustedTypesPolicyName: options.overlay.trustedTypesPolicyName,
- catchRuntimeError: options.overlay.runtimeErrors
- } : {
- trustedTypesPolicyName: false,
- catchRuntimeError: options.overlay
- }) : {
- send: function send() {}
- };
- /**
- * @param {Options} options
- * @param {Status} currentStatus
- */
- var reloadApp = function reloadApp(_ref, currentStatus) {
- var hot = _ref.hot,
- liveReload = _ref.liveReload;
- if (currentStatus.isUnloading) {
- return;
- }
- var currentHash = currentStatus.currentHash,
- previousHash = currentStatus.previousHash;
- var isInitial = currentHash.indexOf(/** @type {string} */previousHash) >= 0;
- if (isInitial) {
- return;
- }
- /**
- * @param {Window} rootWindow
- * @param {number} intervalId
- */
- function applyReload(rootWindow, intervalId) {
- clearInterval(intervalId);
- log.info("App updated. Reloading...");
- rootWindow.location.reload();
- }
- var search = self.location.search.toLowerCase();
- var allowToHot = search.indexOf("webpack-dev-server-hot=false") === -1;
- var allowToLiveReload = search.indexOf("webpack-dev-server-live-reload=false") === -1;
- if (hot && allowToHot) {
- log.info("App hot update...");
- hotEmitter.emit("webpackHotUpdate", currentStatus.currentHash);
- if (typeof self !== "undefined" && self.window) {
- // broadcast update to window
- self.postMessage("webpackHotUpdate".concat(currentStatus.currentHash), "*");
- }
- }
- // allow refreshing the page only if liveReload isn't disabled
- else if (liveReload && allowToLiveReload) {
- var rootWindow = self;
- // use parent window for reload (in case we're in an iframe with no valid src)
- var intervalId = self.setInterval(function () {
- if (rootWindow.location.protocol !== "about:") {
- // reload immediately if protocol is valid
- applyReload(rootWindow, intervalId);
- } else {
- rootWindow = rootWindow.parent;
- if (rootWindow.parent === rootWindow) {
- // if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways
- applyReload(rootWindow, intervalId);
- }
- }
- });
- }
- };
- var ansiRegex = new RegExp(["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|"), "g");
- /**
- *
- * Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string.
- * Adapted from code originally released by Sindre Sorhus
- * Licensed the MIT License
- *
- * @param {string} string
- * @return {string}
- */
- var stripAnsi = function stripAnsi(string) {
- if (typeof string !== "string") {
- throw new TypeError("Expected a `string`, got `".concat(typeof string, "`"));
- }
- return string.replace(ansiRegex, "");
- };
- var onSocketMessage = {
- hot: function hot() {
- if (parsedResourceQuery.hot === "false") {
- return;
- }
- options.hot = true;
- },
- liveReload: function liveReload() {
- if (parsedResourceQuery["live-reload"] === "false") {
- return;
- }
- options.liveReload = true;
- },
- invalid: function invalid() {
- log.info("App updated. Recompiling...");
- // Fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
- if (options.overlay) {
- overlay.send({
- type: "DISMISS"
- });
- }
- sendMessage("Invalid");
- },
- /**
- * @param {string} hash
- */
- hash: function hash(_hash) {
- status.previousHash = status.currentHash;
- status.currentHash = _hash;
- },
- logging: setAllLogLevel,
- /**
- * @param {boolean} value
- */
- overlay: function overlay(value) {
- if (typeof document === "undefined") {
- return;
- }
- options.overlay = value;
- decodeOverlayOptions(options.overlay);
- },
- /**
- * @param {number} value
- */
- reconnect: function reconnect(value) {
- if (parsedResourceQuery.reconnect === "false") {
- return;
- }
- options.reconnect = value;
- },
- /**
- * @param {boolean} value
- */
- progress: function progress(value) {
- options.progress = value;
- },
- /**
- * @param {{ pluginName?: string, percent: number, msg: string }} data
- */
- "progress-update": function progressUpdate(data) {
- if (options.progress) {
- log.info("".concat(data.pluginName ? "[".concat(data.pluginName, "] ") : "").concat(data.percent, "% - ").concat(data.msg, "."));
- }
- if (isProgressSupported()) {
- if (typeof options.progress === "string") {
- var progress = document.querySelector("wds-progress");
- if (!progress) {
- defineProgressElement();
- progress = document.createElement("wds-progress");
- document.body.appendChild(progress);
- }
- progress.setAttribute("progress", data.percent);
- progress.setAttribute("type", options.progress);
- }
- }
- sendMessage("Progress", data);
- },
- "still-ok": function stillOk() {
- log.info("Nothing changed.");
- if (options.overlay) {
- overlay.send({
- type: "DISMISS"
- });
- }
- sendMessage("StillOk");
- },
- ok: function ok() {
- sendMessage("Ok");
- if (options.overlay) {
- overlay.send({
- type: "DISMISS"
- });
- }
- reloadApp(options, status);
- },
- /**
- * @param {string} file
- */
- "static-changed": function staticChanged(file) {
- log.info("".concat(file ? "\"".concat(file, "\"") : "Content", " from static directory was changed. Reloading..."));
- self.location.reload();
- },
- /**
- * @param {Error[]} warnings
- * @param {any} params
- */
- warnings: function warnings(_warnings, params) {
- log.warn("Warnings while compiling.");
- var printableWarnings = _warnings.map(function (error) {
- var _formatProblem = formatProblem("warning", error),
- header = _formatProblem.header,
- body = _formatProblem.body;
- return "".concat(header, "\n").concat(stripAnsi(body));
- });
- sendMessage("Warnings", printableWarnings);
- for (var i = 0; i < printableWarnings.length; i++) {
- log.warn(printableWarnings[i]);
- }
- var overlayWarningsSetting = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.warnings;
- if (overlayWarningsSetting) {
- var warningsToDisplay = typeof overlayWarningsSetting === "function" ? _warnings.filter(overlayWarningsSetting) : _warnings;
- if (warningsToDisplay.length) {
- overlay.send({
- type: "BUILD_ERROR",
- level: "warning",
- messages: _warnings
- });
- }
- }
- if (params && params.preventReloading) {
- return;
- }
- reloadApp(options, status);
- },
- /**
- * @param {Error[]} errors
- */
- errors: function errors(_errors) {
- log.error("Errors while compiling. Reload prevented.");
- var printableErrors = _errors.map(function (error) {
- var _formatProblem2 = formatProblem("error", error),
- header = _formatProblem2.header,
- body = _formatProblem2.body;
- return "".concat(header, "\n").concat(stripAnsi(body));
- });
- sendMessage("Errors", printableErrors);
- for (var i = 0; i < printableErrors.length; i++) {
- log.error(printableErrors[i]);
- }
- var overlayErrorsSettings = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.errors;
- if (overlayErrorsSettings) {
- var errorsToDisplay = typeof overlayErrorsSettings === "function" ? _errors.filter(overlayErrorsSettings) : _errors;
- if (errorsToDisplay.length) {
- overlay.send({
- type: "BUILD_ERROR",
- level: "error",
- messages: _errors
- });
- }
- }
- },
- /**
- * @param {Error} error
- */
- error: function error(_error) {
- log.error(_error);
- },
- close: function close() {
- log.info("Disconnected!");
- if (options.overlay) {
- overlay.send({
- type: "DISMISS"
- });
- }
- sendMessage("Close");
- }
- };
- /**
- * @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL
- * @returns {string}
- */
- var formatURL = function formatURL(objURL) {
- var protocol = objURL.protocol || "";
- if (protocol && protocol.substr(-1) !== ":") {
- protocol += ":";
- }
- var auth = objURL.auth || "";
- if (auth) {
- auth = encodeURIComponent(auth);
- auth = auth.replace(/%3A/i, ":");
- auth += "@";
- }
- var host = "";
- if (objURL.hostname) {
- host = auth + (objURL.hostname.indexOf(":") === -1 ? objURL.hostname : "[".concat(objURL.hostname, "]"));
- if (objURL.port) {
- host += ":".concat(objURL.port);
- }
- }
- var pathname = objURL.pathname || "";
- if (objURL.slashes) {
- host = "//".concat(host || "");
- if (pathname && pathname.charAt(0) !== "/") {
- pathname = "/".concat(pathname);
- }
- } else if (!host) {
- host = "";
- }
- var search = objURL.search || "";
- if (search && search.charAt(0) !== "?") {
- search = "?".concat(search);
- }
- var hash = objURL.hash || "";
- if (hash && hash.charAt(0) !== "#") {
- hash = "#".concat(hash);
- }
- pathname = pathname.replace(/[?#]/g,
- /**
- * @param {string} match
- * @returns {string}
- */
- function (match) {
- return encodeURIComponent(match);
- });
- search = search.replace("#", "%23");
- return "".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);
- };
- /**
- * @param {URL & { fromCurrentScript?: boolean }} parsedURL
- * @returns {string}
- */
- var createSocketURL = function createSocketURL(parsedURL) {
- var hostname = parsedURL.hostname;
- // Node.js module parses it as `::`
- // `new URL(urlString, [baseURLString])` parses it as '[::]'
- var isInAddrAny = hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]";
- // why do we need this check?
- // hostname n/a for file protocol (example, when using electron, ionic)
- // see: https://github.com/webpack/webpack-dev-server/pull/384
- if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf("http") === 0) {
- hostname = self.location.hostname;
- }
- var socketURLProtocol = parsedURL.protocol || self.location.protocol;
- // When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
- if (socketURLProtocol === "auto:" || hostname && isInAddrAny && self.location.protocol === "https:") {
- socketURLProtocol = self.location.protocol;
- }
- socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, "ws");
- var socketURLAuth = "";
- // `new URL(urlString, [baseURLstring])` doesn't have `auth` property
- // Parse authentication credentials in case we need them
- if (parsedURL.username) {
- socketURLAuth = parsedURL.username;
- // Since HTTP basic authentication does not allow empty username,
- // we only include password if the username is not empty.
- if (parsedURL.password) {
- // Result: <username>:<password>
- socketURLAuth = socketURLAuth.concat(":", parsedURL.password);
- }
- }
- // In case the host is a raw IPv6 address, it can be enclosed in
- // the brackets as the brackets are needed in the final URL string.
- // Need to remove those as url.format blindly adds its own set of brackets
- // if the host string contains colons. That would lead to non-working
- // double brackets (e.g. [[::]]) host
- //
- // All of these web socket url params are optionally passed in through resourceQuery,
- // so we need to fall back to the default if they are not provided
- var socketURLHostname = (hostname || self.location.hostname || "localhost").replace(/^\[(.*)\]$/, "$1");
- var socketURLPort = parsedURL.port;
- if (!socketURLPort || socketURLPort === "0") {
- socketURLPort = self.location.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.
- var socketURLPathname = "/ws";
- if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
- socketURLPathname = parsedURL.pathname;
- }
- return formatURL({
- protocol: socketURLProtocol,
- auth: socketURLAuth,
- hostname: socketURLHostname,
- port: socketURLPort,
- pathname: socketURLPathname,
- slashes: true
- });
- };
- var socketURL = createSocketURL(parsedResourceQuery);
- socket(socketURL, onSocketMessage, options.reconnect);
- export { getCurrentScriptSource, parseURL, createSocketURL };
|