index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. 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; }
  2. 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; }
  3. function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  4. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  5. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  6. /* global __resourceQuery, __webpack_hash__ */
  7. /// <reference types="webpack/module" />
  8. import webpackHotLog from "webpack/hot/log.js";
  9. import stripAnsi from "./utils/stripAnsi.js";
  10. import parseURL from "./utils/parseURL.js";
  11. import socket from "./socket.js";
  12. import { formatProblem, createOverlay } from "./overlay.js";
  13. import { log, logEnabledFeatures, setLogLevel } from "./utils/log.js";
  14. import sendMessage from "./utils/sendMessage.js";
  15. import reloadApp from "./utils/reloadApp.js";
  16. import createSocketURL from "./utils/createSocketURL.js";
  17. /**
  18. * @typedef {Object} OverlayOptions
  19. * @property {boolean | (error: Error) => boolean} [warnings]
  20. * @property {boolean | (error: Error) => boolean} [errors]
  21. * @property {boolean | (error: Error) => boolean} [runtimeErrors]
  22. * @property {string} [trustedTypesPolicyName]
  23. */
  24. /**
  25. * @typedef {Object} Options
  26. * @property {boolean} hot
  27. * @property {boolean} liveReload
  28. * @property {boolean} progress
  29. * @property {boolean | OverlayOptions} overlay
  30. * @property {string} [logging]
  31. * @property {number} [reconnect]
  32. */
  33. /**
  34. * @typedef {Object} Status
  35. * @property {boolean} isUnloading
  36. * @property {string} currentHash
  37. * @property {string} [previousHash]
  38. */
  39. /**
  40. * @param {boolean | { warnings?: boolean | string; errors?: boolean | string; runtimeErrors?: boolean | string; }} overlayOptions
  41. */
  42. var decodeOverlayOptions = function decodeOverlayOptions(overlayOptions) {
  43. if (typeof overlayOptions === "object") {
  44. ["warnings", "errors", "runtimeErrors"].forEach(function (property) {
  45. if (typeof overlayOptions[property] === "string") {
  46. var overlayFilterFunctionString = decodeURIComponent(overlayOptions[property]);
  47. // eslint-disable-next-line no-new-func
  48. var overlayFilterFunction = new Function("message", "var callback = ".concat(overlayFilterFunctionString, "\n return callback(message)"));
  49. overlayOptions[property] = overlayFilterFunction;
  50. }
  51. });
  52. }
  53. };
  54. /**
  55. * @type {Status}
  56. */
  57. var status = {
  58. isUnloading: false,
  59. // TODO Workaround for webpack v4, `__webpack_hash__` is not replaced without HotModuleReplacement
  60. // eslint-disable-next-line camelcase
  61. currentHash: typeof __webpack_hash__ !== "undefined" ? __webpack_hash__ : ""
  62. };
  63. /** @type {Options} */
  64. var options = {
  65. hot: false,
  66. liveReload: false,
  67. progress: false,
  68. overlay: false
  69. };
  70. var parsedResourceQuery = parseURL(__resourceQuery);
  71. var enabledFeatures = {
  72. "Hot Module Replacement": false,
  73. "Live Reloading": false,
  74. Progress: false,
  75. Overlay: false
  76. };
  77. if (parsedResourceQuery.hot === "true") {
  78. options.hot = true;
  79. enabledFeatures["Hot Module Replacement"] = true;
  80. }
  81. if (parsedResourceQuery["live-reload"] === "true") {
  82. options.liveReload = true;
  83. enabledFeatures["Live Reloading"] = true;
  84. }
  85. if (parsedResourceQuery.progress === "true") {
  86. options.progress = true;
  87. enabledFeatures.Progress = true;
  88. }
  89. if (parsedResourceQuery.overlay) {
  90. try {
  91. options.overlay = JSON.parse(parsedResourceQuery.overlay);
  92. } catch (e) {
  93. log.error("Error parsing overlay options from resource query:", e);
  94. }
  95. // Fill in default "true" params for partially-specified objects.
  96. if (typeof options.overlay === "object") {
  97. options.overlay = _objectSpread({
  98. errors: true,
  99. warnings: true,
  100. runtimeErrors: true
  101. }, options.overlay);
  102. decodeOverlayOptions(options.overlay);
  103. }
  104. enabledFeatures.Overlay = true;
  105. }
  106. if (parsedResourceQuery.logging) {
  107. options.logging = parsedResourceQuery.logging;
  108. }
  109. if (typeof parsedResourceQuery.reconnect !== "undefined") {
  110. options.reconnect = Number(parsedResourceQuery.reconnect);
  111. }
  112. /**
  113. * @param {string} level
  114. */
  115. function setAllLogLevel(level) {
  116. // This is needed because the HMR logger operate separately from dev server logger
  117. webpackHotLog.setLogLevel(level === "verbose" || level === "log" ? "info" : level);
  118. setLogLevel(level);
  119. }
  120. if (options.logging) {
  121. setAllLogLevel(options.logging);
  122. }
  123. logEnabledFeatures(enabledFeatures);
  124. self.addEventListener("beforeunload", function () {
  125. status.isUnloading = true;
  126. });
  127. var overlay = typeof window !== "undefined" ? createOverlay(typeof options.overlay === "object" ? {
  128. trustedTypesPolicyName: options.overlay.trustedTypesPolicyName,
  129. catchRuntimeError: options.overlay.runtimeErrors
  130. } : {
  131. trustedTypesPolicyName: false,
  132. catchRuntimeError: options.overlay
  133. }) : {
  134. send: function send() {}
  135. };
  136. var onSocketMessage = {
  137. hot: function hot() {
  138. if (parsedResourceQuery.hot === "false") {
  139. return;
  140. }
  141. options.hot = true;
  142. },
  143. liveReload: function liveReload() {
  144. if (parsedResourceQuery["live-reload"] === "false") {
  145. return;
  146. }
  147. options.liveReload = true;
  148. },
  149. invalid: function invalid() {
  150. log.info("App updated. Recompiling...");
  151. // Fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
  152. if (options.overlay) {
  153. overlay.send({
  154. type: "DISMISS"
  155. });
  156. }
  157. sendMessage("Invalid");
  158. },
  159. /**
  160. * @param {string} hash
  161. */
  162. hash: function hash(_hash) {
  163. status.previousHash = status.currentHash;
  164. status.currentHash = _hash;
  165. },
  166. logging: setAllLogLevel,
  167. /**
  168. * @param {boolean} value
  169. */
  170. overlay: function overlay(value) {
  171. if (typeof document === "undefined") {
  172. return;
  173. }
  174. options.overlay = value;
  175. decodeOverlayOptions(options.overlay);
  176. },
  177. /**
  178. * @param {number} value
  179. */
  180. reconnect: function reconnect(value) {
  181. if (parsedResourceQuery.reconnect === "false") {
  182. return;
  183. }
  184. options.reconnect = value;
  185. },
  186. /**
  187. * @param {boolean} value
  188. */
  189. progress: function progress(value) {
  190. options.progress = value;
  191. },
  192. /**
  193. * @param {{ pluginName?: string, percent: number, msg: string }} data
  194. */
  195. "progress-update": function progressUpdate(data) {
  196. if (options.progress) {
  197. log.info("".concat(data.pluginName ? "[".concat(data.pluginName, "] ") : "").concat(data.percent, "% - ").concat(data.msg, "."));
  198. }
  199. sendMessage("Progress", data);
  200. },
  201. "still-ok": function stillOk() {
  202. log.info("Nothing changed.");
  203. if (options.overlay) {
  204. overlay.send({
  205. type: "DISMISS"
  206. });
  207. }
  208. sendMessage("StillOk");
  209. },
  210. ok: function ok() {
  211. sendMessage("Ok");
  212. if (options.overlay) {
  213. overlay.send({
  214. type: "DISMISS"
  215. });
  216. }
  217. reloadApp(options, status);
  218. },
  219. // TODO: remove in v5 in favor of 'static-changed'
  220. /**
  221. * @param {string} file
  222. */
  223. "content-changed": function contentChanged(file) {
  224. log.info("".concat(file ? "\"".concat(file, "\"") : "Content", " from static directory was changed. Reloading..."));
  225. self.location.reload();
  226. },
  227. /**
  228. * @param {string} file
  229. */
  230. "static-changed": function staticChanged(file) {
  231. log.info("".concat(file ? "\"".concat(file, "\"") : "Content", " from static directory was changed. Reloading..."));
  232. self.location.reload();
  233. },
  234. /**
  235. * @param {Error[]} warnings
  236. * @param {any} params
  237. */
  238. warnings: function warnings(_warnings, params) {
  239. log.warn("Warnings while compiling.");
  240. var printableWarnings = _warnings.map(function (error) {
  241. var _formatProblem = formatProblem("warning", error),
  242. header = _formatProblem.header,
  243. body = _formatProblem.body;
  244. return "".concat(header, "\n").concat(stripAnsi(body));
  245. });
  246. sendMessage("Warnings", printableWarnings);
  247. for (var i = 0; i < printableWarnings.length; i++) {
  248. log.warn(printableWarnings[i]);
  249. }
  250. var overlayWarningsSetting = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.warnings;
  251. if (overlayWarningsSetting) {
  252. var warningsToDisplay = typeof overlayWarningsSetting === "function" ? _warnings.filter(overlayWarningsSetting) : _warnings;
  253. if (warningsToDisplay.length) {
  254. overlay.send({
  255. type: "BUILD_ERROR",
  256. level: "warning",
  257. messages: _warnings
  258. });
  259. }
  260. }
  261. if (params && params.preventReloading) {
  262. return;
  263. }
  264. reloadApp(options, status);
  265. },
  266. /**
  267. * @param {Error[]} errors
  268. */
  269. errors: function errors(_errors) {
  270. log.error("Errors while compiling. Reload prevented.");
  271. var printableErrors = _errors.map(function (error) {
  272. var _formatProblem2 = formatProblem("error", error),
  273. header = _formatProblem2.header,
  274. body = _formatProblem2.body;
  275. return "".concat(header, "\n").concat(stripAnsi(body));
  276. });
  277. sendMessage("Errors", printableErrors);
  278. for (var i = 0; i < printableErrors.length; i++) {
  279. log.error(printableErrors[i]);
  280. }
  281. var overlayErrorsSettings = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.errors;
  282. if (overlayErrorsSettings) {
  283. var errorsToDisplay = typeof overlayErrorsSettings === "function" ? _errors.filter(overlayErrorsSettings) : _errors;
  284. if (errorsToDisplay.length) {
  285. overlay.send({
  286. type: "BUILD_ERROR",
  287. level: "error",
  288. messages: _errors
  289. });
  290. }
  291. }
  292. },
  293. /**
  294. * @param {Error} error
  295. */
  296. error: function error(_error) {
  297. log.error(_error);
  298. },
  299. close: function close() {
  300. log.info("Disconnected!");
  301. if (options.overlay) {
  302. overlay.send({
  303. type: "DISMISS"
  304. });
  305. }
  306. sendMessage("Close");
  307. }
  308. };
  309. var socketURL = createSocketURL(parsedResourceQuery);
  310. socket(socketURL, onSocketMessage, options.reconnect);