From 8667b683bb0f94705d950e45cd43a2020ebc6579 Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Mon, 28 Feb 2022 16:23:47 +0300 Subject: [PATCH] support filteredErrorDetailsCount/filteredWarningDetailsCount --- cspell.json | 1 + lib/stats/DefaultStatsFactoryPlugin.js | 104 +++++++++++++----- .../StatsTestCases.basictest.js.snap | 100 +++++++++++++++-- test/statsCases/errors-space-error/loader.js | 7 +- .../errors-space-error/webpack.config.js | 28 ++++- 5 files changed, 195 insertions(+), 45 deletions(-) diff --git a/cspell.json b/cspell.json index 7ac16bc9e3e..01ca07128ab 100644 --- a/cspell.json +++ b/cspell.json @@ -161,6 +161,7 @@ "opencollective", "opensource", "opuuus", + "overlimit", "overridable", "overridables", "parallelism", diff --git a/lib/stats/DefaultStatsFactoryPlugin.js b/lib/stats/DefaultStatsFactoryPlugin.js index 007083d3c3c..9c784461f63 100644 --- a/lib/stats/DefaultStatsFactoryPlugin.js +++ b/lib/stats/DefaultStatsFactoryPlugin.js @@ -811,10 +811,24 @@ const SIMPLE_EXTRACTORS = { }, errors: (object, compilation, context, options, factory) => { const { type, cachedGetErrors } = context; - object.errors = errorsSpaceLimit( - factory.create(`${type}.errors`, cachedGetErrors(compilation), context), + const rawErrors = factory.create( + `${type}.errors`, + cachedGetErrors(compilation), + context + ); + if ( + options.errorDetails === true || + !Number.isFinite(options.errorsSpace) + ) { + object.errors = rawErrors; + return; + } + const [errors, filtered] = errorsSpaceLimit( + rawErrors, options.errorsSpace ); + object.errors = errors; + if (filtered) object.filteredErrorDetailsCount = filtered; }, errorsCount: (object, compilation, { cachedGetErrors }) => { object.errorsCount = countWithChildren(compilation, c => @@ -823,14 +837,24 @@ const SIMPLE_EXTRACTORS = { }, warnings: (object, compilation, context, options, factory) => { const { type, cachedGetWarnings } = context; - object.warnings = errorsSpaceLimit( - factory.create( - `${type}.warnings`, - cachedGetWarnings(compilation), - context - ), + const rawWarnings = factory.create( + `${type}.warnings`, + cachedGetWarnings(compilation), + context + ); + if ( + options.errorDetails === true || + !Number.isFinite(options.warningsSpace) + ) { + object.warnings = rawWarnings; + return; + } + const [warnings, filtered] = errorsSpaceLimit( + rawWarnings, options.warningsSpace ); + object.warnings = warnings; + if (filtered) object.filteredWarningDetailsCount = filtered; }, warningsCount: ( object, @@ -864,16 +888,22 @@ const SIMPLE_EXTRACTORS = { if (errorDetails === "auto") { if (warnings) { const warnings = cachedGetWarnings(compilation); - object.filteredWarningDetailsCount = warnings - .map(e => typeof e !== "string" && e.details) - .filter(Boolean).length; + const filtered = object.filteredWarningDetailsCount || 0; + object.filteredWarningDetailsCount = + filtered + + warnings + .map(e => typeof e !== "string" && e.details) + .filter(Boolean).length; } if (errors) { const errors = cachedGetErrors(compilation); if (errors.length >= 3) { - object.filteredErrorDetailsCount = errors - .map(e => typeof e !== "string" && e.details) - .filter(Boolean).length; + const filtered = object.filteredErrorDetailsCount || 0; + object.filteredErrorDetailsCount = + filtered + + errors + .map(e => typeof e !== "string" && e.details) + .filter(Boolean).length; } } } @@ -1782,16 +1812,18 @@ const spaceLimited = ( }; const errorsSpaceLimit = (errors, max) => { - if (!Number.isFinite(max)) return errors; + let filtered = 0; // Can not fit into limit // print only messages - if (errors.length > max) - return errors.map(error => { - if (error.details === undefined) return error; - const { details, ...rest } = error; - return { details: "", ...rest }; - }); - + if (errors.length >= max) + return [ + errors.map(error => { + if (error.details === undefined) return error; + filtered++; + return { ...error, details: "" }; + }), + filtered + ]; let fullLength = errors.length; let result = errors; @@ -1802,23 +1834,35 @@ const errorsSpaceLimit = (errors, max) => { const len = splitted.length; fullLength += len; if (fullLength > max) { - result = errors.slice(0, i); - const { details, ...rest } = errors[i++]; + result = i > 0 ? errors.slice(0, i) : []; + const overlimit = fullLength - max; result.push({ - details: splitted.slice(0, len - (fullLength - max)).join("\n"), - ...rest + ...errors[i++], + details: `${splitted + .slice(0, len - overlimit) + .join("\n")}\n+${overlimit} hidden line${ + overlimit === 1 ? "" : "s" + }` }); + filtered = errors.length - i; + for (; i < errors.length; i++) { + if (errors[i].details === undefined) result.push(errors[i]); + result.push({ ...errors[i], details: "" }); + } + break; + } else if (fullLength === max) { + result = errors.slice(0, ++i); + filtered = errors.length - i; for (; i < errors.length; i++) { - const { details, ...rest } = errors[i]; - if (details === undefined) result.push(errors[i]); - result.push({ details: "", ...rest }); + if (errors[i].details === undefined) result.push(errors[i]); + result.push({ ...errors[i], details: "" }); } break; } } } - return result; + return [result, filtered]; }; const assetGroup = (children, assets) => { diff --git a/test/__snapshots__/StatsTestCases.basictest.js.snap b/test/__snapshots__/StatsTestCases.basictest.js.snap index 7068df1fa7d..dd73b655c10 100644 --- a/test/__snapshots__/StatsTestCases.basictest.js.snap +++ b/test/__snapshots__/StatsTestCases.basictest.js.snap @@ -989,34 +989,110 @@ webpack x.x.x compiled successfully in X ms" exports[`StatsTestCases should print correct stats for errors-space-error 1`] = ` "assets by status 84 bytes [cached] 1 asset -./loader.js!./index.js 1 bytes [built] [code generated] [1 error] +./loader.js!./index.js 1 bytes [built] [code generated] [2 errors] ERROR in ./index.js (./loader.js!./index.js) Module Error (from ./loader.js): -loader error -Error: loader error +loader error1 -webpack x.x.x compiled with 1 error in X ms +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +2 errors have detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms assets by status 84 bytes [cached] 1 asset -./loader.js!./index.js 1 bytes [built] [code generated] [1 error] +./loader.js!./index.js 1 bytes [built] [code generated] [2 errors] ERROR in ./index.js (./loader.js!./index.js) Module Error (from ./loader.js): -loader error +loader error1 -webpack x.x.x compiled with 1 error in X ms +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +2 errors have detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms assets by status 84 bytes [cached] 1 asset -./loader.js!./index.js 1 bytes [built] [code generated] [1 error] +./loader.js!./index.js 1 bytes [built] [code generated] [2 errors] ERROR in ./index.js (./loader.js!./index.js) Module Error (from ./loader.js): -loader error -Error: loader error - at Object..module.exports (Xdir/errors-space-error/loader.js:4:17) +loader error1 +stack1 ++2 hidden lines -webpack x.x.x compiled with 1 error in X ms" +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +1 error has detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status 84 bytes [cached] 1 asset +./loader.js!./index.js 1 bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 +stack1 +stack2 ++1 hidden line + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +1 error has detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status 84 bytes [cached] 1 asset +./loader.js!./index.js 1 bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 +stack1 +stack2 +stack3 + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +1 error has detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status 84 bytes [cached] 1 asset +./loader.js!./index.js 1 bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 +stack1 +stack2 +stack3 + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 +stack1 +stack2 + +webpack x.x.x compiled with 2 errors in X ms" `; exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = ` diff --git a/test/statsCases/errors-space-error/loader.js b/test/statsCases/errors-space-error/loader.js index 6b5d40ed604..eb535791a3c 100644 --- a/test/statsCases/errors-space-error/loader.js +++ b/test/statsCases/errors-space-error/loader.js @@ -1,6 +1,11 @@ "use strict"; module.exports = function (content) { - this.emitError(new Error("loader error")); + let error = new Error("loader error1"); + error.stack = "stack1\nstack2\nstack3"; + this.emitError(error); + error = new Error("loader error2"); + error.stack = "stack1\nstack2"; + this.emitError(error); return content; } diff --git a/test/statsCases/errors-space-error/webpack.config.js b/test/statsCases/errors-space-error/webpack.config.js index fc0538e1835..4ea95efae2e 100644 --- a/test/statsCases/errors-space-error/webpack.config.js +++ b/test/statsCases/errors-space-error/webpack.config.js @@ -4,7 +4,7 @@ module.exports = [ entry: "./loader!./index.js", mode: "production", stats: { - errorsSpace: 2, + errorsSpace: 0, errors: true } }, @@ -12,7 +12,31 @@ module.exports = [ entry: "./loader!./index.js", mode: "production", stats: { - errorsSpace: 0, + errorsSpace: 2, // 2 errors (2 errors without details) + errors: true + } + }, + { + entry: "./loader!./index.js", + mode: "production", + stats: { + errorsSpace: 3, // 2 errors (2 errors without details) + errors: true + } + }, + { + entry: "./loader!./index.js", + mode: "production", + stats: { + errorsSpace: 4, // 2 errors + 2 lines (2 errors, one with partial details) + errors: true + } + }, + { + entry: "./loader!./index.js", + mode: "production", + stats: { + errorsSpace: 5, // 2 errors + 3 lines (2 errors, one full details) errors: true } },