mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-01-12 22:46:30 +08:00
Fix error overlay in Firefox (#749)
This commit is contained in:
129
packages/react-dev-utils/webpackHotDevClient.js
vendored
129
packages/react-dev-utils/webpackHotDevClient.js
vendored
@@ -39,13 +39,10 @@ var colors = {
|
||||
};
|
||||
ansiHTML.setColors(colors);
|
||||
|
||||
function showErrorOverlay(message) {
|
||||
// Use an iframe so that document styles don't mess up the overlay.
|
||||
var iframeID = 'react-dev-utils-webpack-hot-dev-client-overlay';
|
||||
var iframe =
|
||||
document.getElementById(iframeID) ||
|
||||
document.createElement('iframe');
|
||||
iframe.id = iframeID;
|
||||
function createOverlayIframe(onIframeLoad) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.id = 'react-dev-utils-webpack-hot-dev-client-overlay';
|
||||
iframe.src = 'about:blank';
|
||||
iframe.style.position = 'fixed';
|
||||
iframe.style.left = 0;
|
||||
iframe.style.top = 0;
|
||||
@@ -55,39 +52,74 @@ function showErrorOverlay(message) {
|
||||
iframe.style.height = '100vh';
|
||||
iframe.style.border = 'none';
|
||||
iframe.style.zIndex = 9999999999;
|
||||
document.body.appendChild(iframe);
|
||||
iframe.onload = onIframeLoad;
|
||||
return iframe;
|
||||
}
|
||||
|
||||
// Inside, make a div.
|
||||
var overlayID = 'react-dev-utils-webpack-hot-dev-client-overlay-div';
|
||||
var overlay =
|
||||
iframe.contentDocument.getElementById(overlayID) ||
|
||||
iframe.contentDocument.createElement('div');
|
||||
overlay.id = overlayID;
|
||||
overlay.style.position = 'fixed';
|
||||
overlay.style.left = 0;
|
||||
overlay.style.top = 0;
|
||||
overlay.style.right = 0;
|
||||
overlay.style.bottom = 0;
|
||||
overlay.style.width = '100vw';
|
||||
overlay.style.height = '100vh';
|
||||
overlay.style.backgroundColor = 'black';
|
||||
overlay.style.color = '#E8E8E8';
|
||||
overlay.style.fontFamily = 'Menlo, Consolas, monospace';
|
||||
overlay.style.fontSize = 'large';
|
||||
overlay.style.padding = '2rem';
|
||||
overlay.style.lineHeight = '1.2';
|
||||
overlay.style.whiteSpace = 'pre-wrap';
|
||||
overlay.style.overflow = 'auto';
|
||||
function addOverlayDivTo(iframe) {
|
||||
var div = iframe.contentDocument.createElement('div');
|
||||
div.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div';
|
||||
div.style.position = 'fixed';
|
||||
div.style.left = 0;
|
||||
div.style.top = 0;
|
||||
div.style.right = 0;
|
||||
div.style.bottom = 0;
|
||||
div.style.width = '100vw';
|
||||
div.style.height = '100vh';
|
||||
div.style.backgroundColor = 'black';
|
||||
div.style.color = '#E8E8E8';
|
||||
div.style.fontFamily = 'Menlo, Consolas, monospace';
|
||||
div.style.fontSize = 'large';
|
||||
div.style.padding = '2rem';
|
||||
div.style.lineHeight = '1.2';
|
||||
div.style.whiteSpace = 'pre-wrap';
|
||||
div.style.overflow = 'auto';
|
||||
iframe.contentDocument.body.appendChild(div);
|
||||
return div;
|
||||
}
|
||||
|
||||
// Make it look similar to our terminal.
|
||||
overlay.innerHTML =
|
||||
'<span style="color: #' +
|
||||
colors.red +
|
||||
'">Failed to compile.</span><br><br>' +
|
||||
ansiHTML(entities.encode(message));
|
||||
var overlayIframe = null;
|
||||
var overlayDiv = null;
|
||||
var lastOnOverlayDivReady = null;
|
||||
|
||||
// Render!
|
||||
iframe.contentDocument.body.appendChild(overlay);
|
||||
function ensureOverlayDivExists(onOverlayDivReady) {
|
||||
if (overlayDiv) {
|
||||
// Everything is ready, call the callback right away.
|
||||
onOverlayDivReady(overlayDiv);
|
||||
return;
|
||||
}
|
||||
|
||||
// Creating an iframe may be asynchronous so we'll schedule the callback.
|
||||
// In case of multiple calls, last callback wins.
|
||||
lastOnOverlayDivReady = onOverlayDivReady;
|
||||
|
||||
if (overlayIframe) {
|
||||
// We're already creating it.
|
||||
return;
|
||||
}
|
||||
|
||||
// Create iframe and, when it is ready, a div inside it.
|
||||
overlayIframe = createOverlayIframe(function onIframeLoad() {
|
||||
overlayDiv = addOverlayDivTo(overlayIframe);
|
||||
// Now we can talk!
|
||||
lastOnOverlayDivReady(overlayDiv);
|
||||
});
|
||||
|
||||
// Zalgo alert: onIframeLoad() will be called either synchronouly
|
||||
// or asynchronously depending on the browser.
|
||||
// We delay adding it so `overlayIframe` is set when `onIframeLoad` fires.
|
||||
document.body.appendChild(overlayIframe);
|
||||
}
|
||||
|
||||
function showErrorOverlay(message) {
|
||||
ensureOverlayDivExists(function onOverlayDivReady(overlayDiv) {
|
||||
// Make it look similar to our terminal.
|
||||
overlayDiv.innerHTML =
|
||||
'<span style="color: #' +
|
||||
colors.red +
|
||||
'">Failed to compile.</span><br><br>' +
|
||||
ansiHTML(entities.encode(message));
|
||||
});
|
||||
}
|
||||
|
||||
// Connect to WebpackDevServer via a socket.
|
||||
@@ -105,11 +137,22 @@ var connection = new SockJS(url.format({
|
||||
// Remember some state related to hot module replacement.
|
||||
var isFirstCompilation = true;
|
||||
var mostRecentCompilationHash = null;
|
||||
var hasCompileErrors = false;
|
||||
|
||||
function clearOutdatedErrors() {
|
||||
// Clean up outdated compile errors, if any.
|
||||
if (hasCompileErrors && typeof console.clear === 'function') {
|
||||
console.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Successful compilation.
|
||||
function handleSuccess() {
|
||||
clearOutdatedErrors();
|
||||
|
||||
var isHotUpdate = !isFirstCompilation;
|
||||
isFirstCompilation = false;
|
||||
hasCompileErrors = false;
|
||||
|
||||
// Attempt to apply hot updates or reload.
|
||||
if (isHotUpdate) {
|
||||
@@ -119,8 +162,11 @@ function handleSuccess() {
|
||||
|
||||
// Compilation with warnings (e.g. ESLint).
|
||||
function handleWarnings(warnings) {
|
||||
clearOutdatedErrors();
|
||||
|
||||
var isHotUpdate = !isFirstCompilation;
|
||||
isFirstCompilation = false;
|
||||
hasCompileErrors = false;
|
||||
|
||||
function printWarnings() {
|
||||
// Print warnings to the console.
|
||||
@@ -144,7 +190,10 @@ function handleWarnings(warnings) {
|
||||
|
||||
// Compilation with errors (e.g. syntax error or missing modules).
|
||||
function handleErrors(errors) {
|
||||
clearOutdatedErrors();
|
||||
|
||||
isFirstCompilation = false;
|
||||
hasCompileErrors = true;
|
||||
|
||||
// "Massage" webpack messages.
|
||||
var formatted = formatWebpackMessages({
|
||||
@@ -154,6 +203,12 @@ function handleErrors(errors) {
|
||||
|
||||
// Only show the first error.
|
||||
showErrorOverlay(formatted.errors[0]);
|
||||
|
||||
// Also log them to the console.
|
||||
for (var i = 0; i < formatted.errors.length; i++) {
|
||||
console.error(stripAnsi(formatted.errors[i]));
|
||||
}
|
||||
|
||||
// Do not attempt to reload now.
|
||||
// We will reload on next success instead.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user