You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.9 KiB
100 lines
2.9 KiB
/* global __react_refresh_error_overlay__, __react_refresh_socket__, __resourceQuery */ |
|
|
|
const events = require('./utils/errorEventHandlers.js'); |
|
const formatWebpackErrors = require('./utils/formatWebpackErrors.js'); |
|
const runWithPatchedUrl = require('./utils/patchUrl.js'); |
|
const runWithRetry = require('./utils/retry.js'); |
|
|
|
// Setup error states |
|
let isHotReload = false; |
|
let hasRuntimeErrors = false; |
|
|
|
/** |
|
* Try dismissing the compile error overlay. |
|
* This will also reset runtime error records (if any), |
|
* because we have new source to evaluate. |
|
* @returns {void} |
|
*/ |
|
function tryDismissErrorOverlay() { |
|
__react_refresh_error_overlay__.clearCompileError(); |
|
__react_refresh_error_overlay__.clearRuntimeErrors(!hasRuntimeErrors); |
|
hasRuntimeErrors = false; |
|
} |
|
|
|
/** |
|
* A function called after a compile success signal is received from Webpack. |
|
* @returns {void} |
|
*/ |
|
function handleCompileSuccess() { |
|
isHotReload = true; |
|
|
|
if (isHotReload) { |
|
tryDismissErrorOverlay(); |
|
} |
|
} |
|
|
|
/** |
|
* A function called after a compile errored signal is received from Webpack. |
|
* @param {string[]} errors |
|
* @returns {void} |
|
*/ |
|
function handleCompileErrors(errors) { |
|
isHotReload = true; |
|
|
|
const formattedErrors = formatWebpackErrors(errors); |
|
|
|
// Only show the first error |
|
__react_refresh_error_overlay__.showCompileError(formattedErrors[0]); |
|
} |
|
|
|
/** |
|
* Handles compilation messages from Webpack. |
|
* Integrates with a compile error overlay. |
|
* @param {*} message A Webpack HMR message sent via WebSockets. |
|
* @returns {void} |
|
*/ |
|
function compileMessageHandler(message) { |
|
switch (message.type) { |
|
case 'ok': |
|
case 'still-ok': |
|
case 'warnings': { |
|
// TODO: Implement handling for warnings |
|
handleCompileSuccess(); |
|
break; |
|
} |
|
case 'errors': { |
|
handleCompileErrors(message.data); |
|
break; |
|
} |
|
default: { |
|
// Do nothing. |
|
} |
|
} |
|
} |
|
|
|
if (process.env.NODE_ENV !== 'production') { |
|
if (typeof window !== 'undefined') { |
|
runWithPatchedUrl(function setupOverlay() { |
|
// Only register if no other overlay have been registered |
|
if (!window.__reactRefreshOverlayInjected && __react_refresh_socket__) { |
|
// Registers handlers for compile errors with retry - |
|
// This is to prevent mismatching injection order causing errors to be thrown |
|
runWithRetry(function initSocket() { |
|
__react_refresh_socket__.init(compileMessageHandler, __resourceQuery); |
|
}, 3); |
|
// Registers handlers for runtime errors |
|
events.handleError(function handleError(error) { |
|
hasRuntimeErrors = true; |
|
__react_refresh_error_overlay__.handleRuntimeError(error); |
|
}); |
|
events.handleUnhandledRejection(function handleUnhandledPromiseRejection(error) { |
|
hasRuntimeErrors = true; |
|
__react_refresh_error_overlay__.handleRuntimeError(error); |
|
}); |
|
|
|
// Mark overlay as injected to prevent double-injection |
|
window.__reactRefreshOverlayInjected = true; |
|
} |
|
}); |
|
} |
|
}
|
|
|