From 10da2238b0fce26973160ef03ba0dd35d5bc0568 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Thu, 4 Nov 2021 21:46:29 +0300 Subject: [PATCH] fix: infinity refresh on warnings (#4006) --- client-src/index.js | 2 - package-lock.json | 91 +++++++++++++ package.json | 2 + test/client/index.test.js | 1 - .../overlay.test.js.snap.webpack4 | 126 ++++++++++++++++++ .../overlay.test.js.snap.webpack5 | 126 ++++++++++++++++++ test/e2e/overlay.test.js | 126 +++++++++++++++++- 7 files changed, 469 insertions(+), 5 deletions(-) diff --git a/client-src/index.js b/client-src/index.js index 6ee246baef..414610b57a 100644 --- a/client-src/index.js +++ b/client-src/index.js @@ -183,8 +183,6 @@ const onSocketMessage = { if (needShowOverlayForWarnings) { show("warning", warnings); } - - reloadApp(options, status); }, errors(errors) { log.error("Errors while compiling. Reload prevented."); diff --git a/package-lock.json b/package-lock.json index 3896df9ca5..b33fb05498 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,8 @@ "body-parser": "^1.19.0", "core-js": "^3.12.1", "css-loader": "^5.2.4", + "css-tree": "^1.1.3", + "csstree": "^0.0.3", "eslint": "^8.0.1", "eslint-config-prettier": "^8.3.0", "eslint-config-webpack": "^1.2.5", @@ -5282,6 +5284,28 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/css-what": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", @@ -5330,6 +5354,19 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/csstree": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/csstree/-/csstree-0.0.3.tgz", + "integrity": "sha1-l7aAwMz9TQ/8+AwGEnlpS6nDyMs=", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "string-iterator": "0.0.1" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -11212,6 +11249,12 @@ "node": ">= 12" } }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -13893,6 +13936,15 @@ "node": ">=0.6.19" } }, + "node_modules/string-iterator": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/string-iterator/-/string-iterator-0.0.1.tgz", + "integrity": "sha1-FIG9jYC1oYiGp5BQgCF54anzoYQ=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -19391,6 +19443,24 @@ "nth-check": "^2.0.0" } }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "css-what": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", @@ -19426,6 +19496,15 @@ } } }, + "csstree": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/csstree/-/csstree-0.0.3.tgz", + "integrity": "sha1-l7aAwMz9TQ/8+AwGEnlpS6nDyMs=", + "dev": true, + "requires": { + "string-iterator": "0.0.1" + } + }, "dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -23808,6 +23887,12 @@ "integrity": "sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw==", "dev": true }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -25847,6 +25932,12 @@ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", "dev": true }, + "string-iterator": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/string-iterator/-/string-iterator-0.0.1.tgz", + "integrity": "sha1-FIG9jYC1oYiGp5BQgCF54anzoYQ=", + "dev": true + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", diff --git a/package.json b/package.json index 5c345df35f..3828e3128a 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,8 @@ "body-parser": "^1.19.0", "core-js": "^3.12.1", "css-loader": "^5.2.4", + "css-tree": "^1.1.3", + "csstree": "^0.0.3", "eslint": "^8.0.1", "eslint-config-prettier": "^8.3.0", "eslint-config-webpack": "^1.2.5", diff --git a/test/client/index.test.js b/test/client/index.test.js index 6d98a0937b..ee3c64a947 100644 --- a/test/client/index.test.js +++ b/test/client/index.test.js @@ -206,7 +206,6 @@ describe("index", () => { onSocketMessage.warnings([]); expect(overlay.show).toBeCalled(); - expect(reloadApp).toBeCalled(); }); test("should run onSocketMessage.error", () => { diff --git a/test/e2e/__snapshots__/overlay.test.js.snap.webpack4 b/test/e2e/__snapshots__/overlay.test.js.snap.webpack4 index 3c1eaab350..e73698b92d 100644 --- a/test/e2e/__snapshots__/overlay.test.js.snap.webpack4 +++ b/test/e2e/__snapshots__/overlay.test.js.snap.webpack4 @@ -342,6 +342,69 @@ exports[`overlay should not show initially, then show on an error, then show oth " `; +exports[`overlay should show a warning after invalidation: overlay html 1`] = ` +" +
+ Compiled with problems:

+
+ WARNING

+
Warning from compilation
+

+
+
+ +" +`; + +exports[`overlay should show a warning after invalidation: page html 1`] = ` +" + + + +" +`; + exports[`overlay should show a warning and error for initial compilation and protects against xss: overlay html 1`] = ` "
+
+ Compiled with problems:

+
+ ERROR

+
Error from compilation
+

+
+
+ +" +`; + +exports[`overlay should show an error after invalidation: page html 1`] = ` +" + + + +" +`; + exports[`overlay should show an error for initial compilation: overlay html 1`] = ` "
+
+ Compiled with problems:

+
+ WARNING

+
Warning from compilation
+

+
+
+ +" +`; + +exports[`overlay should show a warning after invalidation: page html 1`] = ` +" + + + +" +`; + exports[`overlay should show a warning and error for initial compilation and protects against xss: overlay html 1`] = ` "
+
+ Compiled with problems:

+
+ ERROR

+
Error from compilation
+

+
+
+ +" +`; + +exports[`overlay should show an error after invalidation: page html 1`] = ` +" + + + +" +`; + exports[`overlay should show an error for initial compilation: overlay html 1`] = ` "
{ + if ( + typeof this.skipCounter !== "undefined" && + this.counter !== this.skipCounter + ) { + this.counter += 1; + + return; + } + compilation.errors.push(new Error(this.message)); } ); @@ -27,8 +38,10 @@ class ErrorPlugin { } class WarningPlugin { - constructor(message) { + constructor(message, skipCounter) { this.message = message || "Warning from compilation"; + this.skipCounter = skipCounter; + this.counter = 0; } // eslint-disable-next-line class-methods-use-this @@ -36,6 +49,15 @@ class WarningPlugin { compiler.hooks.thisCompilation.tap( "warnings-webpack-plugin", (compilation) => { + if ( + typeof this.skipCounter !== "undefined" && + this.counter !== this.skipCounter + ) { + this.counter += 1; + + return; + } + compilation.warnings.push(new Error(this.message)); } ); @@ -892,4 +914,104 @@ describe("overlay", () => { await browser.close(); }); + + it("should show an error after invalidation", async () => { + const compiler = webpack(config); + + new ErrorPlugin("Error from compilation", 1).apply(compiler); + + const devServerOptions = { + port, + }; + const server = new Server(devServerOptions, compiler); + + await server.start(); + + const { page, browser } = await runBrowser(); + + await page.goto(`http://localhost:${port}/main`, { + waitUntil: "networkidle0", + }); + + await new Promise((resolve) => { + server.middleware.invalidate(() => { + resolve(); + }); + }); + + await new Promise((resolve) => { + server.middleware.waitUntilValid(() => { + resolve(); + }); + }); + + await page.waitForSelector("#webpack-dev-server-client-overlay"); + + const pageHtml = await page.evaluate(() => document.body.outerHTML); + const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); + const overlayFrame = await overlayHandle.contentFrame(); + const overlayHtml = await overlayFrame.evaluate( + () => document.body.outerHTML + ); + + expect(prettier.format(pageHtml, { parser: "html" })).toMatchSnapshot( + "page html" + ); + expect(prettier.format(overlayHtml, { parser: "html" })).toMatchSnapshot( + "overlay html" + ); + + await browser.close(); + await server.stop(); + }); + + it("should show a warning after invalidation", async () => { + const compiler = webpack(config); + + new WarningPlugin("Warning from compilation", 1).apply(compiler); + + const devServerOptions = { + port, + }; + const server = new Server(devServerOptions, compiler); + + await server.start(); + + const { page, browser } = await runBrowser(); + + await page.goto(`http://localhost:${port}/main`, { + waitUntil: "networkidle0", + }); + + await new Promise((resolve) => { + server.middleware.invalidate(() => { + resolve(); + }); + }); + + await new Promise((resolve) => { + server.middleware.waitUntilValid(() => { + resolve(); + }); + }); + + await page.waitForSelector("#webpack-dev-server-client-overlay"); + + const pageHtml = await page.evaluate(() => document.body.outerHTML); + const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); + const overlayFrame = await overlayHandle.contentFrame(); + const overlayHtml = await overlayFrame.evaluate( + () => document.body.outerHTML + ); + + expect(prettier.format(pageHtml, { parser: "html" })).toMatchSnapshot( + "page html" + ); + expect(prettier.format(overlayHtml, { parser: "html" })).toMatchSnapshot( + "overlay html" + ); + + await browser.close(); + await server.stop(); + }); });