function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /* global __resourceQuery, __webpack_hash__ */ /// import webpackHotLog from "webpack/hot/log.js"; import stripAnsi from "./utils/stripAnsi.js"; import parseURL from "./utils/parseURL.js"; import socket from "./socket.js"; import { formatProblem, show, hide } from "./overlay.js"; import { log, logEnabledFeatures, setLogLevel } from "./utils/log.js"; import sendMessage from "./utils/sendMessage.js"; import reloadApp from "./utils/reloadApp.js"; import createSocketURL from "./utils/createSocketURL.js"; /** * @typedef {Object} Options * @property {boolean} hot * @property {boolean} liveReload * @property {boolean} progress * @property {boolean | { warnings?: boolean, errors?: boolean, trustedTypesPolicyName?: string }} overlay * @property {string} [logging] * @property {number} [reconnect] */ /** * @typedef {Object} Status * @property {boolean} isUnloading * @property {string} currentHash * @property {string} [previousHash] */ /** * @type {Status} */ var status = { isUnloading: false, // TODO Workaround for webpack v4, `__webpack_hash__` is not replaced without HotModuleReplacement // eslint-disable-next-line camelcase currentHash: typeof __webpack_hash__ !== "undefined" ? __webpack_hash__ : "" }; /** @type {Options} */ var options = { hot: false, liveReload: false, progress: false, overlay: false }; var parsedResourceQuery = parseURL(__resourceQuery); var enabledFeatures = { "Hot Module Replacement": false, "Live Reloading": 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 }, options.overlay); } enabledFeatures.Overlay = true; } if (parsedResourceQuery.logging) { options.logging = parsedResourceQuery.logging; } if (typeof parsedResourceQuery.reconnect !== "undefined") { options.reconnect = Number(parsedResourceQuery.reconnect); } logEnabledFeatures(enabledFeatures); /** * @param {string} level */ 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); } self.addEventListener("beforeunload", function () { status.isUnloading = true; }); 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) { hide(); } 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; }, /** * @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, ".")); } sendMessage("Progress", data); }, "still-ok": function stillOk() { log.info("Nothing changed."); if (options.overlay) { hide(); } sendMessage("StillOk"); }, ok: function ok() { sendMessage("Ok"); if (options.overlay) { hide(); } reloadApp(options, status); }, // TODO: remove in v5 in favor of 'static-changed' /** * @param {string} file */ "content-changed": function contentChanged(file) { log.info("".concat(file ? "\"".concat(file, "\"") : "Content", " from static directory was changed. Reloading...")); self.location.reload(); }, /** * @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 needShowOverlayForWarnings = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.warnings; if (needShowOverlayForWarnings) { var trustedTypesPolicyName = typeof options.overlay === "object" && options.overlay.trustedTypesPolicyName; show("warning", _warnings, trustedTypesPolicyName || null); } 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 needShowOverlayForErrors = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.errors; if (needShowOverlayForErrors) { var trustedTypesPolicyName = typeof options.overlay === "object" && options.overlay.trustedTypesPolicyName; show("error", _errors, trustedTypesPolicyName || null); } }, /** * @param {Error} error */ error: function error(_error) { log.error(_error); }, close: function close() { log.info("Disconnected!"); if (options.overlay) { hide(); } sendMessage("Close"); } }; var socketURL = createSocketURL(parsedResourceQuery); socket(socketURL, onSocketMessage, options.reconnect);