@@ -23,9 +23,14 @@ function isLikelyASyntaxError(message) {
23
23
}
24
24
25
25
// Cleans up webpack error messages.
26
- function formatMessage ( message ) {
26
+ function formatMessage ( message , isError ) {
27
27
var lines = message . split ( '\n' ) ;
28
28
29
+ if ( lines . length > 2 && lines [ 1 ] === '' ) {
30
+ // Remove extra newline.
31
+ lines . splice ( 1 , 1 ) ;
32
+ }
33
+
29
34
// Remove webpack-specific loader notation from filename.
30
35
// Before:
31
36
// ./~/css-loader!./~/postcss-loader!./src/App.css
@@ -35,6 +40,15 @@ function formatMessage(message) {
35
40
lines [ 0 ] = lines [ 0 ] . substr ( lines [ 0 ] . lastIndexOf ( '!' ) + 1 ) ;
36
41
}
37
42
43
+ lines = lines . filter ( function ( line ) {
44
+ // Webpack adds a list of entry points to warning messages:
45
+ // @ ./src/index.js
46
+ // @ multi react-scripts/~/react-dev-utils/webpackHotDevClient.js ...
47
+ // It is misleading (and unrelated to the warnings) so we clean it up.
48
+ // It is only useful for syntax errors but we have beautiful frames for them.
49
+ return line . indexOf ( ' @ ' ) !== 0 ;
50
+ } ) ;
51
+
38
52
// line #0 is filename
39
53
// line #1 is the main error message
40
54
if ( ! lines [ 0 ] || ! lines [ 1 ] ) {
@@ -50,54 +64,76 @@ function formatMessage(message) {
50
64
. replace ( "Cannot resolve 'file' or 'directory' " , '' )
51
65
. replace ( 'Cannot resolve module ' , '' )
52
66
. replace ( 'Error: ' , '' ) ,
53
- // Skip all irrelevant lines.
54
- // (For some reason they only appear on the client in browser.)
55
- '' ,
56
- lines [ lines . length - 1 ] , // error location is the last line
57
67
] ;
58
68
}
59
69
60
70
// Cleans up syntax error messages.
61
71
if ( lines [ 1 ] . indexOf ( 'Module build failed: ' ) === 0 ) {
62
- // For some reason, on the client messages appear duplicated:
63
- // https://github.com/webpack/webpack/issues/3008
64
- // This won't happen in Node but since we share this helpers,
65
- // we will dedupe them right here. We will ignore all lines
66
- // after the original error message text is repeated the second time.
67
- var errorText = lines [ 1 ] . substr ( 'Module build failed: ' . length ) ;
68
- var cleanedLines = [ ] ;
69
- var hasReachedDuplicateMessage = false ;
70
- // Gather lines until we reach the beginning of duplicate message.
71
- lines . forEach ( function ( line , index ) {
72
- if (
73
- // First time it occurs is fine.
74
- index !== 1 &&
75
- // line.endsWith(errorText)
76
- line . length >= errorText . length &&
77
- line . indexOf ( errorText ) === line . length - errorText . length
78
- ) {
79
- // We see the same error message for the second time!
80
- // Filter out repeated error message and everything after it.
81
- hasReachedDuplicateMessage = true ;
82
- }
83
- if (
84
- ! hasReachedDuplicateMessage ||
85
- // Print last line anyway because it contains the source location
86
- index === lines . length - 1
87
- ) {
88
- // This line is OK to appear in the output.
89
- cleanedLines . push ( line ) ;
90
- }
91
- } ) ;
92
- // We are clean now!
93
- lines = cleanedLines ;
94
- // Finally, brush up the error message a little.
95
72
lines [ 1 ] = lines [ 1 ] . replace (
96
73
'Module build failed: SyntaxError:' ,
97
74
friendlySyntaxErrorLabel
98
75
) ;
99
76
}
100
77
78
+ // Clean up export errors.
79
+ // TODO: we should really send a PR to Webpack for this.
80
+ var exportError = / \s * ( .+ ?) \s * ( " ) ? e x p o r t ' ( .+ ?) ' w a s n o t f o u n d i n ' ( .+ ?) ' / ;
81
+ if ( lines [ 1 ] . match ( exportError ) ) {
82
+ lines [ 1 ] = lines [ 1 ] . replace (
83
+ exportError ,
84
+ "$1 '$4' does not contain an export named '$3'."
85
+ ) ;
86
+ }
87
+
88
+ // TODO: Ideally we should write a custom ESLint formatter instead.
89
+
90
+ // If the second line already includes a filename, and it's a warning,
91
+ // this is likely coming from ESLint. Skip it because Webpack also prints it.
92
+ // Let's omit that in this case.
93
+ var BEGIN_ESLINT_FILENAME = String . fromCharCode ( 27 ) + '[4m' ;
94
+ // Also filter out ESLint summaries for each file
95
+ var BEGIN_ESLINT_WARNING_SUMMARY = String . fromCharCode ( 27 ) +
96
+ '[33m' +
97
+ String . fromCharCode ( 27 ) +
98
+ '[1m' +
99
+ String . fromCharCode ( 10006 ) ;
100
+ var BEGIN_ESLINT_ERROR_SUMMARY = String . fromCharCode ( 27 ) +
101
+ '[31m' +
102
+ String . fromCharCode ( 27 ) +
103
+ '[1m' +
104
+ String . fromCharCode ( 10006 ) ;
105
+ // ESLint puts separators like this between groups. We don't need them:
106
+ var ESLINT_EMPTY_SEPARATOR = String . fromCharCode ( 27 ) +
107
+ '[22m' +
108
+ String . fromCharCode ( 27 ) +
109
+ '[39m' ;
110
+ // Go!
111
+ lines = lines . filter ( function ( line ) {
112
+ if ( line === ESLINT_EMPTY_SEPARATOR ) {
113
+ return false ;
114
+ }
115
+ if (
116
+ line . indexOf ( BEGIN_ESLINT_FILENAME ) === 0 ||
117
+ line . indexOf ( BEGIN_ESLINT_WARNING_SUMMARY ) === 0 ||
118
+ line . indexOf ( BEGIN_ESLINT_ERROR_SUMMARY ) === 0
119
+ ) {
120
+ return false ;
121
+ }
122
+ return true ;
123
+ } ) ;
124
+
125
+ // Prepend filename with an explanation.
126
+ lines [ 0 ] =
127
+ // Underline
128
+ String . fromCharCode ( 27 ) +
129
+ '[4m' +
130
+ // Filename
131
+ lines [ 0 ] +
132
+ // End underline
133
+ String . fromCharCode ( 27 ) +
134
+ '[24m' +
135
+ ( isError ? ' contains errors.' : ' contains warnings.' ) ;
136
+
101
137
// Reassemble the message.
102
138
message = lines . join ( '\n' ) ;
103
139
// Internal stacks are generally useless so we strip them... with the
@@ -109,15 +145,15 @@ function formatMessage(message) {
109
145
''
110
146
) ; // at ... ...:x:y
111
147
112
- return message ;
148
+ return message . trim ( ) ;
113
149
}
114
150
115
151
function formatWebpackMessages ( json ) {
116
152
var formattedErrors = json . errors . map ( function ( message ) {
117
- return 'Error in ' + formatMessage ( message ) ;
153
+ return formatMessage ( message , true ) ;
118
154
} ) ;
119
155
var formattedWarnings = json . warnings . map ( function ( message ) {
120
- return 'Warning in ' + formatMessage ( message ) ;
156
+ return formatMessage ( message , false ) ;
121
157
} ) ;
122
158
var result = {
123
159
errors : formattedErrors ,
0 commit comments