From b78547a36609a47db54b814c2e740e40c29e13a8 Mon Sep 17 00:00:00 2001
From: Nitin Kumar <snitin315@gmail.com>
Date: Thu, 9 Dec 2021 16:27:51 +0530
Subject: [PATCH 1/4] feat: improve error and warning messages in overlay

---
 client-src/overlay.js                         |   9 +-
 client-src/utils/format-webpack-message.js    | 132 ++++++++++++++++++
 .../overlay.test.js.snap.webpack5             |  16 +--
 3 files changed, 143 insertions(+), 14 deletions(-)
 create mode 100644 client-src/utils/format-webpack-message.js

diff --git a/client-src/overlay.js b/client-src/overlay.js
index 5c074702ff..1edbb781e0 100644
--- a/client-src/overlay.js
+++ b/client-src/overlay.js
@@ -3,6 +3,7 @@
 
 import ansiHTML from "ansi-html-community";
 import { encode } from "html-entities";
+import formatWebpackMessage from "./utils/format-webpack-message.js";
 
 const colors = {
   reset: ["transparent", "transparent"],
@@ -147,11 +148,8 @@ function hide() {
  */
 function formatProblem(type, item) {
   let header = type === "warning" ? "WARNING" : "ERROR";
-  let body = "";
 
-  if (typeof item === "string") {
-    body += item;
-  } else {
+  if (typeof item === "object") {
     const file = item.file || "";
     // eslint-disable-next-line no-nested-ternary
     const moduleName = item.moduleName
@@ -168,10 +166,9 @@ function formatProblem(type, item) {
           }${loc ? ` ${loc}` : ""}`
         : ""
     }`;
-    body += item.message || "";
   }
 
-  return { header, body };
+  return { header, body: formatWebpackMessage(item) };
 }
 
 // Compilation with errors (e.g. syntax error or missing modules).
diff --git a/client-src/utils/format-webpack-message.js b/client-src/utils/format-webpack-message.js
new file mode 100644
index 0000000000..dccf8f5819
--- /dev/null
+++ b/client-src/utils/format-webpack-message.js
@@ -0,0 +1,132 @@
+/**
+MIT License
+Copyright (c) 2015-present, Facebook, Inc.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+import stripAnsi from "../modules/strip-ansi/index.js";
+// This file is based on https://github.com/facebook/create-react-app/blob/7b1a32be6ec9f99a6c9a3c66813f3ac09c4736b9/packages/react-dev-utils/formatWebpackMessages.js
+// It's been edited to remove chalk and CRA-specific logic
+
+const friendlySyntaxErrorLabel = "Syntax error:";
+
+// Cleans up webpack error messages.
+function formatWebpackMessage(message, verbose) {
+  if (typeof message === "object" && message.message) {
+    const filteredModuleTrace =
+      message.moduleTrace &&
+      message.moduleTrace.filter(
+        (trace) =>
+          !/next-(middleware|client-pages|flight-(client|server))-loader\.js/.test(
+            trace.originName
+          )
+      );
+    message =
+      (message.moduleName ? `${stripAnsi(message.moduleName)}\n` : "") +
+      (message.file ? `${stripAnsi(message.file)}\n` : "") +
+      message.message +
+      (message.details && verbose ? `\n${message.details}` : "") +
+      (filteredModuleTrace && filteredModuleTrace.length && verbose
+        ? `\n\nImport trace for requested module:${filteredModuleTrace
+            .map((trace) => `\n${trace.originName}`)
+            .join("")}`
+        : "") +
+      (message.stack && verbose ? `\n${message.stack}` : "");
+  }
+  let lines = message.split("\n");
+
+  // Strip Webpack-added headers off errors/warnings
+  // https://github.com/webpack/webpack/blob/master/lib/ModuleError.js
+  lines = lines.filter((line) => !/Module [A-z ]+\(from/.test(line));
+
+  // Transform parsing error into syntax error
+  lines = lines.map((line) => {
+    const parsingError = /Line (\d+):(?:(\d+):)?\s*Parsing error: (.+)$/.exec(
+      line
+    );
+    if (!parsingError) {
+      return line;
+    }
+    const [, errorLine, errorColumn, errorMessage] = parsingError;
+    return `${friendlySyntaxErrorLabel} ${errorMessage} (${errorLine}:${errorColumn})`;
+  });
+
+  message = lines.join("\n");
+  // Smoosh syntax errors (commonly found in CSS)
+  message = message.replace(
+    /SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
+    `${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
+  );
+  // Clean up export errors
+  message = message.replace(
+    /^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
+    `Attempted import error: '$1' is not exported from '$2'.`
+  );
+  message = message.replace(
+    /^.*export 'default' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
+    `Attempted import error: '$2' does not contain a default export (imported as '$1').`
+  );
+  message = message.replace(
+    /^.*export '(.+?)' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
+    `Attempted import error: '$1' is not exported from '$3' (imported as '$2').`
+  );
+  lines = message.split("\n");
+
+  // Remove leading newline
+  if (lines.length > 2 && lines[1].trim() === "") {
+    lines.splice(1, 1);
+  }
+
+  // Cleans up verbose "module not found" messages for files and packages.
+  if (lines[1] && lines[1].indexOf("Module not found: ") === 0) {
+    lines = [
+      lines[0],
+      lines[1]
+        .replace("Error: ", "")
+        .replace("Module not found: Cannot find file:", "Cannot find file:"),
+      ...lines.slice(2),
+    ];
+  }
+
+  if (!verbose) {
+    message = lines.join("\n");
+    // Internal stacks are generally useless so we strip them... with the
+    // exception of stacks containing `webpack:` because they're normally
+    // from user code generated by Webpack. For more information see
+    // https://github.com/facebook/create-react-app/pull/1050
+    message = message.replace(
+      /^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm,
+      ""
+      // eslint-disable-next-line line-comment-position
+    ); // at ... ...:x:y
+    // eslint-disable-next-line line-comment-position
+    message = message.replace(/^\s*at\s<anonymous>(\n|$)/gm, ""); // at <anonymous>
+    lines = message.split("\n");
+  }
+
+  // Remove duplicated newlines
+  lines = lines.filter(
+    (line, index, arr) =>
+      index === 0 || line.trim() !== "" || line.trim() !== arr[index - 1].trim()
+  );
+
+  // Reassemble the message
+  message = lines.join("\n");
+  return message.trim();
+}
+
+export default formatWebpackMessage;
diff --git a/test/e2e/__snapshots__/overlay.test.js.snap.webpack5 b/test/e2e/__snapshots__/overlay.test.js.snap.webpack5
index c8a56d4012..20efe665c7 100644
--- a/test/e2e/__snapshots__/overlay.test.js.snap.webpack5
+++ b/test/e2e/__snapshots__/overlay.test.js.snap.webpack5
@@ -70,8 +70,8 @@ exports[`overlay should not show initially, then show on an error and allow to c
       <span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
       ><br /><br />
       <div>
-        Module parse failed: Unterminated template (1:1) You may need an
-        appropriate loader to handle this file type, currently no loaders are
+        ./foo.js Module parse failed: Unterminated template (1:1) You may need
+        an appropriate loader to handle this file type, currently no loaders are
         configured to process this file. See
         https://webpack.js.org/concepts#loaders &gt; \`;
       </div>
@@ -157,8 +157,8 @@ exports[`overlay should not show initially, then show on an error, then hide on
       <span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
       ><br /><br />
       <div>
-        Module parse failed: Unterminated template (1:1) You may need an
-        appropriate loader to handle this file type, currently no loaders are
+        ./foo.js Module parse failed: Unterminated template (1:1) You may need
+        an appropriate loader to handle this file type, currently no loaders are
         configured to process this file. See
         https://webpack.js.org/concepts#loaders &gt; \`;
       </div>
@@ -244,8 +244,8 @@ exports[`overlay should not show initially, then show on an error, then show oth
       <span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
       ><br /><br />
       <div>
-        Module parse failed: Unterminated template (1:1) You may need an
-        appropriate loader to handle this file type, currently no loaders are
+        ./foo.js Module parse failed: Unterminated template (1:1) You may need
+        an appropriate loader to handle this file type, currently no loaders are
         configured to process this file. See
         https://webpack.js.org/concepts#loaders &gt; \`;
       </div>
@@ -294,8 +294,8 @@ exports[`overlay should not show initially, then show on an error, then show oth
       <span style=\\"color: rgb(227, 96, 73)\\">ERROR in ./foo.js 1:1</span
       ><br /><br />
       <div>
-        Module parse failed: Unterminated template (1:1) You may need an
-        appropriate loader to handle this file type, currently no loaders are
+        ./foo.js Module parse failed: Unterminated template (1:1) You may need
+        an appropriate loader to handle this file type, currently no loaders are
         configured to process this file. See
         https://webpack.js.org/concepts#loaders &gt; \`;a
       </div>

From c2495203a96005a1080d4fb7ba13e7198a923bc3 Mon Sep 17 00:00:00 2001
From: Nitin Kumar <snitin315@gmail.com>
Date: Sun, 17 Apr 2022 07:41:07 +0530
Subject: [PATCH 2/4] fix: lint and debug

---
 client-src/utils/format-webpack-message.js | 2 +-
 package.json                               | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/client-src/utils/format-webpack-message.js b/client-src/utils/format-webpack-message.js
index dccf8f5819..ef437eda13 100644
--- a/client-src/utils/format-webpack-message.js
+++ b/client-src/utils/format-webpack-message.js
@@ -18,7 +18,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 */
 
-import stripAnsi from "../modules/strip-ansi/index.js";
+import stripAnsi from "./stripAnsi.js";
 // This file is based on https://github.com/facebook/create-react-app/blob/7b1a32be6ec9f99a6c9a3c66813f3ac09c4736b9/packages/react-dev-utils/formatWebpackMessages.js
 // It's been edited to remove chalk and CRA-specific logic
 
diff --git a/package.json b/package.json
index b819330d08..c65dfdeaa2 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
     "build:client": "rimraf ./client/* && babel client-src/ --out-dir client/ --ignore \"client-src/webpack.config.js\" --ignore \"client-src/modules\" && webpack --config client-src/webpack.config.js",
     "build:types": "rimraf ./types/* && tsc --declaration --emitDeclarationOnly --outDir types && node ./scripts/extend-webpack-types.js && prettier \"types/**/*.ts\" --write && prettier \"types/**/*.ts\" --write",
     "build": "npm-run-all -p \"build:**\"",
-    "test:only": "jest",
+    "test:only": "jest overlay.test.js",
     "test:coverage": "npm run test:only -- --coverage",
     "test:watch": "npm run test:coverage --watch",
     "test": "npm run test:coverage",

From 0269db43806c43fc60c891099253ded22f0c96db Mon Sep 17 00:00:00 2001
From: Nitin Kumar <snitin315@gmail.com>
Date: Sun, 17 Apr 2022 07:47:34 +0530
Subject: [PATCH 3/4] test: fix

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index c65dfdeaa2..b819330d08 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
     "build:client": "rimraf ./client/* && babel client-src/ --out-dir client/ --ignore \"client-src/webpack.config.js\" --ignore \"client-src/modules\" && webpack --config client-src/webpack.config.js",
     "build:types": "rimraf ./types/* && tsc --declaration --emitDeclarationOnly --outDir types && node ./scripts/extend-webpack-types.js && prettier \"types/**/*.ts\" --write && prettier \"types/**/*.ts\" --write",
     "build": "npm-run-all -p \"build:**\"",
-    "test:only": "jest overlay.test.js",
+    "test:only": "jest",
     "test:coverage": "npm run test:only -- --coverage",
     "test:watch": "npm run test:coverage --watch",
     "test": "npm run test:coverage",

From 3d8c2d4467324f4b029f4087ad772d7e4ed3d18c Mon Sep 17 00:00:00 2001
From: Nitin Kumar <snitin315@gmail.com>
Date: Sun, 17 Apr 2022 08:16:55 +0530
Subject: [PATCH 4/4] test: update snapshot

---
 .../multi-compiler.test.js.snap.webpack5             | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/test/e2e/__snapshots__/multi-compiler.test.js.snap.webpack5 b/test/e2e/__snapshots__/multi-compiler.test.js.snap.webpack5
index ca63857c9e..3537ab5f38 100644
--- a/test/e2e/__snapshots__/multi-compiler.test.js.snap.webpack5
+++ b/test/e2e/__snapshots__/multi-compiler.test.js.snap.webpack5
@@ -55,13 +55,13 @@ Array [
   "[HMR] Cannot apply update. Need to do a full reload!",
   "[HMR] Error: Aborted because ./browser.js is not accepted
 Update propagation: ./browser.js
-    at applyHandler (http://127.0.0.1:8103/browser.js:1034:31)
-    at http://127.0.0.1:8103/browser.js:733:21
+    at applyHandler (http://127.0.0.1:8103/browser.js:1045:31)
+    at http://127.0.0.1:8103/browser.js:744:21
     at Array.map (<anonymous>)
-    at internalApply (http://127.0.0.1:8103/browser.js:732:54)
-    at http://127.0.0.1:8103/browser.js:702:26
-    at waitForBlockingPromises (http://127.0.0.1:8103/browser.js:656:48)
-    at http://127.0.0.1:8103/browser.js:700:24",
+    at internalApply (http://127.0.0.1:8103/browser.js:743:54)
+    at http://127.0.0.1:8103/browser.js:713:26
+    at waitForBlockingPromises (http://127.0.0.1:8103/browser.js:667:48)
+    at http://127.0.0.1:8103/browser.js:711:24",
   "[HMR] Waiting for update signal from WDS...",
   "Hello from the browser",
   "[webpack-dev-server] Hot Module Replacement enabled.",