diff --git a/src/loader.js b/src/loader.js
index 2e182aa5..5c0b04b1 100644
--- a/src/loader.js
+++ b/src/loader.js
@@ -44,22 +44,31 @@ const MiniCssExtractPlugin = require("./index");
* @returns {string}
*/
function hotLoader(content, context) {
- const accept = context.locals
- ? ""
- : "module.hot.accept(undefined, cssReload);";
-
+ const localsJsonString = JSON.stringify(JSON.stringify(context.locals));
return `${content}
if(module.hot) {
- // ${Date.now()}
- var cssReload = require(${stringifyRequest(
- context.loaderContext,
- path.join(__dirname, "hmr/hotModuleReplacement.js")
- )})(module.id, ${JSON.stringify({
- ...context.options,
- locals: !!context.locals,
- })});
- module.hot.dispose(cssReload);
- ${accept}
+ (function() {
+ var localsJsonString = ${localsJsonString};
+ // ${Date.now()}
+ var cssReload = require(${stringifyRequest(
+ context.loaderContext,
+ path.join(__dirname, "hmr/hotModuleReplacement.js")
+ )})(module.id, ${JSON.stringify(context.options)});
+ // only invalidate when locals change
+ if (
+ module.hot.data &&
+ module.hot.data.value &&
+ module.hot.data.value !== localsJsonString
+ ) {
+ module.hot.invalidate();
+ } else {
+ module.hot.accept();
+ }
+ module.hot.dispose(function(data) {
+ data.value = localsJsonString;
+ cssReload();
+ });
+ })();
}
`;
}
@@ -563,3 +572,4 @@ function loader(content) {
module.exports = loader;
module.exports.pitch = pitch;
+module.exports.hotLoader = hotLoader;
diff --git a/test/HMR.test.js b/test/HMR.test.js
index 79ee30e6..1c781d9b 100644
--- a/test/HMR.test.js
+++ b/test/HMR.test.js
@@ -5,6 +5,7 @@
/* eslint-disable no-console */
import hotModuleReplacement from "../src/hmr/hotModuleReplacement";
+import { hotLoader } from "../src/loader";
function getLoadEvent() {
const event = document.createEvent("Event");
@@ -361,4 +362,29 @@ describe("HMR", () => {
done();
}, 100);
});
+
+ it("hotLoader works for non-locals", () => {
+ const o = Date.now;
+ Date.now = () => 1;
+ const code = hotLoader("//content;", {
+ loaderContext: {
+ context: __dirname,
+ },
+ });
+ Date.now = o;
+ expect(code).toMatchSnapshot();
+ });
+
+ it("hotLoader works for locals", () => {
+ const o = Date.now;
+ Date.now = () => 1;
+ const code = hotLoader("//content;", {
+ loaderContext: {
+ context: __dirname,
+ },
+ locals: { foo: "bar" },
+ });
+ Date.now = o;
+ expect(code).toMatchSnapshot();
+ });
});
diff --git a/test/__snapshots__/HMR.test.js.snap b/test/__snapshots__/HMR.test.js.snap
index ee4d6eef..608bd559 100644
--- a/test/__snapshots__/HMR.test.js.snap
+++ b/test/__snapshots__/HMR.test.js.snap
@@ -1,5 +1,57 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`HMR hotLoader works for locals 1`] = `
+"//content;
+ if(module.hot) {
+ (function() {
+ var localsJsonString = \\"{\\\\\\"foo\\\\\\":\\\\\\"bar\\\\\\"}\\";
+ // 1
+ var cssReload = require(\\"../src/hmr/hotModuleReplacement.js\\")(module.id, undefined);
+ // only invalidate when locals change
+ if (
+ module.hot.data &&
+ module.hot.data.value &&
+ module.hot.data.value !== localsJsonString
+ ) {
+ module.hot.invalidate();
+ } else {
+ module.hot.accept();
+ }
+ module.hot.dispose(function(data) {
+ data.value = localsJsonString;
+ cssReload();
+ });
+ })();
+ }
+ "
+`;
+
+exports[`HMR hotLoader works for non-locals 1`] = `
+"//content;
+ if(module.hot) {
+ (function() {
+ var localsJsonString = undefined;
+ // 1
+ var cssReload = require(\\"../src/hmr/hotModuleReplacement.js\\")(module.id, undefined);
+ // only invalidate when locals change
+ if (
+ module.hot.data &&
+ module.hot.data.value &&
+ module.hot.data.value !== localsJsonString
+ ) {
+ module.hot.invalidate();
+ } else {
+ module.hot.accept();
+ }
+ module.hot.dispose(function(data) {
+ data.value = localsJsonString;
+ cssReload();
+ });
+ })();
+ }
+ "
+`;
+
exports[`HMR should handle error event 1`] = `"[HMR] css reload %s"`;
exports[`HMR should handle error event 2`] = `""`;
diff --git a/test/cases/hmr-locals/expected/main.css b/test/cases/hmr-locals/expected/main.css
new file mode 100644
index 00000000..c5589a3f
--- /dev/null
+++ b/test/cases/hmr-locals/expected/main.css
@@ -0,0 +1,7 @@
+/*!************************************************************************************************!*\
+ !*** css ../../../node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./index.css ***!
+ \************************************************************************************************/
+.VoofDB21D_QzDbRdwMiY {
+ color: red;
+}
+
diff --git a/test/cases/hmr-locals/expected/main.js b/test/cases/hmr-locals/expected/main.js
new file mode 100644
index 00000000..69b2e238
--- /dev/null
+++ b/test/cases/hmr-locals/expected/main.js
@@ -0,0 +1,1587 @@
+/******/ (() => { // webpackBootstrap
+/******/ var __webpack_modules__ = ({
+
+/***/ "../../../src/hmr/hotModuleReplacement.js":
+/*!************************************************!*\
+ !*** ../../../src/hmr/hotModuleReplacement.js ***!
+ \************************************************/
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+/* eslint-env browser */
+/*
+ eslint-disable
+ no-console,
+ func-names
+*/
+
+/** @typedef {any} TODO */
+
+const normalizeUrl = __webpack_require__(/*! ./normalize-url */ "../../../src/hmr/normalize-url.js");
+
+const srcByModuleId = Object.create(null);
+
+const noDocument = typeof document === "undefined";
+
+const { forEach } = Array.prototype;
+
+/**
+ * @param {function} fn
+ * @param {number} time
+ * @returns {(function(): void)|*}
+ */
+function debounce(fn, time) {
+ let timeout = 0;
+
+ return function () {
+ // @ts-ignore
+ const self = this;
+ // eslint-disable-next-line prefer-rest-params
+ const args = arguments;
+
+ const functionCall = function functionCall() {
+ return fn.apply(self, args);
+ };
+
+ clearTimeout(timeout);
+
+ // @ts-ignore
+ timeout = setTimeout(functionCall, time);
+ };
+}
+
+function noop() {}
+
+/**
+ * @param {TODO} moduleId
+ * @returns {TODO}
+ */
+function getCurrentScriptUrl(moduleId) {
+ let src = srcByModuleId[moduleId];
+
+ if (!src) {
+ if (document.currentScript) {
+ ({ src } = /** @type {HTMLScriptElement} */ (document.currentScript));
+ } else {
+ const scripts = document.getElementsByTagName("script");
+ const lastScriptTag = scripts[scripts.length - 1];
+
+ if (lastScriptTag) {
+ ({ src } = lastScriptTag);
+ }
+ }
+
+ srcByModuleId[moduleId] = src;
+ }
+
+ /**
+ * @param {string} fileMap
+ * @returns {null | string[]}
+ */
+ return function (fileMap) {
+ if (!src) {
+ return null;
+ }
+
+ const splitResult = src.split(/([^\\/]+)\.js$/);
+ const filename = splitResult && splitResult[1];
+
+ if (!filename) {
+ return [src.replace(".js", ".css")];
+ }
+
+ if (!fileMap) {
+ return [src.replace(".js", ".css")];
+ }
+
+ return fileMap.split(",").map((mapRule) => {
+ const reg = new RegExp(`${filename}\\.js$`, "g");
+
+ return normalizeUrl(
+ src.replace(reg, `${mapRule.replace(/{fileName}/g, filename)}.css`)
+ );
+ });
+ };
+}
+
+/**
+ * @param {TODO} el
+ * @param {string} [url]
+ */
+function updateCss(el, url) {
+ if (!url) {
+ if (!el.href) {
+ return;
+ }
+
+ // eslint-disable-next-line
+ url = el.href.split("?")[0];
+ }
+
+ if (!isUrlRequest(/** @type {string} */ (url))) {
+ return;
+ }
+
+ if (el.isLoaded === false) {
+ // We seem to be about to replace a css link that hasn't loaded yet.
+ // We're probably changing the same file more than once.
+ return;
+ }
+
+ if (!url || !(url.indexOf(".css") > -1)) {
+ return;
+ }
+
+ // eslint-disable-next-line no-param-reassign
+ el.visited = true;
+
+ const newEl = el.cloneNode();
+
+ newEl.isLoaded = false;
+
+ newEl.addEventListener("load", () => {
+ if (newEl.isLoaded) {
+ return;
+ }
+
+ newEl.isLoaded = true;
+ el.parentNode.removeChild(el);
+ });
+
+ newEl.addEventListener("error", () => {
+ if (newEl.isLoaded) {
+ return;
+ }
+
+ newEl.isLoaded = true;
+ el.parentNode.removeChild(el);
+ });
+
+ newEl.href = `${url}?${Date.now()}`;
+
+ if (el.nextSibling) {
+ el.parentNode.insertBefore(newEl, el.nextSibling);
+ } else {
+ el.parentNode.appendChild(newEl);
+ }
+}
+
+/**
+ * @param {string} href
+ * @param {TODO} src
+ * @returns {TODO}
+ */
+function getReloadUrl(href, src) {
+ let ret;
+
+ // eslint-disable-next-line no-param-reassign
+ href = normalizeUrl(href);
+
+ src.some(
+ /**
+ * @param {string} url
+ */
+ // eslint-disable-next-line array-callback-return
+ (url) => {
+ if (href.indexOf(src) > -1) {
+ ret = url;
+ }
+ }
+ );
+
+ return ret;
+}
+
+/**
+ * @param {string} [src]
+ * @returns {boolean}
+ */
+function reloadStyle(src) {
+ if (!src) {
+ return false;
+ }
+
+ const elements = document.querySelectorAll("link");
+ let loaded = false;
+
+ forEach.call(elements, (el) => {
+ if (!el.href) {
+ return;
+ }
+
+ const url = getReloadUrl(el.href, src);
+
+ if (!isUrlRequest(url)) {
+ return;
+ }
+
+ if (el.visited === true) {
+ return;
+ }
+
+ if (url) {
+ updateCss(el, url);
+
+ loaded = true;
+ }
+ });
+
+ return loaded;
+}
+
+function reloadAll() {
+ const elements = document.querySelectorAll("link");
+
+ forEach.call(elements, (el) => {
+ if (el.visited === true) {
+ return;
+ }
+
+ updateCss(el);
+ });
+}
+
+/**
+ * @param {string} url
+ * @returns {boolean}
+ */
+function isUrlRequest(url) {
+ // An URL is not an request if
+
+ // It is not http or https
+ if (!/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(url)) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * @param {TODO} moduleId
+ * @param {TODO} options
+ * @returns {TODO}
+ */
+module.exports = function (moduleId, options) {
+ if (noDocument) {
+ console.log("no window.document found, will not HMR CSS");
+
+ return noop;
+ }
+
+ const getScriptSrc = getCurrentScriptUrl(moduleId);
+
+ function update() {
+ const src = getScriptSrc(options.filename);
+ const reloaded = reloadStyle(src);
+
+ if (options.locals) {
+ console.log("[HMR] Detected local css modules. Reload all css");
+
+ reloadAll();
+
+ return;
+ }
+
+ if (reloaded) {
+ console.log("[HMR] css reload %s", src.join(" "));
+ } else {
+ console.log("[HMR] Reload all css");
+
+ reloadAll();
+ }
+ }
+
+ return debounce(update, 50);
+};
+
+
+/***/ }),
+
+/***/ "../../../src/hmr/normalize-url.js":
+/*!*****************************************!*\
+ !*** ../../../src/hmr/normalize-url.js ***!
+ \*****************************************/
+/***/ ((module) => {
+
+/* eslint-disable */
+
+/**
+ * @param {string[]} pathComponents
+ * @returns {string}
+ */
+function normalizeUrl(pathComponents) {
+ return pathComponents
+ .reduce(function (accumulator, item) {
+ switch (item) {
+ case "..":
+ accumulator.pop();
+ break;
+ case ".":
+ break;
+ default:
+ accumulator.push(item);
+ }
+
+ return accumulator;
+ }, /** @type {string[]} */ ([]))
+ .join("/");
+}
+
+/**
+ * @param {string} urlString
+ * @returns {string}
+ */
+module.exports = function (urlString) {
+ urlString = urlString.trim();
+
+ if (/^data:/i.test(urlString)) {
+ return urlString;
+ }
+
+ var protocol =
+ urlString.indexOf("//") !== -1 ? urlString.split("//")[0] + "//" : "";
+ var components = urlString.replace(new RegExp(protocol, "i"), "").split("/");
+ var host = components[0].toLowerCase().replace(/\.$/, "");
+
+ components[0] = "";
+
+ var path = normalizeUrl(components);
+
+ return protocol + host + path;
+};
+
+
+/***/ }),
+
+/***/ "./index.css":
+/*!*******************!*\
+ !*** ./index.css ***!
+ \*******************/
+/***/ ((module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+// extracted by mini-css-extract-plugin
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({"x":"VoofDB21D_QzDbRdwMiY"});
+ if(true) {
+ (function() {
+ var localsJsonString = "{\"x\":\"VoofDB21D_QzDbRdwMiY\"}";
+ //
+ var cssReload = __webpack_require__(/*! ../../../src/hmr/hotModuleReplacement.js */ "../../../src/hmr/hotModuleReplacement.js")(module.id, {});
+ // only invalidate when locals change
+ if (
+ module.hot.data &&
+ module.hot.data.value &&
+ module.hot.data.value !== localsJsonString
+ ) {
+ module.hot.invalidate();
+ } else {
+ module.hot.accept();
+ }
+ module.hot.dispose(function(data) {
+ data.value = localsJsonString;
+ cssReload();
+ });
+ })();
+ }
+
+
+/***/ })
+
+/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/ // Check if module is in cache
+/******/ var cachedModule = __webpack_module_cache__[moduleId];
+/******/ if (cachedModule !== undefined) {
+/******/ if (cachedModule.error !== undefined) throw cachedModule.error;
+/******/ return cachedModule.exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = __webpack_module_cache__[moduleId] = {
+/******/ id: moduleId,
+/******/ // no module.loaded needed
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ try {
+/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };
+/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); });
+/******/ module = execOptions.module;
+/******/ execOptions.factory.call(module.exports, module, module.exports, execOptions.require);
+/******/ } catch(e) {
+/******/ module.error = e;
+/******/ throw e;
+/******/ }
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = __webpack_modules__;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = __webpack_module_cache__;
+/******/
+/******/ // expose the module execution interceptor
+/******/ __webpack_require__.i = [];
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/define property getters */
+/******/ (() => {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = (exports, definition) => {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/get javascript update chunk filename */
+/******/ (() => {
+/******/ // This function allow to reference all chunks
+/******/ __webpack_require__.hu = (chunkId) => {
+/******/ // return url for filenames based on template
+/******/ return "" + chunkId + "." + __webpack_require__.h() + ".hot-update.js";
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/get mini-css chunk filename */
+/******/ (() => {
+/******/ // This function allow to reference async chunks
+/******/ __webpack_require__.miniCssF = (chunkId) => {
+/******/ // return url for filenames based on template
+/******/ return undefined;
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/get update manifest filename */
+/******/ (() => {
+/******/ __webpack_require__.hmrF = () => ("main." + __webpack_require__.h() + ".hot-update.json");
+/******/ })();
+/******/
+/******/ /* webpack/runtime/getFullHash */
+/******/ (() => {
+/******/ __webpack_require__.h = () => ("xxxxxxxxxxxxxxxxxxxxxx")
+/******/ })();
+/******/
+/******/ /* webpack/runtime/global */
+/******/ (() => {
+/******/ __webpack_require__.g = (function() {
+/******/ if (typeof globalThis === 'object') return globalThis;
+/******/ try {
+/******/ return this || new Function('return this')();
+/******/ } catch (e) {
+/******/ if (typeof window === 'object') return window;
+/******/ }
+/******/ })();
+/******/ })();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ (() => {
+/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
+/******/ })();
+/******/
+/******/ /* webpack/runtime/load script */
+/******/ (() => {
+/******/ var inProgress = {};
+/******/ // data-webpack is not used as build has no uniqueName
+/******/ // loadScript function to load a script via script tag
+/******/ __webpack_require__.l = (url, done, key, chunkId) => {
+/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
+/******/ var script, needAttach;
+/******/ if(key !== undefined) {
+/******/ var scripts = document.getElementsByTagName("script");
+/******/ for(var i = 0; i < scripts.length; i++) {
+/******/ var s = scripts[i];
+/******/ if(s.getAttribute("src") == url) { script = s; break; }
+/******/ }
+/******/ }
+/******/ if(!script) {
+/******/ needAttach = true;
+/******/ script = document.createElement('script');
+/******/
+/******/ script.charset = 'utf-8';
+/******/ script.timeout = 120;
+/******/ if (__webpack_require__.nc) {
+/******/ script.setAttribute("nonce", __webpack_require__.nc);
+/******/ }
+/******/
+/******/
+/******/ script.src = url;
+/******/ }
+/******/ inProgress[url] = [done];
+/******/ var onScriptComplete = (prev, event) => {
+/******/ // avoid mem leaks in IE.
+/******/ script.onerror = script.onload = null;
+/******/ clearTimeout(timeout);
+/******/ var doneFns = inProgress[url];
+/******/ delete inProgress[url];
+/******/ script.parentNode && script.parentNode.removeChild(script);
+/******/ doneFns && doneFns.forEach((fn) => (fn(event)));
+/******/ if(prev) return prev(event);
+/******/ }
+/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
+/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
+/******/ script.onload = onScriptComplete.bind(null, script.onload);
+/******/ needAttach && document.head.appendChild(script);
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/make namespace object */
+/******/ (() => {
+/******/ // define __esModule on exports
+/******/ __webpack_require__.r = (exports) => {
+/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ }
+/******/ Object.defineProperty(exports, '__esModule', { value: true });
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/hot module replacement */
+/******/ (() => {
+/******/ var currentModuleData = {};
+/******/ var installedModules = __webpack_require__.c;
+/******/
+/******/ // module and require creation
+/******/ var currentChildModule;
+/******/ var currentParents = [];
+/******/
+/******/ // status
+/******/ var registeredStatusHandlers = [];
+/******/ var currentStatus = "idle";
+/******/
+/******/ // while downloading
+/******/ var blockingPromises = 0;
+/******/ var blockingPromisesWaiting = [];
+/******/
+/******/ // The update info
+/******/ var currentUpdateApplyHandlers;
+/******/ var queuedInvalidatedModules;
+/******/
+/******/ __webpack_require__.hmrD = currentModuleData;
+/******/
+/******/ __webpack_require__.i.push(function (options) {
+/******/ var module = options.module;
+/******/ var require = createRequire(options.require, options.id);
+/******/ module.hot = createModuleHotObject(options.id, module);
+/******/ module.parents = currentParents;
+/******/ module.children = [];
+/******/ currentParents = [];
+/******/ options.require = require;
+/******/ });
+/******/
+/******/ __webpack_require__.hmrC = {};
+/******/ __webpack_require__.hmrI = {};
+/******/
+/******/ function createRequire(require, moduleId) {
+/******/ var me = installedModules[moduleId];
+/******/ if (!me) return require;
+/******/ var fn = function (request) {
+/******/ if (me.hot.active) {
+/******/ if (installedModules[request]) {
+/******/ var parents = installedModules[request].parents;
+/******/ if (parents.indexOf(moduleId) === -1) {
+/******/ parents.push(moduleId);
+/******/ }
+/******/ } else {
+/******/ currentParents = [moduleId];
+/******/ currentChildModule = request;
+/******/ }
+/******/ if (me.children.indexOf(request) === -1) {
+/******/ me.children.push(request);
+/******/ }
+/******/ } else {
+/******/ console.warn(
+/******/ "[HMR] unexpected require(" +
+/******/ request +
+/******/ ") from disposed module " +
+/******/ moduleId
+/******/ );
+/******/ currentParents = [];
+/******/ }
+/******/ return require(request);
+/******/ };
+/******/ var createPropertyDescriptor = function (name) {
+/******/ return {
+/******/ configurable: true,
+/******/ enumerable: true,
+/******/ get: function () {
+/******/ return require[name];
+/******/ },
+/******/ set: function (value) {
+/******/ require[name] = value;
+/******/ }
+/******/ };
+/******/ };
+/******/ for (var name in require) {
+/******/ if (Object.prototype.hasOwnProperty.call(require, name) && name !== "e") {
+/******/ Object.defineProperty(fn, name, createPropertyDescriptor(name));
+/******/ }
+/******/ }
+/******/ fn.e = function (chunkId, fetchPriority) {
+/******/ return trackBlockingPromise(require.e(chunkId, fetchPriority));
+/******/ };
+/******/ return fn;
+/******/ }
+/******/
+/******/ function createModuleHotObject(moduleId, me) {
+/******/ var _main = currentChildModule !== moduleId;
+/******/ var hot = {
+/******/ // private stuff
+/******/ _acceptedDependencies: {},
+/******/ _acceptedErrorHandlers: {},
+/******/ _declinedDependencies: {},
+/******/ _selfAccepted: false,
+/******/ _selfDeclined: false,
+/******/ _selfInvalidated: false,
+/******/ _disposeHandlers: [],
+/******/ _main: _main,
+/******/ _requireSelf: function () {
+/******/ currentParents = me.parents.slice();
+/******/ currentChildModule = _main ? undefined : moduleId;
+/******/ __webpack_require__(moduleId);
+/******/ },
+/******/
+/******/ // Module API
+/******/ active: true,
+/******/ accept: function (dep, callback, errorHandler) {
+/******/ if (dep === undefined) hot._selfAccepted = true;
+/******/ else if (typeof dep === "function") hot._selfAccepted = dep;
+/******/ else if (typeof dep === "object" && dep !== null) {
+/******/ for (var i = 0; i < dep.length; i++) {
+/******/ hot._acceptedDependencies[dep[i]] = callback || function () {};
+/******/ hot._acceptedErrorHandlers[dep[i]] = errorHandler;
+/******/ }
+/******/ } else {
+/******/ hot._acceptedDependencies[dep] = callback || function () {};
+/******/ hot._acceptedErrorHandlers[dep] = errorHandler;
+/******/ }
+/******/ },
+/******/ decline: function (dep) {
+/******/ if (dep === undefined) hot._selfDeclined = true;
+/******/ else if (typeof dep === "object" && dep !== null)
+/******/ for (var i = 0; i < dep.length; i++)
+/******/ hot._declinedDependencies[dep[i]] = true;
+/******/ else hot._declinedDependencies[dep] = true;
+/******/ },
+/******/ dispose: function (callback) {
+/******/ hot._disposeHandlers.push(callback);
+/******/ },
+/******/ addDisposeHandler: function (callback) {
+/******/ hot._disposeHandlers.push(callback);
+/******/ },
+/******/ removeDisposeHandler: function (callback) {
+/******/ var idx = hot._disposeHandlers.indexOf(callback);
+/******/ if (idx >= 0) hot._disposeHandlers.splice(idx, 1);
+/******/ },
+/******/ invalidate: function () {
+/******/ this._selfInvalidated = true;
+/******/ switch (currentStatus) {
+/******/ case "idle":
+/******/ currentUpdateApplyHandlers = [];
+/******/ Object.keys(__webpack_require__.hmrI).forEach(function (key) {
+/******/ __webpack_require__.hmrI[key](
+/******/ moduleId,
+/******/ currentUpdateApplyHandlers
+/******/ );
+/******/ });
+/******/ setStatus("ready");
+/******/ break;
+/******/ case "ready":
+/******/ Object.keys(__webpack_require__.hmrI).forEach(function (key) {
+/******/ __webpack_require__.hmrI[key](
+/******/ moduleId,
+/******/ currentUpdateApplyHandlers
+/******/ );
+/******/ });
+/******/ break;
+/******/ case "prepare":
+/******/ case "check":
+/******/ case "dispose":
+/******/ case "apply":
+/******/ (queuedInvalidatedModules = queuedInvalidatedModules || []).push(
+/******/ moduleId
+/******/ );
+/******/ break;
+/******/ default:
+/******/ // ignore requests in error states
+/******/ break;
+/******/ }
+/******/ },
+/******/
+/******/ // Management API
+/******/ check: hotCheck,
+/******/ apply: hotApply,
+/******/ status: function (l) {
+/******/ if (!l) return currentStatus;
+/******/ registeredStatusHandlers.push(l);
+/******/ },
+/******/ addStatusHandler: function (l) {
+/******/ registeredStatusHandlers.push(l);
+/******/ },
+/******/ removeStatusHandler: function (l) {
+/******/ var idx = registeredStatusHandlers.indexOf(l);
+/******/ if (idx >= 0) registeredStatusHandlers.splice(idx, 1);
+/******/ },
+/******/
+/******/ //inherit from previous dispose call
+/******/ data: currentModuleData[moduleId]
+/******/ };
+/******/ currentChildModule = undefined;
+/******/ return hot;
+/******/ }
+/******/
+/******/ function setStatus(newStatus) {
+/******/ currentStatus = newStatus;
+/******/ var results = [];
+/******/
+/******/ for (var i = 0; i < registeredStatusHandlers.length; i++)
+/******/ results[i] = registeredStatusHandlers[i].call(null, newStatus);
+/******/
+/******/ return Promise.all(results).then(function () {});
+/******/ }
+/******/
+/******/ function unblock() {
+/******/ if (--blockingPromises === 0) {
+/******/ setStatus("ready").then(function () {
+/******/ if (blockingPromises === 0) {
+/******/ var list = blockingPromisesWaiting;
+/******/ blockingPromisesWaiting = [];
+/******/ for (var i = 0; i < list.length; i++) {
+/******/ list[i]();
+/******/ }
+/******/ }
+/******/ });
+/******/ }
+/******/ }
+/******/
+/******/ function trackBlockingPromise(promise) {
+/******/ switch (currentStatus) {
+/******/ case "ready":
+/******/ setStatus("prepare");
+/******/ /* fallthrough */
+/******/ case "prepare":
+/******/ blockingPromises++;
+/******/ promise.then(unblock, unblock);
+/******/ return promise;
+/******/ default:
+/******/ return promise;
+/******/ }
+/******/ }
+/******/
+/******/ function waitForBlockingPromises(fn) {
+/******/ if (blockingPromises === 0) return fn();
+/******/ return new Promise(function (resolve) {
+/******/ blockingPromisesWaiting.push(function () {
+/******/ resolve(fn());
+/******/ });
+/******/ });
+/******/ }
+/******/
+/******/ function hotCheck(applyOnUpdate) {
+/******/ if (currentStatus !== "idle") {
+/******/ throw new Error("check() is only allowed in idle status");
+/******/ }
+/******/ return setStatus("check")
+/******/ .then(__webpack_require__.hmrM)
+/******/ .then(function (update) {
+/******/ if (!update) {
+/******/ return setStatus(applyInvalidatedModules() ? "ready" : "idle").then(
+/******/ function () {
+/******/ return null;
+/******/ }
+/******/ );
+/******/ }
+/******/
+/******/ return setStatus("prepare").then(function () {
+/******/ var updatedModules = [];
+/******/ currentUpdateApplyHandlers = [];
+/******/
+/******/ return Promise.all(
+/******/ Object.keys(__webpack_require__.hmrC).reduce(function (
+/******/ promises,
+/******/ key
+/******/ ) {
+/******/ __webpack_require__.hmrC[key](
+/******/ update.c,
+/******/ update.r,
+/******/ update.m,
+/******/ promises,
+/******/ currentUpdateApplyHandlers,
+/******/ updatedModules
+/******/ );
+/******/ return promises;
+/******/ }, [])
+/******/ ).then(function () {
+/******/ return waitForBlockingPromises(function () {
+/******/ if (applyOnUpdate) {
+/******/ return internalApply(applyOnUpdate);
+/******/ } else {
+/******/ return setStatus("ready").then(function () {
+/******/ return updatedModules;
+/******/ });
+/******/ }
+/******/ });
+/******/ });
+/******/ });
+/******/ });
+/******/ }
+/******/
+/******/ function hotApply(options) {
+/******/ if (currentStatus !== "ready") {
+/******/ return Promise.resolve().then(function () {
+/******/ throw new Error(
+/******/ "apply() is only allowed in ready status (state: " +
+/******/ currentStatus +
+/******/ ")"
+/******/ );
+/******/ });
+/******/ }
+/******/ return internalApply(options);
+/******/ }
+/******/
+/******/ function internalApply(options) {
+/******/ options = options || {};
+/******/
+/******/ applyInvalidatedModules();
+/******/
+/******/ var results = currentUpdateApplyHandlers.map(function (handler) {
+/******/ return handler(options);
+/******/ });
+/******/ currentUpdateApplyHandlers = undefined;
+/******/
+/******/ var errors = results
+/******/ .map(function (r) {
+/******/ return r.error;
+/******/ })
+/******/ .filter(Boolean);
+/******/
+/******/ if (errors.length > 0) {
+/******/ return setStatus("abort").then(function () {
+/******/ throw errors[0];
+/******/ });
+/******/ }
+/******/
+/******/ // Now in "dispose" phase
+/******/ var disposePromise = setStatus("dispose");
+/******/
+/******/ results.forEach(function (result) {
+/******/ if (result.dispose) result.dispose();
+/******/ });
+/******/
+/******/ // Now in "apply" phase
+/******/ var applyPromise = setStatus("apply");
+/******/
+/******/ var error;
+/******/ var reportError = function (err) {
+/******/ if (!error) error = err;
+/******/ };
+/******/
+/******/ var outdatedModules = [];
+/******/ results.forEach(function (result) {
+/******/ if (result.apply) {
+/******/ var modules = result.apply(reportError);
+/******/ if (modules) {
+/******/ for (var i = 0; i < modules.length; i++) {
+/******/ outdatedModules.push(modules[i]);
+/******/ }
+/******/ }
+/******/ }
+/******/ });
+/******/
+/******/ return Promise.all([disposePromise, applyPromise]).then(function () {
+/******/ // handle errors in accept handlers and self accepted module load
+/******/ if (error) {
+/******/ return setStatus("fail").then(function () {
+/******/ throw error;
+/******/ });
+/******/ }
+/******/
+/******/ if (queuedInvalidatedModules) {
+/******/ return internalApply(options).then(function (list) {
+/******/ outdatedModules.forEach(function (moduleId) {
+/******/ if (list.indexOf(moduleId) < 0) list.push(moduleId);
+/******/ });
+/******/ return list;
+/******/ });
+/******/ }
+/******/
+/******/ return setStatus("idle").then(function () {
+/******/ return outdatedModules;
+/******/ });
+/******/ });
+/******/ }
+/******/
+/******/ function applyInvalidatedModules() {
+/******/ if (queuedInvalidatedModules) {
+/******/ if (!currentUpdateApplyHandlers) currentUpdateApplyHandlers = [];
+/******/ Object.keys(__webpack_require__.hmrI).forEach(function (key) {
+/******/ queuedInvalidatedModules.forEach(function (moduleId) {
+/******/ __webpack_require__.hmrI[key](
+/******/ moduleId,
+/******/ currentUpdateApplyHandlers
+/******/ );
+/******/ });
+/******/ });
+/******/ queuedInvalidatedModules = undefined;
+/******/ return true;
+/******/ }
+/******/ }
+/******/ })();
+/******/
+/******/ /* webpack/runtime/publicPath */
+/******/ (() => {
+/******/ var scriptUrl;
+/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
+/******/ var document = __webpack_require__.g.document;
+/******/ if (!scriptUrl && document) {
+/******/ if (document.currentScript)
+/******/ scriptUrl = document.currentScript.src;
+/******/ if (!scriptUrl) {
+/******/ var scripts = document.getElementsByTagName("script");
+/******/ if(scripts.length) {
+/******/ var i = scripts.length - 1;
+/******/ while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;
+/******/ }
+/******/ }
+/******/ }
+/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
+/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
+/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
+/******/ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
+/******/ __webpack_require__.p = scriptUrl;
+/******/ })();
+/******/
+/******/ /* webpack/runtime/css loading */
+/******/ (() => {
+/******/ if (typeof document === "undefined") return;
+/******/ var createStylesheet = (chunkId, fullhref, oldTag, resolve, reject) => {
+/******/ var linkTag = document.createElement("link");
+/******/
+/******/ linkTag.rel = "stylesheet";
+/******/ linkTag.type = "text/css";
+/******/ if (__webpack_require__.nc) {
+/******/ linkTag.nonce = __webpack_require__.nc;
+/******/ }
+/******/ var onLinkComplete = (event) => {
+/******/ // avoid mem leaks.
+/******/ linkTag.onerror = linkTag.onload = null;
+/******/ if (event.type === 'load') {
+/******/ resolve();
+/******/ } else {
+/******/ var errorType = event && event.type;
+/******/ var realHref = event && event.target && event.target.href || fullhref;
+/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + errorType + ": " + realHref + ")");
+/******/ err.name = "ChunkLoadError";
+/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
+/******/ err.type = errorType;
+/******/ err.request = realHref;
+/******/ if (linkTag.parentNode) linkTag.parentNode.removeChild(linkTag)
+/******/ reject(err);
+/******/ }
+/******/ }
+/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
+/******/ linkTag.href = fullhref;
+/******/
+/******/
+/******/ if (oldTag) {
+/******/ oldTag.parentNode.insertBefore(linkTag, oldTag.nextSibling);
+/******/ } else {
+/******/ document.head.appendChild(linkTag);
+/******/ }
+/******/ return linkTag;
+/******/ };
+/******/ var findStylesheet = (href, fullhref) => {
+/******/ var existingLinkTags = document.getElementsByTagName("link");
+/******/ for(var i = 0; i < existingLinkTags.length; i++) {
+/******/ var tag = existingLinkTags[i];
+/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");
+/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return tag;
+/******/ }
+/******/ var existingStyleTags = document.getElementsByTagName("style");
+/******/ for(var i = 0; i < existingStyleTags.length; i++) {
+/******/ var tag = existingStyleTags[i];
+/******/ var dataHref = tag.getAttribute("data-href");
+/******/ if(dataHref === href || dataHref === fullhref) return tag;
+/******/ }
+/******/ };
+/******/ var loadStylesheet = (chunkId) => {
+/******/ return new Promise((resolve, reject) => {
+/******/ var href = __webpack_require__.miniCssF(chunkId);
+/******/ var fullhref = __webpack_require__.p + href;
+/******/ if(findStylesheet(href, fullhref)) return resolve();
+/******/ createStylesheet(chunkId, fullhref, null, resolve, reject);
+/******/ });
+/******/ }
+/******/ // no chunk loading
+/******/
+/******/ var oldTags = [];
+/******/ var newTags = [];
+/******/ var applyHandler = (options) => {
+/******/ return { dispose: () => {
+/******/ for(var i = 0; i < oldTags.length; i++) {
+/******/ var oldTag = oldTags[i];
+/******/ if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);
+/******/ }
+/******/ oldTags.length = 0;
+/******/ }, apply: () => {
+/******/ for(var i = 0; i < newTags.length; i++) newTags[i].rel = "stylesheet";
+/******/ newTags.length = 0;
+/******/ } };
+/******/ }
+/******/ __webpack_require__.hmrC.miniCss = (chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList) => {
+/******/ applyHandlers.push(applyHandler);
+/******/ chunkIds.forEach((chunkId) => {
+/******/ var href = __webpack_require__.miniCssF(chunkId);
+/******/ var fullhref = __webpack_require__.p + href;
+/******/ var oldTag = findStylesheet(href, fullhref);
+/******/ if(!oldTag) return;
+/******/ promises.push(new Promise((resolve, reject) => {
+/******/ var tag = createStylesheet(chunkId, fullhref, oldTag, () => {
+/******/ tag.as = "style";
+/******/ tag.rel = "preload";
+/******/ resolve();
+/******/ }, reject);
+/******/ oldTags.push(oldTag);
+/******/ newTags.push(tag);
+/******/ }));
+/******/ });
+/******/ }
+/******/ })();
+/******/
+/******/ /* webpack/runtime/jsonp chunk loading */
+/******/ (() => {
+/******/ // no baseURI
+/******/
+/******/ // object to store loaded and loading chunks
+/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
+/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
+/******/ var installedChunks = __webpack_require__.hmrS_jsonp = __webpack_require__.hmrS_jsonp || {
+/******/ "main": 0
+/******/ };
+/******/
+/******/ // no chunk on demand loading
+/******/
+/******/ // no prefetching
+/******/
+/******/ // no preloaded
+/******/
+/******/ var currentUpdatedModulesList;
+/******/ var waitingUpdateResolves = {};
+/******/ function loadUpdateChunk(chunkId, updatedModulesList) {
+/******/ currentUpdatedModulesList = updatedModulesList;
+/******/ return new Promise((resolve, reject) => {
+/******/ waitingUpdateResolves[chunkId] = resolve;
+/******/ // start update chunk loading
+/******/ var url = __webpack_require__.p + __webpack_require__.hu(chunkId);
+/******/ // create error before stack unwound to get useful stacktrace later
+/******/ var error = new Error();
+/******/ var loadingEnded = (event) => {
+/******/ if(waitingUpdateResolves[chunkId]) {
+/******/ waitingUpdateResolves[chunkId] = undefined
+/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
+/******/ var realSrc = event && event.target && event.target.src;
+/******/ error.message = 'Loading hot update chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
+/******/ error.name = 'ChunkLoadError';
+/******/ error.type = errorType;
+/******/ error.request = realSrc;
+/******/ reject(error);
+/******/ }
+/******/ };
+/******/ __webpack_require__.l(url, loadingEnded);
+/******/ });
+/******/ }
+/******/
+/******/ self["webpackHotUpdate"] = (chunkId, moreModules, runtime) => {
+/******/ for(var moduleId in moreModules) {
+/******/ if(__webpack_require__.o(moreModules, moduleId)) {
+/******/ currentUpdate[moduleId] = moreModules[moduleId];
+/******/ if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);
+/******/ }
+/******/ }
+/******/ if(runtime) currentUpdateRuntime.push(runtime);
+/******/ if(waitingUpdateResolves[chunkId]) {
+/******/ waitingUpdateResolves[chunkId]();
+/******/ waitingUpdateResolves[chunkId] = undefined;
+/******/ }
+/******/ };
+/******/
+/******/ var currentUpdateChunks;
+/******/ var currentUpdate;
+/******/ var currentUpdateRemovedChunks;
+/******/ var currentUpdateRuntime;
+/******/ function applyHandler(options) {
+/******/ if (__webpack_require__.f) delete __webpack_require__.f.jsonpHmr;
+/******/ currentUpdateChunks = undefined;
+/******/ function getAffectedModuleEffects(updateModuleId) {
+/******/ var outdatedModules = [updateModuleId];
+/******/ var outdatedDependencies = {};
+/******/
+/******/ var queue = outdatedModules.map(function (id) {
+/******/ return {
+/******/ chain: [id],
+/******/ id: id
+/******/ };
+/******/ });
+/******/ while (queue.length > 0) {
+/******/ var queueItem = queue.pop();
+/******/ var moduleId = queueItem.id;
+/******/ var chain = queueItem.chain;
+/******/ var module = __webpack_require__.c[moduleId];
+/******/ if (
+/******/ !module ||
+/******/ (module.hot._selfAccepted && !module.hot._selfInvalidated)
+/******/ )
+/******/ continue;
+/******/ if (module.hot._selfDeclined) {
+/******/ return {
+/******/ type: "self-declined",
+/******/ chain: chain,
+/******/ moduleId: moduleId
+/******/ };
+/******/ }
+/******/ if (module.hot._main) {
+/******/ return {
+/******/ type: "unaccepted",
+/******/ chain: chain,
+/******/ moduleId: moduleId
+/******/ };
+/******/ }
+/******/ for (var i = 0; i < module.parents.length; i++) {
+/******/ var parentId = module.parents[i];
+/******/ var parent = __webpack_require__.c[parentId];
+/******/ if (!parent) continue;
+/******/ if (parent.hot._declinedDependencies[moduleId]) {
+/******/ return {
+/******/ type: "declined",
+/******/ chain: chain.concat([parentId]),
+/******/ moduleId: moduleId,
+/******/ parentId: parentId
+/******/ };
+/******/ }
+/******/ if (outdatedModules.indexOf(parentId) !== -1) continue;
+/******/ if (parent.hot._acceptedDependencies[moduleId]) {
+/******/ if (!outdatedDependencies[parentId])
+/******/ outdatedDependencies[parentId] = [];
+/******/ addAllToSet(outdatedDependencies[parentId], [moduleId]);
+/******/ continue;
+/******/ }
+/******/ delete outdatedDependencies[parentId];
+/******/ outdatedModules.push(parentId);
+/******/ queue.push({
+/******/ chain: chain.concat([parentId]),
+/******/ id: parentId
+/******/ });
+/******/ }
+/******/ }
+/******/
+/******/ return {
+/******/ type: "accepted",
+/******/ moduleId: updateModuleId,
+/******/ outdatedModules: outdatedModules,
+/******/ outdatedDependencies: outdatedDependencies
+/******/ };
+/******/ }
+/******/
+/******/ function addAllToSet(a, b) {
+/******/ for (var i = 0; i < b.length; i++) {
+/******/ var item = b[i];
+/******/ if (a.indexOf(item) === -1) a.push(item);
+/******/ }
+/******/ }
+/******/
+/******/ // at begin all updates modules are outdated
+/******/ // the "outdated" status can propagate to parents if they don't accept the children
+/******/ var outdatedDependencies = {};
+/******/ var outdatedModules = [];
+/******/ var appliedUpdate = {};
+/******/
+/******/ var warnUnexpectedRequire = function warnUnexpectedRequire(module) {
+/******/ console.warn(
+/******/ "[HMR] unexpected require(" + module.id + ") to disposed module"
+/******/ );
+/******/ };
+/******/
+/******/ for (var moduleId in currentUpdate) {
+/******/ if (__webpack_require__.o(currentUpdate, moduleId)) {
+/******/ var newModuleFactory = currentUpdate[moduleId];
+/******/ /** @type {TODO} */
+/******/ var result;
+/******/ if (newModuleFactory) {
+/******/ result = getAffectedModuleEffects(moduleId);
+/******/ } else {
+/******/ result = {
+/******/ type: "disposed",
+/******/ moduleId: moduleId
+/******/ };
+/******/ }
+/******/ /** @type {Error|false} */
+/******/ var abortError = false;
+/******/ var doApply = false;
+/******/ var doDispose = false;
+/******/ var chainInfo = "";
+/******/ if (result.chain) {
+/******/ chainInfo = "\nUpdate propagation: " + result.chain.join(" -> ");
+/******/ }
+/******/ switch (result.type) {
+/******/ case "self-declined":
+/******/ if (options.onDeclined) options.onDeclined(result);
+/******/ if (!options.ignoreDeclined)
+/******/ abortError = new Error(
+/******/ "Aborted because of self decline: " +
+/******/ result.moduleId +
+/******/ chainInfo
+/******/ );
+/******/ break;
+/******/ case "declined":
+/******/ if (options.onDeclined) options.onDeclined(result);
+/******/ if (!options.ignoreDeclined)
+/******/ abortError = new Error(
+/******/ "Aborted because of declined dependency: " +
+/******/ result.moduleId +
+/******/ " in " +
+/******/ result.parentId +
+/******/ chainInfo
+/******/ );
+/******/ break;
+/******/ case "unaccepted":
+/******/ if (options.onUnaccepted) options.onUnaccepted(result);
+/******/ if (!options.ignoreUnaccepted)
+/******/ abortError = new Error(
+/******/ "Aborted because " + moduleId + " is not accepted" + chainInfo
+/******/ );
+/******/ break;
+/******/ case "accepted":
+/******/ if (options.onAccepted) options.onAccepted(result);
+/******/ doApply = true;
+/******/ break;
+/******/ case "disposed":
+/******/ if (options.onDisposed) options.onDisposed(result);
+/******/ doDispose = true;
+/******/ break;
+/******/ default:
+/******/ throw new Error("Unexception type " + result.type);
+/******/ }
+/******/ if (abortError) {
+/******/ return {
+/******/ error: abortError
+/******/ };
+/******/ }
+/******/ if (doApply) {
+/******/ appliedUpdate[moduleId] = newModuleFactory;
+/******/ addAllToSet(outdatedModules, result.outdatedModules);
+/******/ for (moduleId in result.outdatedDependencies) {
+/******/ if (__webpack_require__.o(result.outdatedDependencies, moduleId)) {
+/******/ if (!outdatedDependencies[moduleId])
+/******/ outdatedDependencies[moduleId] = [];
+/******/ addAllToSet(
+/******/ outdatedDependencies[moduleId],
+/******/ result.outdatedDependencies[moduleId]
+/******/ );
+/******/ }
+/******/ }
+/******/ }
+/******/ if (doDispose) {
+/******/ addAllToSet(outdatedModules, [result.moduleId]);
+/******/ appliedUpdate[moduleId] = warnUnexpectedRequire;
+/******/ }
+/******/ }
+/******/ }
+/******/ currentUpdate = undefined;
+/******/
+/******/ // Store self accepted outdated modules to require them later by the module system
+/******/ var outdatedSelfAcceptedModules = [];
+/******/ for (var j = 0; j < outdatedModules.length; j++) {
+/******/ var outdatedModuleId = outdatedModules[j];
+/******/ var module = __webpack_require__.c[outdatedModuleId];
+/******/ if (
+/******/ module &&
+/******/ (module.hot._selfAccepted || module.hot._main) &&
+/******/ // removed self-accepted modules should not be required
+/******/ appliedUpdate[outdatedModuleId] !== warnUnexpectedRequire &&
+/******/ // when called invalidate self-accepting is not possible
+/******/ !module.hot._selfInvalidated
+/******/ ) {
+/******/ outdatedSelfAcceptedModules.push({
+/******/ module: outdatedModuleId,
+/******/ require: module.hot._requireSelf,
+/******/ errorHandler: module.hot._selfAccepted
+/******/ });
+/******/ }
+/******/ }
+/******/
+/******/ var moduleOutdatedDependencies;
+/******/
+/******/ return {
+/******/ dispose: function () {
+/******/ currentUpdateRemovedChunks.forEach(function (chunkId) {
+/******/ delete installedChunks[chunkId];
+/******/ });
+/******/ currentUpdateRemovedChunks = undefined;
+/******/
+/******/ var idx;
+/******/ var queue = outdatedModules.slice();
+/******/ while (queue.length > 0) {
+/******/ var moduleId = queue.pop();
+/******/ var module = __webpack_require__.c[moduleId];
+/******/ if (!module) continue;
+/******/
+/******/ var data = {};
+/******/
+/******/ // Call dispose handlers
+/******/ var disposeHandlers = module.hot._disposeHandlers;
+/******/ for (j = 0; j < disposeHandlers.length; j++) {
+/******/ disposeHandlers[j].call(null, data);
+/******/ }
+/******/ __webpack_require__.hmrD[moduleId] = data;
+/******/
+/******/ // disable module (this disables requires from this module)
+/******/ module.hot.active = false;
+/******/
+/******/ // remove module from cache
+/******/ delete __webpack_require__.c[moduleId];
+/******/
+/******/ // when disposing there is no need to call dispose handler
+/******/ delete outdatedDependencies[moduleId];
+/******/
+/******/ // remove "parents" references from all children
+/******/ for (j = 0; j < module.children.length; j++) {
+/******/ var child = __webpack_require__.c[module.children[j]];
+/******/ if (!child) continue;
+/******/ idx = child.parents.indexOf(moduleId);
+/******/ if (idx >= 0) {
+/******/ child.parents.splice(idx, 1);
+/******/ }
+/******/ }
+/******/ }
+/******/
+/******/ // remove outdated dependency from module children
+/******/ var dependency;
+/******/ for (var outdatedModuleId in outdatedDependencies) {
+/******/ if (__webpack_require__.o(outdatedDependencies, outdatedModuleId)) {
+/******/ module = __webpack_require__.c[outdatedModuleId];
+/******/ if (module) {
+/******/ moduleOutdatedDependencies =
+/******/ outdatedDependencies[outdatedModuleId];
+/******/ for (j = 0; j < moduleOutdatedDependencies.length; j++) {
+/******/ dependency = moduleOutdatedDependencies[j];
+/******/ idx = module.children.indexOf(dependency);
+/******/ if (idx >= 0) module.children.splice(idx, 1);
+/******/ }
+/******/ }
+/******/ }
+/******/ }
+/******/ },
+/******/ apply: function (reportError) {
+/******/ // insert new code
+/******/ for (var updateModuleId in appliedUpdate) {
+/******/ if (__webpack_require__.o(appliedUpdate, updateModuleId)) {
+/******/ __webpack_require__.m[updateModuleId] = appliedUpdate[updateModuleId];
+/******/ }
+/******/ }
+/******/
+/******/ // run new runtime modules
+/******/ for (var i = 0; i < currentUpdateRuntime.length; i++) {
+/******/ currentUpdateRuntime[i](__webpack_require__);
+/******/ }
+/******/
+/******/ // call accept handlers
+/******/ for (var outdatedModuleId in outdatedDependencies) {
+/******/ if (__webpack_require__.o(outdatedDependencies, outdatedModuleId)) {
+/******/ var module = __webpack_require__.c[outdatedModuleId];
+/******/ if (module) {
+/******/ moduleOutdatedDependencies =
+/******/ outdatedDependencies[outdatedModuleId];
+/******/ var callbacks = [];
+/******/ var errorHandlers = [];
+/******/ var dependenciesForCallbacks = [];
+/******/ for (var j = 0; j < moduleOutdatedDependencies.length; j++) {
+/******/ var dependency = moduleOutdatedDependencies[j];
+/******/ var acceptCallback =
+/******/ module.hot._acceptedDependencies[dependency];
+/******/ var errorHandler =
+/******/ module.hot._acceptedErrorHandlers[dependency];
+/******/ if (acceptCallback) {
+/******/ if (callbacks.indexOf(acceptCallback) !== -1) continue;
+/******/ callbacks.push(acceptCallback);
+/******/ errorHandlers.push(errorHandler);
+/******/ dependenciesForCallbacks.push(dependency);
+/******/ }
+/******/ }
+/******/ for (var k = 0; k < callbacks.length; k++) {
+/******/ try {
+/******/ callbacks[k].call(null, moduleOutdatedDependencies);
+/******/ } catch (err) {
+/******/ if (typeof errorHandlers[k] === "function") {
+/******/ try {
+/******/ errorHandlers[k](err, {
+/******/ moduleId: outdatedModuleId,
+/******/ dependencyId: dependenciesForCallbacks[k]
+/******/ });
+/******/ } catch (err2) {
+/******/ if (options.onErrored) {
+/******/ options.onErrored({
+/******/ type: "accept-error-handler-errored",
+/******/ moduleId: outdatedModuleId,
+/******/ dependencyId: dependenciesForCallbacks[k],
+/******/ error: err2,
+/******/ originalError: err
+/******/ });
+/******/ }
+/******/ if (!options.ignoreErrored) {
+/******/ reportError(err2);
+/******/ reportError(err);
+/******/ }
+/******/ }
+/******/ } else {
+/******/ if (options.onErrored) {
+/******/ options.onErrored({
+/******/ type: "accept-errored",
+/******/ moduleId: outdatedModuleId,
+/******/ dependencyId: dependenciesForCallbacks[k],
+/******/ error: err
+/******/ });
+/******/ }
+/******/ if (!options.ignoreErrored) {
+/******/ reportError(err);
+/******/ }
+/******/ }
+/******/ }
+/******/ }
+/******/ }
+/******/ }
+/******/ }
+/******/
+/******/ // Load self accepted modules
+/******/ for (var o = 0; o < outdatedSelfAcceptedModules.length; o++) {
+/******/ var item = outdatedSelfAcceptedModules[o];
+/******/ var moduleId = item.module;
+/******/ try {
+/******/ item.require(moduleId);
+/******/ } catch (err) {
+/******/ if (typeof item.errorHandler === "function") {
+/******/ try {
+/******/ item.errorHandler(err, {
+/******/ moduleId: moduleId,
+/******/ module: __webpack_require__.c[moduleId]
+/******/ });
+/******/ } catch (err2) {
+/******/ if (options.onErrored) {
+/******/ options.onErrored({
+/******/ type: "self-accept-error-handler-errored",
+/******/ moduleId: moduleId,
+/******/ error: err2,
+/******/ originalError: err
+/******/ });
+/******/ }
+/******/ if (!options.ignoreErrored) {
+/******/ reportError(err2);
+/******/ reportError(err);
+/******/ }
+/******/ }
+/******/ } else {
+/******/ if (options.onErrored) {
+/******/ options.onErrored({
+/******/ type: "self-accept-errored",
+/******/ moduleId: moduleId,
+/******/ error: err
+/******/ });
+/******/ }
+/******/ if (!options.ignoreErrored) {
+/******/ reportError(err);
+/******/ }
+/******/ }
+/******/ }
+/******/ }
+/******/
+/******/ return outdatedModules;
+/******/ }
+/******/ };
+/******/ }
+/******/ __webpack_require__.hmrI.jsonp = function (moduleId, applyHandlers) {
+/******/ if (!currentUpdate) {
+/******/ currentUpdate = {};
+/******/ currentUpdateRuntime = [];
+/******/ currentUpdateRemovedChunks = [];
+/******/ applyHandlers.push(applyHandler);
+/******/ }
+/******/ if (!__webpack_require__.o(currentUpdate, moduleId)) {
+/******/ currentUpdate[moduleId] = __webpack_require__.m[moduleId];
+/******/ }
+/******/ };
+/******/ __webpack_require__.hmrC.jsonp = function (
+/******/ chunkIds,
+/******/ removedChunks,
+/******/ removedModules,
+/******/ promises,
+/******/ applyHandlers,
+/******/ updatedModulesList
+/******/ ) {
+/******/ applyHandlers.push(applyHandler);
+/******/ currentUpdateChunks = {};
+/******/ currentUpdateRemovedChunks = removedChunks;
+/******/ currentUpdate = removedModules.reduce(function (obj, key) {
+/******/ obj[key] = false;
+/******/ return obj;
+/******/ }, {});
+/******/ currentUpdateRuntime = [];
+/******/ chunkIds.forEach(function (chunkId) {
+/******/ if (
+/******/ __webpack_require__.o(installedChunks, chunkId) &&
+/******/ installedChunks[chunkId] !== undefined
+/******/ ) {
+/******/ promises.push(loadUpdateChunk(chunkId, updatedModulesList));
+/******/ currentUpdateChunks[chunkId] = true;
+/******/ } else {
+/******/ currentUpdateChunks[chunkId] = false;
+/******/ }
+/******/ });
+/******/ if (__webpack_require__.f) {
+/******/ __webpack_require__.f.jsonpHmr = function (chunkId, promises) {
+/******/ if (
+/******/ currentUpdateChunks &&
+/******/ __webpack_require__.o(currentUpdateChunks, chunkId) &&
+/******/ !currentUpdateChunks[chunkId]
+/******/ ) {
+/******/ promises.push(loadUpdateChunk(chunkId));
+/******/ currentUpdateChunks[chunkId] = true;
+/******/ }
+/******/ };
+/******/ }
+/******/ };
+/******/
+/******/ __webpack_require__.hmrM = () => {
+/******/ if (typeof fetch === "undefined") throw new Error("No browser support: need fetch API");
+/******/ return fetch(__webpack_require__.p + __webpack_require__.hmrF()).then((response) => {
+/******/ if(response.status === 404) return; // no update available
+/******/ if(!response.ok) throw new Error("Failed to fetch update manifest " + response.statusText);
+/******/ return response.json();
+/******/ });
+/******/ };
+/******/
+/******/ // no on chunks loaded
+/******/
+/******/ // no jsonp function
+/******/ })();
+/******/
+/************************************************************************/
+/******/
+/******/ // module cache are used so entry inlining is disabled
+/******/ // startup
+/******/ // Load entry module and return exports
+/******/ var __webpack_exports__ = __webpack_require__("./index.css");
+/******/
+/******/ })()
+;
\ No newline at end of file
diff --git a/test/cases/hmr-locals/index.css b/test/cases/hmr-locals/index.css
new file mode 100644
index 00000000..739f1581
--- /dev/null
+++ b/test/cases/hmr-locals/index.css
@@ -0,0 +1,3 @@
+.x {
+ color: red;
+}
diff --git a/test/cases/hmr-locals/webpack.config.js b/test/cases/hmr-locals/webpack.config.js
new file mode 100644
index 00000000..639b6511
--- /dev/null
+++ b/test/cases/hmr-locals/webpack.config.js
@@ -0,0 +1,33 @@
+import { HotModuleReplacementPlugin } from "webpack";
+
+import Self from "../../../src";
+
+module.exports = {
+ entry: "./index.css",
+ mode: "development",
+ devtool: false,
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: [
+ {
+ loader: Self.loader,
+ },
+ {
+ loader: "css-loader",
+ options: {
+ modules: true,
+ },
+ },
+ ],
+ },
+ ],
+ },
+ plugins: [
+ new HotModuleReplacementPlugin(),
+ new Self({
+ filename: "[name].css",
+ }),
+ ],
+};
diff --git a/test/cases/hmr/expected/main.js b/test/cases/hmr/expected/main.js
index 39fc3d64..593668a5 100644
--- a/test/cases/hmr/expected/main.js
+++ b/test/cases/hmr/expected/main.js
@@ -363,10 +363,25 @@ __webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
if(true) {
- //
- var cssReload = __webpack_require__(/*! ../../../src/hmr/hotModuleReplacement.js */ "../../../src/hmr/hotModuleReplacement.js")(module.id, {"locals":false});
- module.hot.dispose(cssReload);
- module.hot.accept(undefined, cssReload);
+ (function() {
+ var localsJsonString = undefined;
+ //
+ var cssReload = __webpack_require__(/*! ../../../src/hmr/hotModuleReplacement.js */ "../../../src/hmr/hotModuleReplacement.js")(module.id, {});
+ // only invalidate when locals change
+ if (
+ module.hot.data &&
+ module.hot.data.value &&
+ module.hot.data.value !== localsJsonString
+ ) {
+ module.hot.invalidate();
+ } else {
+ module.hot.accept();
+ }
+ module.hot.dispose(function(data) {
+ data.value = localsJsonString;
+ cssReload();
+ });
+ })();
}
diff --git a/types/loader.d.ts b/types/loader.d.ts
index a007af71..64ba61f4 100644
--- a/types/loader.d.ts
+++ b/types/loader.d.ts
@@ -10,6 +10,7 @@ declare function loader(
declare namespace loader {
export {
pitch,
+ hotLoader,
Schema,
Compiler,
Compilation,
@@ -33,6 +34,40 @@ declare function pitch(
this: import("webpack").LoaderContext,
request: string
): void;
+/** @typedef {import("schema-utils/declarations/validate").Schema} Schema */
+/** @typedef {import("webpack").Compiler} Compiler */
+/** @typedef {import("webpack").Compilation} Compilation */
+/** @typedef {import("webpack").Chunk} Chunk */
+/** @typedef {import("webpack").Module} Module */
+/** @typedef {import("webpack").sources.Source} Source */
+/** @typedef {import("webpack").AssetInfo} AssetInfo */
+/** @typedef {import("webpack").NormalModule} NormalModule */
+/** @typedef {import("./index.js").LoaderOptions} LoaderOptions */
+/** @typedef {{ [key: string]: string | function }} Locals */
+/** @typedef {any} TODO */
+/**
+ * @typedef {Object} Dependency
+ * @property {string} identifier
+ * @property {string | null} context
+ * @property {Buffer} content
+ * @property {string} media
+ * @property {string} [supports]
+ * @property {string} [layer]
+ * @property {Buffer} [sourceMap]
+ */
+/**
+ * @param {string} content
+ * @param {{ loaderContext: import("webpack").LoaderContext, options: LoaderOptions, locals: Locals | undefined }} context
+ * @returns {string}
+ */
+declare function hotLoader(
+ content: string,
+ context: {
+ loaderContext: import("webpack").LoaderContext;
+ options: LoaderOptions;
+ locals: Locals | undefined;
+ }
+): string;
type Schema = import("schema-utils/declarations/validate").Schema;
type Compiler = import("webpack").Compiler;
type Compilation = import("webpack").Compilation;