From e231c77064329fdd586e2e69f65d24f9a5a2004a Mon Sep 17 00:00:00 2001 From: Henry Zhang Date: Mon, 13 Feb 2023 18:24:55 +1100 Subject: [PATCH] Support reading large stats.json files (#423) * Remake PR * Move from devDependencies --- CHANGELOG.md | 3 ++ package-lock.json | 5 +++ package.json | 1 + src/analyzer.js | 5 +-- src/bin/analyzer.js | 78 +++++++++++++++++++++++---------------------- 5 files changed, 52 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be7f7529..36a1efaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ ## UNRELEASED + * **Improvement** + * Support reading large (>500MB) stats.json files ([#423](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/423) by [@henry-alakazhang](https://github.com/henry-alakazhang)) + ## 4.7.0 * **New Feature** diff --git a/package-lock.json b/package-lock.json index f0030794..e2ef6c55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1258,6 +1258,11 @@ "integrity": "sha512-cDql5T3eS4Y5jzrDj25QNpU0pHgLFJ96MaoMAkJX8ceL2yat4u7EbIuqLoTbQLiTy1KxDRFbxHIKLzTUT64Duw==", "dev": true }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", diff --git a/package.json b/package.json index 1b920bd7..59037ac9 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "lib" ], "dependencies": { + "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", "chalk": "^4.1.0", diff --git a/src/analyzer.js b/src/analyzer.js index 4f483dad..14d16153 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -3,6 +3,7 @@ const path = require('path'); const _ = require('lodash'); const gzipSize = require('gzip-size'); +const {parseChunked} = require('@discoveryjs/json-ext'); const Logger = require('./Logger'); const Folder = require('./tree/Folder').default; @@ -164,8 +165,8 @@ function getViewerData(bundleStats, bundleDir, opts) { } function readStatsFromFile(filename) { - return JSON.parse( - fs.readFileSync(filename, 'utf8') + return parseChunked( + fs.createReadStream(filename, {encoding: 'utf8'}) ); } diff --git a/src/bin/analyzer.js b/src/bin/analyzer.js index 42da2d53..caf21f5b 100755 --- a/src/bin/analyzer.js +++ b/src/bin/analyzer.js @@ -110,44 +110,46 @@ bundleStatsFile = resolve(bundleStatsFile); if (!bundleDir) bundleDir = dirname(bundleStatsFile); -let bundleStats; -try { - bundleStats = analyzer.readStatsFromFile(bundleStatsFile); -} catch (err) { - logger.error(`Couldn't read webpack bundle stats from "${bundleStatsFile}":\n${err}`); - logger.debug(err.stack); - process.exit(1); -} - -if (mode === 'server') { - viewer.startServer(bundleStats, { - openBrowser, - port, - host, - defaultSizes, - reportTitle, - bundleDir, - excludeAssets, - logger: new Logger(logLevel), - analyzerUrl: utils.defaultAnalyzerUrl - }); -} else if (mode === 'static') { - viewer.generateReport(bundleStats, { - openBrowser, - reportFilename: resolve(reportFilename || 'report.html'), - reportTitle, - defaultSizes, - bundleDir, - excludeAssets, - logger: new Logger(logLevel) - }); -} else if (mode === 'json') { - viewer.generateJSONReport(bundleStats, { - reportFilename: resolve(reportFilename || 'report.json'), - bundleDir, - excludeAssets, - logger: new Logger(logLevel) - }); +parseAndAnalyse(bundleStatsFile); + +async function parseAndAnalyse(bundleStatsFile) { + try { + const bundleStats = await analyzer.readStatsFromFile(bundleStatsFile); + if (mode === 'server') { + viewer.startServer(bundleStats, { + openBrowser, + port, + host, + defaultSizes, + reportTitle, + bundleDir, + excludeAssets, + logger: new Logger(logLevel), + analyzerUrl: utils.defaultAnalyzerUrl + }); + } else if (mode === 'static') { + viewer.generateReport(bundleStats, { + openBrowser, + reportFilename: resolve(reportFilename || 'report.html'), + reportTitle, + defaultSizes, + bundleDir, + excludeAssets, + logger: new Logger(logLevel) + }); + } else if (mode === 'json') { + viewer.generateJSONReport(bundleStats, { + reportFilename: resolve(reportFilename || 'report.json'), + bundleDir, + excludeAssets, + logger: new Logger(logLevel) + }); + } + } catch (err) { + logger.error(`Couldn't read webpack bundle stats from "${bundleStatsFile}":\n${err}`); + logger.debug(err.stack); + process.exit(1); + } } function showHelp(error) {