Skip to content

Commit b0d7246

Browse files
committed
feat: improve error and warning messages in overlay
1 parent 9b7ae7b commit b0d7246

File tree

4 files changed

+159
-34
lines changed

4 files changed

+159
-34
lines changed

client-src/overlay.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import ansiHTML from "ansi-html-community";
55
import { encode } from "html-entities";
6+
import formatWebpackMessage from "./utils/format-webpack-message.js";
67

78
const colors = {
89
reset: ["transparent", "transparent"],
@@ -126,11 +127,8 @@ function hide() {
126127

127128
function formatProblem(type, item) {
128129
let header = type === "warning" ? "WARNING" : "ERROR";
129-
let body = "";
130130

131-
if (typeof item === "string") {
132-
body += item;
133-
} else {
131+
if (typeof item === "object") {
134132
const file = item.file || "";
135133
// eslint-disable-next-line no-nested-ternary
136134
const moduleName = item.moduleName
@@ -147,10 +145,9 @@ function formatProblem(type, item) {
147145
}${loc ? ` ${loc}` : ""}`
148146
: ""
149147
}`;
150-
body += item.message || "";
151148
}
152149

153-
return { header, body };
150+
return { header, body: formatWebpackMessage(item) };
154151
}
155152

156153
// Compilation with errors (e.g. syntax error or missing modules).
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/**
2+
MIT License
3+
Copyright (c) 2015-present, Facebook, Inc.
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18+
SOFTWARE.
19+
*/
20+
21+
import stripAnsi from "../modules/strip-ansi/index.js";
22+
// This file is based on https://github.com/facebook/create-react-app/blob/7b1a32be6ec9f99a6c9a3c66813f3ac09c4736b9/packages/react-dev-utils/formatWebpackMessages.js
23+
// It's been edited to remove chalk and CRA-specific logic
24+
25+
const friendlySyntaxErrorLabel = "Syntax error:";
26+
27+
// Cleans up webpack error messages.
28+
function formatWebpackMessage(message, verbose) {
29+
if (typeof message === "object" && message.message) {
30+
const filteredModuleTrace =
31+
message.moduleTrace &&
32+
message.moduleTrace.filter(
33+
(trace) =>
34+
!/next-(middleware|client-pages|flight-(client|server))-loader\.js/.test(
35+
trace.originName
36+
)
37+
);
38+
message =
39+
(message.moduleName ? `${stripAnsi(message.moduleName)}\n` : "") +
40+
(message.file ? `${stripAnsi(message.file)}\n` : "") +
41+
message.message +
42+
(message.details && verbose ? `\n${message.details}` : "") +
43+
(filteredModuleTrace && filteredModuleTrace.length && verbose
44+
? `\n\nImport trace for requested module:${filteredModuleTrace
45+
.map((trace) => `\n${trace.originName}`)
46+
.join("")}`
47+
: "") +
48+
(message.stack && verbose ? `\n${message.stack}` : "");
49+
}
50+
let lines = message.split("\n");
51+
52+
// Strip Webpack-added headers off errors/warnings
53+
// https://github.com/webpack/webpack/blob/master/lib/ModuleError.js
54+
lines = lines.filter((line) => !/Module [A-z ]+\(from/.test(line));
55+
56+
// Transform parsing error into syntax error
57+
lines = lines.map((line) => {
58+
const parsingError = /Line (\d+):(?:(\d+):)?\s*Parsing error: (.+)$/.exec(
59+
line
60+
);
61+
if (!parsingError) {
62+
return line;
63+
}
64+
const [, errorLine, errorColumn, errorMessage] = parsingError;
65+
return `${friendlySyntaxErrorLabel} ${errorMessage} (${errorLine}:${errorColumn})`;
66+
});
67+
68+
message = lines.join("\n");
69+
// Smoosh syntax errors (commonly found in CSS)
70+
message = message.replace(
71+
/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
72+
`${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
73+
);
74+
// Clean up export errors
75+
message = message.replace(
76+
/^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
77+
`Attempted import error: '$1' is not exported from '$2'.`
78+
);
79+
message = message.replace(
80+
/^.*export 'default' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
81+
`Attempted import error: '$2' does not contain a default export (imported as '$1').`
82+
);
83+
message = message.replace(
84+
/^.*export '(.+?)' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
85+
`Attempted import error: '$1' is not exported from '$3' (imported as '$2').`
86+
);
87+
lines = message.split("\n");
88+
89+
// Remove leading newline
90+
if (lines.length > 2 && lines[1].trim() === "") {
91+
lines.splice(1, 1);
92+
}
93+
94+
// Cleans up verbose "module not found" messages for files and packages.
95+
if (lines[1] && lines[1].indexOf("Module not found: ") === 0) {
96+
lines = [
97+
lines[0],
98+
lines[1]
99+
.replace("Error: ", "")
100+
.replace("Module not found: Cannot find file:", "Cannot find file:"),
101+
...lines.slice(2),
102+
];
103+
}
104+
105+
if (!verbose) {
106+
message = lines.join("\n");
107+
// Internal stacks are generally useless so we strip them... with the
108+
// exception of stacks containing `webpack:` because they're normally
109+
// from user code generated by Webpack. For more information see
110+
// https://github.com/facebook/create-react-app/pull/1050
111+
message = message.replace(
112+
/^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm,
113+
""
114+
// eslint-disable-next-line line-comment-position
115+
); // at ... ...:x:y
116+
// eslint-disable-next-line line-comment-position
117+
message = message.replace(/^\s*at\s<anonymous>(\n|$)/gm, ""); // at <anonymous>
118+
lines = message.split("\n");
119+
}
120+
121+
// Remove duplicated newlines
122+
lines = lines.filter(
123+
(line, index, arr) =>
124+
index === 0 || line.trim() !== "" || line.trim() !== arr[index - 1].trim()
125+
);
126+
127+
// Reassemble the message
128+
message = lines.join("\n");
129+
return message.trim();
130+
}
131+
132+
export default formatWebpackMessage;

test/e2e/__snapshots__/overlay.test.js.snap.webpack4

+12-12
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ exports[`overlay should not show initially, then show on an error and allow to c
6565
<div>
6666
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
6767
<div>
68-
./foo.js 1:1 Module parse failed: Unterminated template (1:1) You may
69-
need an appropriate loader to handle this file type, currently no
70-
loaders are configured to process this file. See
68+
./foo.js Module parse failed: Unterminated template (1:1) You may need
69+
an appropriate loader to handle this file type, currently no loaders are
70+
configured to process this file. See
7171
https://webpack.js.org/concepts#loaders &gt; \`;
7272
</div>
7373
<br /><br />
@@ -147,9 +147,9 @@ exports[`overlay should not show initially, then show on an error, then hide on
147147
<div>
148148
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
149149
<div>
150-
./foo.js 1:1 Module parse failed: Unterminated template (1:1) You may
151-
need an appropriate loader to handle this file type, currently no
152-
loaders are configured to process this file. See
150+
./foo.js Module parse failed: Unterminated template (1:1) You may need
151+
an appropriate loader to handle this file type, currently no loaders are
152+
configured to process this file. See
153153
https://webpack.js.org/concepts#loaders &gt; \`;
154154
</div>
155155
<br /><br />
@@ -229,9 +229,9 @@ exports[`overlay should not show initially, then show on an error, then show oth
229229
<div>
230230
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
231231
<div>
232-
./foo.js 1:1 Module parse failed: Unterminated template (1:1) You may
233-
need an appropriate loader to handle this file type, currently no
234-
loaders are configured to process this file. See
232+
./foo.js Module parse failed: Unterminated template (1:1) You may need
233+
an appropriate loader to handle this file type, currently no loaders are
234+
configured to process this file. See
235235
https://webpack.js.org/concepts#loaders &gt; \`;
236236
</div>
237237
<br /><br />
@@ -278,9 +278,9 @@ exports[`overlay should not show initially, then show on an error, then show oth
278278
<div>
279279
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
280280
<div>
281-
./foo.js 1:1 Module parse failed: Unterminated template (1:1) You may
282-
need an appropriate loader to handle this file type, currently no
283-
loaders are configured to process this file. See
281+
./foo.js Module parse failed: Unterminated template (1:1) You may need
282+
an appropriate loader to handle this file type, currently no loaders are
283+
configured to process this file. See
284284
https://webpack.js.org/concepts#loaders &gt; \`;a
285285
</div>
286286
<br /><br />

test/e2e/__snapshots__/overlay.test.js.snap.webpack5

+12-16
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,10 @@ exports[`overlay should not show initially, then show on an error and allow to c
6363
X</button
6464
><br /><br />
6565
<div>
66-
<span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
67-
><br /><br />
66+
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
6867
<div>
69-
Module parse failed: Unterminated template (1:1) You may need an
70-
appropriate loader to handle this file type, currently no loaders are
68+
./foo.js Module parse failed: Unterminated template (1:1) You may need
69+
an appropriate loader to handle this file type, currently no loaders are
7170
configured to process this file. See
7271
https://webpack.js.org/concepts#loaders &gt; \`;
7372
</div>
@@ -146,11 +145,10 @@ exports[`overlay should not show initially, then show on an error, then hide on
146145
X</button
147146
><br /><br />
148147
<div>
149-
<span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
150-
><br /><br />
148+
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
151149
<div>
152-
Module parse failed: Unterminated template (1:1) You may need an
153-
appropriate loader to handle this file type, currently no loaders are
150+
./foo.js Module parse failed: Unterminated template (1:1) You may need
151+
an appropriate loader to handle this file type, currently no loaders are
154152
configured to process this file. See
155153
https://webpack.js.org/concepts#loaders &gt; \`;
156154
</div>
@@ -229,11 +227,10 @@ exports[`overlay should not show initially, then show on an error, then show oth
229227
X</button
230228
><br /><br />
231229
<div>
232-
<span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
233-
><br /><br />
230+
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
234231
<div>
235-
Module parse failed: Unterminated template (1:1) You may need an
236-
appropriate loader to handle this file type, currently no loaders are
232+
./foo.js Module parse failed: Unterminated template (1:1) You may need
233+
an appropriate loader to handle this file type, currently no loaders are
237234
configured to process this file. See
238235
https://webpack.js.org/concepts#loaders &gt; \`;
239236
</div>
@@ -279,11 +276,10 @@ exports[`overlay should not show initially, then show on an error, then show oth
279276
X</button
280277
><br /><br />
281278
<div>
282-
<span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
283-
><br /><br />
279+
<span style=\\"color: rgb(227, 96, 73)\\">ERROR</span><br /><br />
284280
<div>
285-
Module parse failed: Unterminated template (1:1) You may need an
286-
appropriate loader to handle this file type, currently no loaders are
281+
./foo.js Module parse failed: Unterminated template (1:1) You may need
282+
an appropriate loader to handle this file type, currently no loaders are
287283
configured to process this file. See
288284
https://webpack.js.org/concepts#loaders &gt; \`;a
289285
</div>

0 commit comments

Comments
 (0)