From 5604cb0401396da18c5891d1c4e4e6046cfbcdff Mon Sep 17 00:00:00 2001 From: srushti Date: Mon, 10 Nov 2025 12:22:03 +0530 Subject: [PATCH 01/12] Fix: prevent TypeError when assets or modules are undefined in analyzer --- src/analyzer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/analyzer.js b/src/analyzer.js index ddcbef7f..d684928f 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -52,7 +52,7 @@ function getViewerData(bundleStats, bundleDir, opts) { } // Picking only `*.js, *.cjs or *.mjs` assets from bundle that has non-empty `chunks` array - bundleStats.assets = bundleStats.assets.filter(asset => { + bundleStats.assets = (bundleStats.assets || []).filter(asset => { // Filter out non 'asset' type asset if type is provided (Webpack 5 add a type to indicate asset types) if (asset.type && asset.type !== 'asset') { return false; @@ -116,7 +116,7 @@ function getViewerData(bundleStats, bundleDir, opts) { } // Picking modules from current bundle script - let assetModules = modules.filter(statModule => assetHasModule(statAsset, statModule)); + let assetModules = (modules || []).filter(statModule => assetHasModule(statAsset, statModule)); // Adding parsed sources if (parsedModules) { @@ -140,7 +140,7 @@ function getViewerData(bundleStats, bundleDir, opts) { unparsedEntryModules[0].parsedSrc = assetSources.runtimeSrc; } else { // If there are multiple entry points we move all of them under synthetic concatenated module. - assetModules = assetModules.filter(mod => !unparsedEntryModules.includes(mod)); + assetModules = (assetModules || []).filter(mod => !unparsedEntryModules.includes(mod)); assetModules.unshift({ identifier: './entry modules', name: './entry modules', From 2b334dd5dbf3e36d9ceb9b3724db552247be2f0e Mon Sep 17 00:00:00 2001 From: srushti Date: Mon, 10 Nov 2025 22:23:08 +0530 Subject: [PATCH 02/12] Changelog: add entry for TypeError fix in analyzer.js (#679) --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7201303f..7beb179f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ ## UNRELEASED +* **Bug Fix** + * Prevent `TypeError` when `assets` or `modules` are undefined in `analyzer.js` + ([#679](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/679) by [@Srushti-33](https://github.com/Srushti-33)) + + * **Breaking Change** * Remove explicit support for Node versions below 16.20.2 ([#650](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/650) by [@valscion](https://github.com/valscion)) * **NOTE:** `webpack-bundle-analyzer` might still support older Node versions but they are no longer tested against. From 8f1d35c0d63524fd282efb03243baba6e675c7a2 Mon Sep 17 00:00:00 2001 From: Srushti Date: Mon, 10 Nov 2025 22:50:41 +0530 Subject: [PATCH 03/12] git commit --amend --author="Srushti "Add real-world test scenarios for incomplete stats --- test/real-world-stats.test.js | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test/real-world-stats.test.js diff --git a/test/real-world-stats.test.js b/test/real-world-stats.test.js new file mode 100644 index 00000000..5668bc01 --- /dev/null +++ b/test/real-world-stats.test.js @@ -0,0 +1,55 @@ +const {expect} = require('chai'); +const analyzer = require('../lib/analyzer'); + +describe('Real-world incomplete stats scenarios', function() { + it('should handle stats from minimal webpack config', function() { + const realWorldStats = { + version: "5.0.0", + hash: "abc123def456", + publicPath: "/dist/", + outputPath: "/project/dist", + chunks: [ + { + id: 0, + names: ["main"], + files: ["main.js"], + hash: "abc123", + size: 1024 + } + ], + // Real-world scenario: assets array missing (common in minimal configs) + // Real-world scenario: modules array missing (some webpack versions) + errors: [], + warnings: [], + entrypoints: { + main: { + chunks: [0], + assets: ["main.js"] + } + } + }; + + expect(() => { + const result = analyzer.getViewerData(realWorldStats); + expect(result).to.be.an('array'); + }).not.to.throw(); + }); + + it('should handle stats with only essential webpack 5 fields', function() { + const webpack5MinimalStats = { + version: "5.0.0", + hash: "webpack5minimal", + publicPath: "/", + outputPath: "/build", + chunks: [], + entrypoints: {}, + // Common real-world scenario: missing assets and modules + errors: [], + warnings: [], + namedChunkGroups: {} + }; + + const result = analyzer.getViewerData(webpack5MinimalStats); + expect(result).to.be.an('array').that.is.empty; + }); +}); \ No newline at end of file From 999f9b12b158552324344f18c59fa75c46a54cae Mon Sep 17 00:00:00 2001 From: srushti Date: Thu, 13 Nov 2025 01:39:37 +0530 Subject: [PATCH 04/12] Address review feedback: remove standalone test and add to existing analyzer.js --- test/analyzer.js | 5 ++++ test/real-world-stats.test.js | 55 ----------------------------------- 2 files changed, 5 insertions(+), 55 deletions(-) delete mode 100644 test/real-world-stats.test.js diff --git a/test/analyzer.js b/test/analyzer.js index 7d8e5ca3..1e3dc857 100644 --- a/test/analyzer.js +++ b/test/analyzer.js @@ -94,6 +94,11 @@ describe('Analyzer', function () { ); }); + it('should handle stats with minimal configuration', async function () { + generateReportFrom('with-invalid-dynamic-require.json'); + await expectValidReport(); + }); + it.skip("should not filter out modules that we couldn't find during parsing", async function () { generateReportFrom('with-missing-parsed-module/stats.json'); const chartData = await getChartData(); diff --git a/test/real-world-stats.test.js b/test/real-world-stats.test.js deleted file mode 100644 index 5668bc01..00000000 --- a/test/real-world-stats.test.js +++ /dev/null @@ -1,55 +0,0 @@ -const {expect} = require('chai'); -const analyzer = require('../lib/analyzer'); - -describe('Real-world incomplete stats scenarios', function() { - it('should handle stats from minimal webpack config', function() { - const realWorldStats = { - version: "5.0.0", - hash: "abc123def456", - publicPath: "/dist/", - outputPath: "/project/dist", - chunks: [ - { - id: 0, - names: ["main"], - files: ["main.js"], - hash: "abc123", - size: 1024 - } - ], - // Real-world scenario: assets array missing (common in minimal configs) - // Real-world scenario: modules array missing (some webpack versions) - errors: [], - warnings: [], - entrypoints: { - main: { - chunks: [0], - assets: ["main.js"] - } - } - }; - - expect(() => { - const result = analyzer.getViewerData(realWorldStats); - expect(result).to.be.an('array'); - }).not.to.throw(); - }); - - it('should handle stats with only essential webpack 5 fields', function() { - const webpack5MinimalStats = { - version: "5.0.0", - hash: "webpack5minimal", - publicPath: "/", - outputPath: "/build", - chunks: [], - entrypoints: {}, - // Common real-world scenario: missing assets and modules - errors: [], - warnings: [], - namedChunkGroups: {} - }; - - const result = analyzer.getViewerData(webpack5MinimalStats); - expect(result).to.be.an('array').that.is.empty; - }); -}); \ No newline at end of file From c746f511fcd32115f9d19398f962111c4f3db5a0 Mon Sep 17 00:00:00 2001 From: srushti Date: Thu, 13 Nov 2025 21:00:28 +0530 Subject: [PATCH 05/12] Add minimal stats generated with webpack-cli --stats=minimal --- test/stats/minimal-stats/expected-chart-data.json | 1 + test/stats/minimal-stats/stats.json | 1 + 2 files changed, 2 insertions(+) create mode 100644 test/stats/minimal-stats/expected-chart-data.json create mode 100644 test/stats/minimal-stats/stats.json diff --git a/test/stats/minimal-stats/expected-chart-data.json b/test/stats/minimal-stats/expected-chart-data.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/test/stats/minimal-stats/expected-chart-data.json @@ -0,0 +1 @@ +[] diff --git a/test/stats/minimal-stats/stats.json b/test/stats/minimal-stats/stats.json new file mode 100644 index 00000000..d068d805 --- /dev/null +++ b/test/stats/minimal-stats/stats.json @@ -0,0 +1 @@ +{"logging":{"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./simple-entry.js":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/viewer.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/store.js":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/ModulesTreemap.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/utils.js":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/localStorage.js":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Tooltip.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Treemap.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Sidebar.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/CheckboxList.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Checkbox.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Dropdown.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Switcher.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/ModulesList.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Search.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/ContextMenu.jsx":{"entries":[],"filteredEntries":3,"debug":false},"webpack.DefinePlugin":{"entries":[],"filteredEntries":137,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/SwitcherItem.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Button.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/ModuleItem.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/Icon.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/CheckboxListItem.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/components/ContextMenuItem.jsx":{"entries":[],"filteredEntries":3,"debug":false},"./node_modules/babel-loader/lib/index.js babel-loader ./node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0]!./client/lib/PureComponent.jsx":{"entries":[],"filteredEntries":3,"debug":false},"webpack.Compiler":{"entries":[],"filteredEntries":7,"debug":false},"webpack.Compilation":{"entries":[],"filteredEntries":27,"debug":false},"webpack.FlagDependencyExportsPlugin":{"entries":[],"filteredEntries":4,"debug":false},"webpack.InnerGraphPlugin":{"entries":[],"filteredEntries":1,"debug":false},"webpack.SideEffectsFlagPlugin":{"entries":[],"filteredEntries":1,"debug":false},"webpack.FlagDependencyUsagePlugin":{"entries":[],"filteredEntries":2,"debug":false},"webpack.buildChunkGraph":{"entries":[],"filteredEntries":9,"debug":false},"webpack.SplitChunksPlugin":{"entries":[],"filteredEntries":4,"debug":false},"webpack.ModuleConcatenationPlugin":{"entries":[],"filteredEntries":8,"debug":false},"webpack.FileSystemInfo":{"entries":[],"filteredEntries":11,"debug":false},"webpack.Watching":{"entries":[],"filteredEntries":1,"debug":false}},"version":"5.102.1","time":4182,"assetsByChunkName":{"main":["viewer.js"]},"filteredAssets":1,"filteredModules":172,"filteredErrorDetailsCount":0,"errors":[],"errorsCount":0,"filteredWarningDetailsCount":0,"warnings":[],"warningsCount":0} From 8a11329caf30cf257d41e9d925ab135888326621 Mon Sep 17 00:00:00 2001 From: srushti Date: Thu, 13 Nov 2025 21:59:53 +0530 Subject: [PATCH 06/12] Fix: use minimal-stats/stats.json in test --- test/analyzer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/analyzer.js b/test/analyzer.js index 1e3dc857..a3869bf5 100644 --- a/test/analyzer.js +++ b/test/analyzer.js @@ -95,7 +95,7 @@ describe('Analyzer', function () { }); it('should handle stats with minimal configuration', async function () { - generateReportFrom('with-invalid-dynamic-require.json'); + generateReportFrom('minimal-stats/stats.json'); await expectValidReport(); }); From 89c1a94dcca0870dc290537acb852e231c868e6e Mon Sep 17 00:00:00 2001 From: srushti Date: Fri, 14 Nov 2025 07:39:58 +0530 Subject: [PATCH 07/12] fix: handle undefined chunks and modules in getBundleModules --- ...214029+Srushti-33@users.noreply.github.com | 324 ++++++++++++++++++ h origin fix-stats-object-error-v2q | 27 ++ test-fix.js | 24 ++ test-stats.json | 20 ++ 4 files changed, 395 insertions(+) create mode 100644 er.email 210214029+Srushti-33@users.noreply.github.com create mode 100644 h origin fix-stats-object-error-v2q create mode 100644 test-fix.js create mode 100644 test-stats.json diff --git a/er.email 210214029+Srushti-33@users.noreply.github.com b/er.email 210214029+Srushti-33@users.noreply.github.com new file mode 100644 index 00000000..74570f66 --- /dev/null +++ b/er.email 210214029+Srushti-33@users.noreply.github.com @@ -0,0 +1,324 @@ + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + ESC-j * Forward one file line (or _N file lines). + ESC-k * Backward one file line (or _N file lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + ESC-b * Backward one window, but don't stop at beginning-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). + ESC-} ^RightArrow Right to last column displayed. + ESC-{ ^LeftArrow Left to first column. + F Forward forever; like "tail -f". + ESC-F Like F but stop when search pattern is found. + r ^R ^L Repaint screen. + R Repaint screen, discarding buffered input. + --------------------------------------------------- + Default "window" is the screen height. + Default "half-window" is half of the screen height. + --------------------------------------------------------------------------- + + SSEEAARRCCHHIINNGG + + /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. + ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. + n * Repeat previous search (for _N-th occurrence). + N * Repeat previous search in reverse direction. + ESC-n * Repeat previous search, spanning files. + ESC-N * Repeat previous search, reverse dir. & spanning files. + ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. + ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. + ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. + ESC-u Undo (toggle) search highlighting. + ESC-U Clear search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines. + --------------------------------------------------- + Search is case-sensitive unless changed with -i or -I. + A search pattern may begin with one or more of: + ^N or ! Search for NON-matching lines. + ^E or * Search multiple files (pass thru END OF FILE). + ^F or @ Start search at FIRST file (for /) or last file (for ?). + ^K Highlight matches, but don't move (KEEP position). + ^R Don't use REGULAR EXPRESSIONS. + ^S _n Search for match in _n-th parenthesized subpattern. + ^W WRAP search if no match found. + ^L Enter next character literally into pattern. + --------------------------------------------------------------------------- + + JJUUMMPPIINNGG + + g < ESC-< * Go to first line in file (or line _N). + G > ESC-> * Go to last line in file (or line _N). + p % * Go to beginning of file (or _N percent into file). + t * Go to the (_N-th) next tag. + T * Go to the (_N-th) previous tag. + { ( [ * Find close bracket } ) ]. + } ) ] * Find open bracket { ( [. + ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. + ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. + --------------------------------------------------- + Each "find close bracket" command goes forward to the close bracket + matching the (_N-th) open bracket in the top line. + Each "find open bracket" command goes backward to the open bracket + matching the (_N-th) close bracket in the bottom line. + + m_<_l_e_t_t_e_r_> Mark the current top line with . + M_<_l_e_t_t_e_r_> Mark the current bottom line with . + '_<_l_e_t_t_e_r_> Go to a previously marked position. + '' Go to the previous position. + ^X^X Same as '. + ESC-m_<_l_e_t_t_e_r_> Clear a mark. + --------------------------------------------------- + A mark is any upper-case or lower-case letter. + Certain marks are predefined: + ^ means beginning of the file + $ means end of the file + --------------------------------------------------------------------------- + + CCHHAANNGGIINNGG FFIILLEESS + + :e [_f_i_l_e] Examine a new file. + ^X^V Same as :e. + :n * Examine the (_N-th) next file from the command line. + :p * Examine the (_N-th) previous file from the command line. + :x * Examine the first (or _N-th) file from the command line. + ^O^O Open the currently selected OSC8 hyperlink. + :d Delete the current file from the command line list. + = ^G :f Print current file name. + --------------------------------------------------------------------------- + + MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS + + -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. + --_<_n_a_m_e_> Toggle a command line option, by name. + __<_f_l_a_g_> Display the setting of a command line option. + ___<_n_a_m_e_> Display the setting of an option, by name. + +_c_m_d Execute the less cmd each time a new file is examined. + + !_c_o_m_m_a_n_d Execute the shell command with $SHELL. + #_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt. + |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. + s _f_i_l_e Save input to a file. + v Edit the current file with $VISUAL or $EDITOR. + V Print version number of "less". + --------------------------------------------------------------------------- + + OOPPTTIIOONNSS + + Most options may be changed either on the command line, + or from within less by using the - or -- command. + Options may be given in one of two forms: either a single + character preceded by a -, or a name preceded by --. + + -? ........ --help + Display help (from command line). + -a ........ --search-skip-screen + Search skips current screen. + -A ........ --SEARCH-SKIP-SCREEN + Search starts just after target line. + -b [_N] .... --buffers=[_N] + Number of buffers. + -B ........ --auto-buffers + Don't automatically allocate buffers for pipes. + -c ........ --clear-screen + Repaint by clearing rather than scrolling. + -d ........ --dumb + Dumb terminal. + -D xx_c_o_l_o_r . --color=xx_c_o_l_o_r + Set screen colors. + -e -E .... --quit-at-eof --QUIT-AT-EOF + Quit at end of file. + -f ........ --force + Force open non-regular files. + -F ........ --quit-if-one-screen + Quit if entire file fits on first screen. + -g ........ --hilite-search + Highlight only last match for searches. + -G ........ --HILITE-SEARCH + Don't highlight any matches for searches. + -h [_N] .... --max-back-scroll=[_N] + Backward scroll limit. + -i ........ --ignore-case + Ignore case in searches that do not contain uppercase. + -I ........ --IGNORE-CASE + Ignore case in all searches. + -j [_N] .... --jump-target=[_N] + Screen position of target lines. + -J ........ --status-column + Display a status column at left edge of screen. + -k _f_i_l_e ... --lesskey-file=_f_i_l_e + Use a compiled lesskey file. + -K ........ --quit-on-intr + Exit less in response to ctrl-C. + -L ........ --no-lessopen + Ignore the LESSOPEN environment variable. + -m -M .... --long-prompt --LONG-PROMPT + Set prompt style. + -n ......... --line-numbers + Suppress line numbers in prompts and messages. + -N ......... --LINE-NUMBERS + Display line number at start of each line. + -o [_f_i_l_e] .. --log-file=[_f_i_l_e] + Copy to log file (standard input only). + -O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e] + Copy to log file (unconditionally overwrite). + -p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n] + Start at pattern (from command line). + -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] + Define new prompt. + -q -Q .... --quiet --QUIET --silent --SILENT + Quiet the terminal bell. + -r -R .... --raw-control-chars --RAW-CONTROL-CHARS + Output "raw" control characters. + -s ........ --squeeze-blank-lines + Squeeze multiple blank lines. + -S ........ --chop-long-lines + Chop (truncate) long lines rather than wrapping. + -t _t_a_g .... --tag=[_t_a_g] + Find a tag. + -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] + Use an alternate tags file. + -u -U .... --underline-special --UNDERLINE-SPECIAL + Change handling of backspaces, tabs and carriage returns. + -V ........ --version + Display the version number of "less". + -w ........ --hilite-unread + Highlight first new line after forward-screen. + -W ........ --HILITE-UNREAD + Highlight first new line after any forward movement. + -x [_N[,...]] --tabs=[_N[,...]] + Set tab stops. + -X ........ --no-init + Don't use termcap init/deinit strings. + -y [_N] .... --max-forw-scroll=[_N] + Forward scroll limit. + -z [_N] .... --window=[_N] + Set size of window. + -" [_c[_c]] . --quotes=[_c[_c]] + Set shell quote characters. + -~ ........ --tilde + Don't display tildes after end of file. + -# [_N] .... --shift=[_N] + Set horizontal scroll amount (0 = one half screen width). + + --exit-follow-on-close + Exit F command on a pipe when writer closes pipe. + --file-size + Automatically determine the size of the input file. + --follow-name + The F command changes files if the input file is renamed. + --form-feed + Stop scrolling when a form feed character is reached. + --header=[_L[,_C[,_N]]] + Use _L lines (starting at line _N) and _C columns as headers. + --incsearch + Search file as each pattern character is typed in. + --intr=[_C] + Use _C instead of ^X to interrupt a read. + --lesskey-context=_t_e_x_t + Use lesskey source file contents. + --lesskey-src=_f_i_l_e + Use a lesskey source file. + --line-num-width=[_N] + Set the width of the -N line number field to _N characters. + --match-shift=[_N] + Show at least _N characters to the left of a search match. + --modelines=[_N] + Read _N lines from the input file and look for vim modelines. + --mouse + Enable mouse input. + --no-edit-warn + Don't warn when using v command on a file opened via LESSOPEN. + --no-keypad + Don't send termcap keypad init/deinit strings. + --no-histdups + Remove duplicates from command history. + --no-number-headers + Don't give line numbers to header lines. + --no-paste + Ignore pasted input. + --no-search-header-lines + Searches do not include header lines. + --no-search-header-columns + Searches do not include header columns. + --no-search-headers + Searches do not include header lines or columns. + --no-vbell + Disable the terminal's visual bell. + --redraw-on-quit + Redraw final screen when quitting. + --rscroll=[_C] + Set the character used to mark truncated lines. + --save-marks + Retain marks across invocations of less. + --search-options=[EFKNRW-] + Set default options for every search. + --show-preproc-errors + Display a message if preprocessor exits with an error status. + --proc-backspace + Process backspaces for bold/underline. + --PROC-BACKSPACE + Treat backspaces as control characters. + --proc-return + Delete carriage returns before newline. + --PROC-RETURN + Treat carriage returns as control characters. + --proc-tab + Expand tabs to spaces. + --PROC-TAB + Treat tabs as control characters. + --status-col-width=[_N] + Set the width of the -J status column to _N characters. + --status-line + Highlight or color the entire line containing a mark. + --use-backslash + Subsequent options use backslash as escape char. + --use-color + Enables colored text. + --wheel-lines=[_N] + Each click of the mouse wheel moves _N lines. + --wordwrap + Wrap lines at spaces. + + + --------------------------------------------------------------------------- + + LLIINNEE EEDDIITTIINNGG + + These keys can be used to edit text being entered + on the "command line" at the bottom of the screen. + + RightArrow ..................... ESC-l ... Move cursor right one character. + LeftArrow ...................... ESC-h ... Move cursor left one character. + ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. + ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. + HOME ........................... ESC-0 ... Move cursor to start of line. + END ............................ ESC-$ ... Move cursor to end of line. + BACKSPACE ................................ Delete char to left of cursor. + DELETE ......................... ESC-x ... Delete char under cursor. + ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. + ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. + ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. + UpArrow ........................ ESC-k ... Retrieve previous command line. + DownArrow ...................... ESC-j ... Retrieve next command line. + TAB ...................................... Complete filename & cycle. + SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. + ctrl-L ................................... Complete filename, list all. diff --git a/h origin fix-stats-object-error-v2q b/h origin fix-stats-object-error-v2q new file mode 100644 index 00000000..ce823849 --- /dev/null +++ b/h origin fix-stats-object-error-v2q @@ -0,0 +1,27 @@ + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + ESC-j * Forward one file line (or _N file lines). + ESC-k * Backward one file line (or _N file lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + ESC-b * Backward one window, but don't stop at beginning-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). diff --git a/test-fix.js b/test-fix.js new file mode 100644 index 00000000..cd3ab752 --- /dev/null +++ b/test-fix.js @@ -0,0 +1,24 @@ +const analyzer = require('./lib/analyzer'); + +// Test with minimal stats (missing assets array) +const testStats = { + version: "5.0.0", + hash: "test123", + chunks: [], + // assets: undefined, // This is missing - should trigger the original bug + errors: [], + warnings: [], + entrypoints: {}, + namedChunkGroups: {}, + outputPath: "/tmp", + publicPath: "/" +}; + +console.log('๐Ÿงช Testing fix...'); +try { + const result = analyzer.getViewerData(testStats); + console.log('โœ… SUCCESS! Fix works - no more TypeError'); + console.log('Result has', result.length, 'assets'); +} catch (error) { + console.error('โŒ FAILED:', error.message); +} \ No newline at end of file diff --git a/test-stats.json b/test-stats.json new file mode 100644 index 00000000..3f5287e0 --- /dev/null +++ b/test-stats.json @@ -0,0 +1,20 @@ +{ + "chunks": [ + { + "id": 1, + "files": ["main.js"], + "modules": [], + "sizes": {} + } + ], + "entrypoints": {}, + "errors": [], + "errorsCount": 0, + "hash": "abc", + "namedChunkGroups": {}, + "outputPath": "/dist", + "publicPath": "/", + "version": "5.x", + "warnings": [], + "warningsCount": 0 +} From 4ddb2d4eb2c043f07e6fbe207ba7f1e06192b27e Mon Sep 17 00:00:00 2001 From: srushti Date: Fri, 14 Nov 2025 07:41:33 +0530 Subject: [PATCH 08/12] chore: remove unintended files --- ...214029+Srushti-33@users.noreply.github.com | 324 ------------------ h origin fix-stats-object-error-v2q | 27 -- test-fix.js | 24 -- test-stats.json | 20 -- 4 files changed, 395 deletions(-) delete mode 100644 er.email 210214029+Srushti-33@users.noreply.github.com delete mode 100644 h origin fix-stats-object-error-v2q delete mode 100644 test-fix.js delete mode 100644 test-stats.json diff --git a/er.email 210214029+Srushti-33@users.noreply.github.com b/er.email 210214029+Srushti-33@users.noreply.github.com deleted file mode 100644 index 74570f66..00000000 --- a/er.email 210214029+Srushti-33@users.noreply.github.com +++ /dev/null @@ -1,324 +0,0 @@ - - SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS - - Commands marked with * may be preceded by a number, _N. - Notes in parentheses indicate the behavior if _N is given. - A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. - - h H Display this help. - q :q Q :Q ZZ Exit. - --------------------------------------------------------------------------- - - MMOOVVIINNGG - - e ^E j ^N CR * Forward one line (or _N lines). - y ^Y k ^K ^P * Backward one line (or _N lines). - ESC-j * Forward one file line (or _N file lines). - ESC-k * Backward one file line (or _N file lines). - f ^F ^V SPACE * Forward one window (or _N lines). - b ^B ESC-v * Backward one window (or _N lines). - z * Forward one window (and set window to _N). - w * Backward one window (and set window to _N). - ESC-SPACE * Forward one window, but don't stop at end-of-file. - ESC-b * Backward one window, but don't stop at beginning-of-file. - d ^D * Forward one half-window (and set half-window to _N). - u ^U * Backward one half-window (and set half-window to _N). - ESC-) RightArrow * Right one half screen width (or _N positions). - ESC-( LeftArrow * Left one half screen width (or _N positions). - ESC-} ^RightArrow Right to last column displayed. - ESC-{ ^LeftArrow Left to first column. - F Forward forever; like "tail -f". - ESC-F Like F but stop when search pattern is found. - r ^R ^L Repaint screen. - R Repaint screen, discarding buffered input. - --------------------------------------------------- - Default "window" is the screen height. - Default "half-window" is half of the screen height. - --------------------------------------------------------------------------- - - SSEEAARRCCHHIINNGG - - /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. - ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. - n * Repeat previous search (for _N-th occurrence). - N * Repeat previous search in reverse direction. - ESC-n * Repeat previous search, spanning files. - ESC-N * Repeat previous search, reverse dir. & spanning files. - ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. - ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. - ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. - ESC-u Undo (toggle) search highlighting. - ESC-U Clear search highlighting. - &_p_a_t_t_e_r_n * Display only matching lines. - --------------------------------------------------- - Search is case-sensitive unless changed with -i or -I. - A search pattern may begin with one or more of: - ^N or ! Search for NON-matching lines. - ^E or * Search multiple files (pass thru END OF FILE). - ^F or @ Start search at FIRST file (for /) or last file (for ?). - ^K Highlight matches, but don't move (KEEP position). - ^R Don't use REGULAR EXPRESSIONS. - ^S _n Search for match in _n-th parenthesized subpattern. - ^W WRAP search if no match found. - ^L Enter next character literally into pattern. - --------------------------------------------------------------------------- - - JJUUMMPPIINNGG - - g < ESC-< * Go to first line in file (or line _N). - G > ESC-> * Go to last line in file (or line _N). - p % * Go to beginning of file (or _N percent into file). - t * Go to the (_N-th) next tag. - T * Go to the (_N-th) previous tag. - { ( [ * Find close bracket } ) ]. - } ) ] * Find open bracket { ( [. - ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. - ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. - --------------------------------------------------- - Each "find close bracket" command goes forward to the close bracket - matching the (_N-th) open bracket in the top line. - Each "find open bracket" command goes backward to the open bracket - matching the (_N-th) close bracket in the bottom line. - - m_<_l_e_t_t_e_r_> Mark the current top line with . - M_<_l_e_t_t_e_r_> Mark the current bottom line with . - '_<_l_e_t_t_e_r_> Go to a previously marked position. - '' Go to the previous position. - ^X^X Same as '. - ESC-m_<_l_e_t_t_e_r_> Clear a mark. - --------------------------------------------------- - A mark is any upper-case or lower-case letter. - Certain marks are predefined: - ^ means beginning of the file - $ means end of the file - --------------------------------------------------------------------------- - - CCHHAANNGGIINNGG FFIILLEESS - - :e [_f_i_l_e] Examine a new file. - ^X^V Same as :e. - :n * Examine the (_N-th) next file from the command line. - :p * Examine the (_N-th) previous file from the command line. - :x * Examine the first (or _N-th) file from the command line. - ^O^O Open the currently selected OSC8 hyperlink. - :d Delete the current file from the command line list. - = ^G :f Print current file name. - --------------------------------------------------------------------------- - - MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS - - -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. - --_<_n_a_m_e_> Toggle a command line option, by name. - __<_f_l_a_g_> Display the setting of a command line option. - ___<_n_a_m_e_> Display the setting of an option, by name. - +_c_m_d Execute the less cmd each time a new file is examined. - - !_c_o_m_m_a_n_d Execute the shell command with $SHELL. - #_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt. - |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. - s _f_i_l_e Save input to a file. - v Edit the current file with $VISUAL or $EDITOR. - V Print version number of "less". - --------------------------------------------------------------------------- - - OOPPTTIIOONNSS - - Most options may be changed either on the command line, - or from within less by using the - or -- command. - Options may be given in one of two forms: either a single - character preceded by a -, or a name preceded by --. - - -? ........ --help - Display help (from command line). - -a ........ --search-skip-screen - Search skips current screen. - -A ........ --SEARCH-SKIP-SCREEN - Search starts just after target line. - -b [_N] .... --buffers=[_N] - Number of buffers. - -B ........ --auto-buffers - Don't automatically allocate buffers for pipes. - -c ........ --clear-screen - Repaint by clearing rather than scrolling. - -d ........ --dumb - Dumb terminal. - -D xx_c_o_l_o_r . --color=xx_c_o_l_o_r - Set screen colors. - -e -E .... --quit-at-eof --QUIT-AT-EOF - Quit at end of file. - -f ........ --force - Force open non-regular files. - -F ........ --quit-if-one-screen - Quit if entire file fits on first screen. - -g ........ --hilite-search - Highlight only last match for searches. - -G ........ --HILITE-SEARCH - Don't highlight any matches for searches. - -h [_N] .... --max-back-scroll=[_N] - Backward scroll limit. - -i ........ --ignore-case - Ignore case in searches that do not contain uppercase. - -I ........ --IGNORE-CASE - Ignore case in all searches. - -j [_N] .... --jump-target=[_N] - Screen position of target lines. - -J ........ --status-column - Display a status column at left edge of screen. - -k _f_i_l_e ... --lesskey-file=_f_i_l_e - Use a compiled lesskey file. - -K ........ --quit-on-intr - Exit less in response to ctrl-C. - -L ........ --no-lessopen - Ignore the LESSOPEN environment variable. - -m -M .... --long-prompt --LONG-PROMPT - Set prompt style. - -n ......... --line-numbers - Suppress line numbers in prompts and messages. - -N ......... --LINE-NUMBERS - Display line number at start of each line. - -o [_f_i_l_e] .. --log-file=[_f_i_l_e] - Copy to log file (standard input only). - -O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e] - Copy to log file (unconditionally overwrite). - -p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n] - Start at pattern (from command line). - -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] - Define new prompt. - -q -Q .... --quiet --QUIET --silent --SILENT - Quiet the terminal bell. - -r -R .... --raw-control-chars --RAW-CONTROL-CHARS - Output "raw" control characters. - -s ........ --squeeze-blank-lines - Squeeze multiple blank lines. - -S ........ --chop-long-lines - Chop (truncate) long lines rather than wrapping. - -t _t_a_g .... --tag=[_t_a_g] - Find a tag. - -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] - Use an alternate tags file. - -u -U .... --underline-special --UNDERLINE-SPECIAL - Change handling of backspaces, tabs and carriage returns. - -V ........ --version - Display the version number of "less". - -w ........ --hilite-unread - Highlight first new line after forward-screen. - -W ........ --HILITE-UNREAD - Highlight first new line after any forward movement. - -x [_N[,...]] --tabs=[_N[,...]] - Set tab stops. - -X ........ --no-init - Don't use termcap init/deinit strings. - -y [_N] .... --max-forw-scroll=[_N] - Forward scroll limit. - -z [_N] .... --window=[_N] - Set size of window. - -" [_c[_c]] . --quotes=[_c[_c]] - Set shell quote characters. - -~ ........ --tilde - Don't display tildes after end of file. - -# [_N] .... --shift=[_N] - Set horizontal scroll amount (0 = one half screen width). - - --exit-follow-on-close - Exit F command on a pipe when writer closes pipe. - --file-size - Automatically determine the size of the input file. - --follow-name - The F command changes files if the input file is renamed. - --form-feed - Stop scrolling when a form feed character is reached. - --header=[_L[,_C[,_N]]] - Use _L lines (starting at line _N) and _C columns as headers. - --incsearch - Search file as each pattern character is typed in. - --intr=[_C] - Use _C instead of ^X to interrupt a read. - --lesskey-context=_t_e_x_t - Use lesskey source file contents. - --lesskey-src=_f_i_l_e - Use a lesskey source file. - --line-num-width=[_N] - Set the width of the -N line number field to _N characters. - --match-shift=[_N] - Show at least _N characters to the left of a search match. - --modelines=[_N] - Read _N lines from the input file and look for vim modelines. - --mouse - Enable mouse input. - --no-edit-warn - Don't warn when using v command on a file opened via LESSOPEN. - --no-keypad - Don't send termcap keypad init/deinit strings. - --no-histdups - Remove duplicates from command history. - --no-number-headers - Don't give line numbers to header lines. - --no-paste - Ignore pasted input. - --no-search-header-lines - Searches do not include header lines. - --no-search-header-columns - Searches do not include header columns. - --no-search-headers - Searches do not include header lines or columns. - --no-vbell - Disable the terminal's visual bell. - --redraw-on-quit - Redraw final screen when quitting. - --rscroll=[_C] - Set the character used to mark truncated lines. - --save-marks - Retain marks across invocations of less. - --search-options=[EFKNRW-] - Set default options for every search. - --show-preproc-errors - Display a message if preprocessor exits with an error status. - --proc-backspace - Process backspaces for bold/underline. - --PROC-BACKSPACE - Treat backspaces as control characters. - --proc-return - Delete carriage returns before newline. - --PROC-RETURN - Treat carriage returns as control characters. - --proc-tab - Expand tabs to spaces. - --PROC-TAB - Treat tabs as control characters. - --status-col-width=[_N] - Set the width of the -J status column to _N characters. - --status-line - Highlight or color the entire line containing a mark. - --use-backslash - Subsequent options use backslash as escape char. - --use-color - Enables colored text. - --wheel-lines=[_N] - Each click of the mouse wheel moves _N lines. - --wordwrap - Wrap lines at spaces. - - - --------------------------------------------------------------------------- - - LLIINNEE EEDDIITTIINNGG - - These keys can be used to edit text being entered - on the "command line" at the bottom of the screen. - - RightArrow ..................... ESC-l ... Move cursor right one character. - LeftArrow ...................... ESC-h ... Move cursor left one character. - ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. - ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. - HOME ........................... ESC-0 ... Move cursor to start of line. - END ............................ ESC-$ ... Move cursor to end of line. - BACKSPACE ................................ Delete char to left of cursor. - DELETE ......................... ESC-x ... Delete char under cursor. - ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. - ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. - ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. - UpArrow ........................ ESC-k ... Retrieve previous command line. - DownArrow ...................... ESC-j ... Retrieve next command line. - TAB ...................................... Complete filename & cycle. - SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. - ctrl-L ................................... Complete filename, list all. diff --git a/h origin fix-stats-object-error-v2q b/h origin fix-stats-object-error-v2q deleted file mode 100644 index ce823849..00000000 --- a/h origin fix-stats-object-error-v2q +++ /dev/null @@ -1,27 +0,0 @@ - - SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS - - Commands marked with * may be preceded by a number, _N. - Notes in parentheses indicate the behavior if _N is given. - A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. - - h H Display this help. - q :q Q :Q ZZ Exit. - --------------------------------------------------------------------------- - - MMOOVVIINNGG - - e ^E j ^N CR * Forward one line (or _N lines). - y ^Y k ^K ^P * Backward one line (or _N lines). - ESC-j * Forward one file line (or _N file lines). - ESC-k * Backward one file line (or _N file lines). - f ^F ^V SPACE * Forward one window (or _N lines). - b ^B ESC-v * Backward one window (or _N lines). - z * Forward one window (and set window to _N). - w * Backward one window (and set window to _N). - ESC-SPACE * Forward one window, but don't stop at end-of-file. - ESC-b * Backward one window, but don't stop at beginning-of-file. - d ^D * Forward one half-window (and set half-window to _N). - u ^U * Backward one half-window (and set half-window to _N). - ESC-) RightArrow * Right one half screen width (or _N positions). - ESC-( LeftArrow * Left one half screen width (or _N positions). diff --git a/test-fix.js b/test-fix.js deleted file mode 100644 index cd3ab752..00000000 --- a/test-fix.js +++ /dev/null @@ -1,24 +0,0 @@ -const analyzer = require('./lib/analyzer'); - -// Test with minimal stats (missing assets array) -const testStats = { - version: "5.0.0", - hash: "test123", - chunks: [], - // assets: undefined, // This is missing - should trigger the original bug - errors: [], - warnings: [], - entrypoints: {}, - namedChunkGroups: {}, - outputPath: "/tmp", - publicPath: "/" -}; - -console.log('๐Ÿงช Testing fix...'); -try { - const result = analyzer.getViewerData(testStats); - console.log('โœ… SUCCESS! Fix works - no more TypeError'); - console.log('Result has', result.length, 'assets'); -} catch (error) { - console.error('โŒ FAILED:', error.message); -} \ No newline at end of file diff --git a/test-stats.json b/test-stats.json deleted file mode 100644 index 3f5287e0..00000000 --- a/test-stats.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "chunks": [ - { - "id": 1, - "files": ["main.js"], - "modules": [], - "sizes": {} - } - ], - "entrypoints": {}, - "errors": [], - "errorsCount": 0, - "hash": "abc", - "namedChunkGroups": {}, - "outputPath": "/dist", - "publicPath": "/", - "version": "5.x", - "warnings": [], - "warningsCount": 0 -} From ed1eebe02a6ea3746cc1d76b717d5baa4bec300c Mon Sep 17 00:00:00 2001 From: Srushti-33 Date: Fri, 14 Nov 2025 05:26:01 -0500 Subject: [PATCH 09/12] fix: handle minimal stats and undefined chunks/modules --- src/analyzer.js | 42 +++++++++++++++++++++++++++++++----------- test/analyzer.js | 5 ++++- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/analyzer.js b/src/analyzer.js index d684928f..b8a37660 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -26,11 +26,23 @@ function getViewerData(bundleStats, bundleDir, opts) { const isAssetIncluded = createAssetsFilter(excludeAssets); - // Sometimes all the information is located in `children` array (e.g. problem in #10) - if ( - (bundleStats.assets == null || bundleStats.assets.length === 0) - && bundleStats.children && bundleStats.children.length > 0 - ) { +// Handle minimal stats format that only has assetsByChunkName but no assets array +if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.assetsByChunkName) { + // Convert assetsByChunkName to assets array for minimal stats + bundleStats.assets = []; + Object.entries(bundleStats.assetsByChunkName).forEach(([chunkName, assetNames]) => { + assetNames.forEach(assetName => { + bundleStats.assets.push({ + name: assetName, + chunks: [chunkName], + size: 0 // Default size for minimal stats + }); + }); + }); +} + +// Sometimes all the information is located in `children` array (e.g. problem in #10) +if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.children && bundleStats.children.length > 0) { const {children} = bundleStats; bundleStats = bundleStats.children[0]; // Sometimes if there are additional child chunks produced add them as child assets, @@ -189,13 +201,21 @@ function getChildAssetBundles(bundleStats, assetName) { } function getBundleModules(bundleStats) { + // Handle case where bundleStats is undefined or has no modules/chunks + if (!bundleStats) { + return []; + } + const seenIds = new Set(); - - return flatten( - ((bundleStats.chunks?.map(chunk => chunk.modules)) || []) - .concat(bundleStats.modules) - .filter(Boolean) - ).filter(mod => { + + // Safely handle chunks and modules that might be undefined + const chunksModules = bundleStats.chunks ? + bundleStats.chunks.map(chunk => chunk.modules || []) : + []; + + const statsModules = bundleStats.modules || []; + + return flatten(chunksModules.concat(statsModules).filter(Boolean)).filter(mod => { // Filtering out Webpack's runtime modules as they don't have ids and can't be parsed (introduced in Webpack 5) if (isRuntimeModule(mod)) { return false; diff --git a/test/analyzer.js b/test/analyzer.js index a3869bf5..d2766787 100644 --- a/test/analyzer.js +++ b/test/analyzer.js @@ -96,8 +96,11 @@ describe('Analyzer', function () { it('should handle stats with minimal configuration', async function () { generateReportFrom('minimal-stats/stats.json'); - await expectValidReport(); + await expectValidReport({ + bundleLabel: 'viewer.js', + statSize: 0 }); +}); it.skip("should not filter out modules that we couldn't find during parsing", async function () { generateReportFrom('with-missing-parsed-module/stats.json'); From 10a4d098fa86afd84226a97d3ffb7193a96d3b1b Mon Sep 17 00:00:00 2001 From: Srushti-33 Date: Tue, 18 Nov 2025 11:48:57 -0500 Subject: [PATCH 10/12] feat: handle undefined assets/modules in analyzer with minimal stats support --- src/analyzer.js | 38 +++++++++++++++++++------------------- test/analyzer.js | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/analyzer.js b/src/analyzer.js index b8a37660..b4ebb6b3 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -26,23 +26,23 @@ function getViewerData(bundleStats, bundleDir, opts) { const isAssetIncluded = createAssetsFilter(excludeAssets); -// Handle minimal stats format that only has assetsByChunkName but no assets array -if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.assetsByChunkName) { + // Handle minimal stats format that only has assetsByChunkName but no assets array + if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.assetsByChunkName) { // Convert assetsByChunkName to assets array for minimal stats - bundleStats.assets = []; - Object.entries(bundleStats.assetsByChunkName).forEach(([chunkName, assetNames]) => { - assetNames.forEach(assetName => { - bundleStats.assets.push({ - name: assetName, - chunks: [chunkName], - size: 0 // Default size for minimal stats + bundleStats.assets = []; + Object.entries(bundleStats.assetsByChunkName).forEach(([chunkName, assetNames]) => { + assetNames.forEach(assetName => { + bundleStats.assets.push({ + name: assetName, + chunks: [chunkName], + size: 0 // Default size for minimal stats + }); }); }); - }); -} + } -// Sometimes all the information is located in `children` array (e.g. problem in #10) -if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.children && bundleStats.children.length > 0) { + // Sometimes all the information is located in `children` array (e.g. problem in #10) + if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.children && bundleStats.children.length > 0) { const {children} = bundleStats; bundleStats = bundleStats.children[0]; // Sometimes if there are additional child chunks produced add them as child assets, @@ -205,16 +205,16 @@ function getBundleModules(bundleStats) { if (!bundleStats) { return []; } - + const seenIds = new Set(); - + // Safely handle chunks and modules that might be undefined - const chunksModules = bundleStats.chunks ? - bundleStats.chunks.map(chunk => chunk.modules || []) : + const chunksModules = bundleStats.chunks ? + bundleStats.chunks.map(chunk => chunk.modules || []) : []; - + const statsModules = bundleStats.modules || []; - + return flatten(chunksModules.concat(statsModules).filter(Boolean)).filter(mod => { // Filtering out Webpack's runtime modules as they don't have ids and can't be parsed (introduced in Webpack 5) if (isRuntimeModule(mod)) { diff --git a/test/analyzer.js b/test/analyzer.js index d2766787..f007085e 100644 --- a/test/analyzer.js +++ b/test/analyzer.js @@ -99,8 +99,8 @@ describe('Analyzer', function () { await expectValidReport({ bundleLabel: 'viewer.js', statSize: 0 + }); }); -}); it.skip("should not filter out modules that we couldn't find during parsing", async function () { generateReportFrom('with-missing-parsed-module/stats.json'); From e76fbd16f1dfb11adac21c129bf44fb0b79e922c Mon Sep 17 00:00:00 2001 From: Vesa Laakso <482561+valscion@users.noreply.github.com> Date: Thu, 20 Nov 2025 15:37:39 +0200 Subject: [PATCH 11/12] Restore back to original, minimal code change This is the same code as the first commit in this PR --- src/analyzer.js | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/src/analyzer.js b/src/analyzer.js index b4ebb6b3..d684928f 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -26,23 +26,11 @@ function getViewerData(bundleStats, bundleDir, opts) { const isAssetIncluded = createAssetsFilter(excludeAssets); - // Handle minimal stats format that only has assetsByChunkName but no assets array - if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.assetsByChunkName) { - // Convert assetsByChunkName to assets array for minimal stats - bundleStats.assets = []; - Object.entries(bundleStats.assetsByChunkName).forEach(([chunkName, assetNames]) => { - assetNames.forEach(assetName => { - bundleStats.assets.push({ - name: assetName, - chunks: [chunkName], - size: 0 // Default size for minimal stats - }); - }); - }); - } - // Sometimes all the information is located in `children` array (e.g. problem in #10) - if ((bundleStats.assets == null || bundleStats.assets.length === 0) && bundleStats.children && bundleStats.children.length > 0) { + if ( + (bundleStats.assets == null || bundleStats.assets.length === 0) + && bundleStats.children && bundleStats.children.length > 0 + ) { const {children} = bundleStats; bundleStats = bundleStats.children[0]; // Sometimes if there are additional child chunks produced add them as child assets, @@ -201,21 +189,13 @@ function getChildAssetBundles(bundleStats, assetName) { } function getBundleModules(bundleStats) { - // Handle case where bundleStats is undefined or has no modules/chunks - if (!bundleStats) { - return []; - } - const seenIds = new Set(); - // Safely handle chunks and modules that might be undefined - const chunksModules = bundleStats.chunks ? - bundleStats.chunks.map(chunk => chunk.modules || []) : - []; - - const statsModules = bundleStats.modules || []; - - return flatten(chunksModules.concat(statsModules).filter(Boolean)).filter(mod => { + return flatten( + ((bundleStats.chunks?.map(chunk => chunk.modules)) || []) + .concat(bundleStats.modules) + .filter(Boolean) + ).filter(mod => { // Filtering out Webpack's runtime modules as they don't have ids and can't be parsed (introduced in Webpack 5) if (isRuntimeModule(mod)) { return false; From e743f65f3528e7a694a9c2e70f758c38caecc002 Mon Sep 17 00:00:00 2001 From: Vesa Laakso <482561+valscion@users.noreply.github.com> Date: Thu, 20 Nov 2025 15:55:36 +0200 Subject: [PATCH 12/12] Simplify test case to expect empty chart data --- test/analyzer.js | 6 ++---- test/stats/minimal-stats/expected-chart-data.json | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 test/stats/minimal-stats/expected-chart-data.json diff --git a/test/analyzer.js b/test/analyzer.js index f007085e..ee019a31 100644 --- a/test/analyzer.js +++ b/test/analyzer.js @@ -96,10 +96,8 @@ describe('Analyzer', function () { it('should handle stats with minimal configuration', async function () { generateReportFrom('minimal-stats/stats.json'); - await expectValidReport({ - bundleLabel: 'viewer.js', - statSize: 0 - }); + const chartData = await getChartData(); + expect(chartData).to.be.empty; }); it.skip("should not filter out modules that we couldn't find during parsing", async function () { diff --git a/test/stats/minimal-stats/expected-chart-data.json b/test/stats/minimal-stats/expected-chart-data.json deleted file mode 100644 index fe51488c..00000000 --- a/test/stats/minimal-stats/expected-chart-data.json +++ /dev/null @@ -1 +0,0 @@ -[]