@@ -39,13 +39,10 @@ var colors = {
39
39
} ;
40
40
ansiHTML . setColors ( colors ) ;
41
41
42
- function showErrorOverlay ( message ) {
43
- // Use an iframe so that document styles don't mess up the overlay.
44
- var iframeID = 'react-dev-utils-webpack-hot-dev-client-overlay' ;
45
- var iframe =
46
- document . getElementById ( iframeID ) ||
47
- document . createElement ( 'iframe' ) ;
48
- iframe . id = iframeID ;
42
+ function createOverlayIframe ( onIframeLoad ) {
43
+ var iframe = document . createElement ( 'iframe' ) ;
44
+ iframe . id = 'react-dev-utils-webpack-hot-dev-client-overlay' ;
45
+ iframe . src = 'about:blank' ;
49
46
iframe . style . position = 'fixed' ;
50
47
iframe . style . left = 0 ;
51
48
iframe . style . top = 0 ;
@@ -55,39 +52,74 @@ function showErrorOverlay(message) {
55
52
iframe . style . height = '100vh' ;
56
53
iframe . style . border = 'none' ;
57
54
iframe . style . zIndex = 9999999999 ;
58
- document . body . appendChild ( iframe ) ;
59
-
60
- // Inside, make a div.
61
- var overlayID = 'react-dev-utils-webpack-hot-dev-client-overlay-div' ;
62
- var overlay =
63
- iframe . contentDocument . getElementById ( overlayID ) ||
64
- iframe . contentDocument . createElement ( 'div' ) ;
65
- overlay . id = overlayID ;
66
- overlay . style . position = 'fixed' ;
67
- overlay . style . left = 0 ;
68
- overlay . style . top = 0 ;
69
- overlay . style . right = 0 ;
70
- overlay . style . bottom = 0 ;
71
- overlay . style . width = '100vw' ;
72
- overlay . style . height = '100vh' ;
73
- overlay . style . backgroundColor = 'black' ;
74
- overlay . style . color = '#E8E8E8' ;
75
- overlay . style . fontFamily = 'Menlo, Consolas, monospace' ;
76
- overlay . style . fontSize = 'large' ;
77
- overlay . style . padding = '2rem' ;
78
- overlay . style . lineHeight = '1.2' ;
79
- overlay . style . whiteSpace = 'pre-wrap' ;
80
- overlay . style . overflow = 'auto' ;
81
-
82
- // Make it look similar to our terminal.
83
- overlay . innerHTML =
84
- '<span style="color: #' +
85
- colors . red +
86
- '">Failed to compile.</span><br><br>' +
87
- ansiHTML ( entities . encode ( message ) ) ;
88
-
89
- // Render!
90
- iframe . contentDocument . body . appendChild ( overlay ) ;
55
+ iframe . onload = onIframeLoad ;
56
+ return iframe ;
57
+ }
58
+
59
+ function addOverlayDivTo ( iframe ) {
60
+ var div = iframe . contentDocument . createElement ( 'div' ) ;
61
+ div . id = 'react-dev-utils-webpack-hot-dev-client-overlay-div' ;
62
+ div . style . position = 'fixed' ;
63
+ div . style . left = 0 ;
64
+ div . style . top = 0 ;
65
+ div . style . right = 0 ;
66
+ div . style . bottom = 0 ;
67
+ div . style . width = '100vw' ;
68
+ div . style . height = '100vh' ;
69
+ div . style . backgroundColor = 'black' ;
70
+ div . style . color = '#E8E8E8' ;
71
+ div . style . fontFamily = 'Menlo, Consolas, monospace' ;
72
+ div . style . fontSize = 'large' ;
73
+ div . style . padding = '2rem' ;
74
+ div . style . lineHeight = '1.2' ;
75
+ div . style . whiteSpace = 'pre-wrap' ;
76
+ div . style . overflow = 'auto' ;
77
+ iframe . contentDocument . body . appendChild ( div ) ;
78
+ return div ;
79
+ }
80
+
81
+ var overlayIframe = null ;
82
+ var overlayDiv = null ;
83
+ var lastOnOverlayDivReady = null ;
84
+
85
+ function ensureOverlayDivExists ( onOverlayDivReady ) {
86
+ if ( overlayDiv ) {
87
+ // Everything is ready, call the callback right away.
88
+ onOverlayDivReady ( overlayDiv ) ;
89
+ return ;
90
+ }
91
+
92
+ // Creating an iframe may be asynchronous so we'll schedule the callback.
93
+ // In case of multiple calls, last callback wins.
94
+ lastOnOverlayDivReady = onOverlayDivReady ;
95
+
96
+ if ( overlayIframe ) {
97
+ // We're already creating it.
98
+ return ;
99
+ }
100
+
101
+ // Create iframe and, when it is ready, a div inside it.
102
+ overlayIframe = createOverlayIframe ( function onIframeLoad ( ) {
103
+ overlayDiv = addOverlayDivTo ( overlayIframe ) ;
104
+ // Now we can talk!
105
+ lastOnOverlayDivReady ( overlayDiv ) ;
106
+ } ) ;
107
+
108
+ // Zalgo alert: onIframeLoad() will be called either synchronouly
109
+ // or asynchronously depending on the browser.
110
+ // We delay adding it so `overlayIframe` is set when `onIframeLoad` fires.
111
+ document . body . appendChild ( overlayIframe ) ;
112
+ }
113
+
114
+ function showErrorOverlay ( message ) {
115
+ ensureOverlayDivExists ( function onOverlayDivReady ( overlayDiv ) {
116
+ // Make it look similar to our terminal.
117
+ overlayDiv . innerHTML =
118
+ '<span style="color: #' +
119
+ colors . red +
120
+ '">Failed to compile.</span><br><br>' +
121
+ ansiHTML ( entities . encode ( message ) ) ;
122
+ } ) ;
91
123
}
92
124
93
125
// Connect to WebpackDevServer via a socket.
@@ -105,11 +137,22 @@ var connection = new SockJS(url.format({
105
137
// Remember some state related to hot module replacement.
106
138
var isFirstCompilation = true ;
107
139
var mostRecentCompilationHash = null ;
140
+ var hasCompileErrors = false ;
141
+
142
+ function clearOutdatedErrors ( ) {
143
+ // Clean up outdated compile errors, if any.
144
+ if ( hasCompileErrors && typeof console . clear === 'function' ) {
145
+ console . clear ( ) ;
146
+ }
147
+ }
108
148
109
149
// Successful compilation.
110
150
function handleSuccess ( ) {
151
+ clearOutdatedErrors ( ) ;
152
+
111
153
var isHotUpdate = ! isFirstCompilation ;
112
154
isFirstCompilation = false ;
155
+ hasCompileErrors = false ;
113
156
114
157
// Attempt to apply hot updates or reload.
115
158
if ( isHotUpdate ) {
@@ -119,8 +162,11 @@ function handleSuccess() {
119
162
120
163
// Compilation with warnings (e.g. ESLint).
121
164
function handleWarnings ( warnings ) {
165
+ clearOutdatedErrors ( ) ;
166
+
122
167
var isHotUpdate = ! isFirstCompilation ;
123
168
isFirstCompilation = false ;
169
+ hasCompileErrors = false ;
124
170
125
171
function printWarnings ( ) {
126
172
// Print warnings to the console.
@@ -144,7 +190,10 @@ function handleWarnings(warnings) {
144
190
145
191
// Compilation with errors (e.g. syntax error or missing modules).
146
192
function handleErrors ( errors ) {
193
+ clearOutdatedErrors ( ) ;
194
+
147
195
isFirstCompilation = false ;
196
+ hasCompileErrors = true ;
148
197
149
198
// "Massage" webpack messages.
150
199
var formatted = formatWebpackMessages ( {
@@ -154,6 +203,12 @@ function handleErrors(errors) {
154
203
155
204
// Only show the first error.
156
205
showErrorOverlay ( formatted . errors [ 0 ] ) ;
206
+
207
+ // Also log them to the console.
208
+ for ( var i = 0 ; i < formatted . errors . length ; i ++ ) {
209
+ console . error ( stripAnsi ( formatted . errors [ i ] ) ) ;
210
+ }
211
+
157
212
// Do not attempt to reload now.
158
213
// We will reload on next success instead.
159
214
}
0 commit comments