webpack-bundle-analyzer 4.6.1 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +1 -5
- package/lib/analyzer.js +45 -14
- package/lib/bin/analyzer.js +41 -39
- package/lib/template.js +2 -0
- package/lib/viewer.js +13 -0
- package/package.json +3 -2
- package/public/viewer.js +2 -2
- package/public/viewer.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,20 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
|
|
|
12
12
|
|
|
13
13
|
## UNRELEASED
|
|
14
14
|
|
|
15
|
+
## 4.8.0
|
|
16
|
+
|
|
17
|
+
* **Improvement**
|
|
18
|
+
* 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))
|
|
19
|
+
* Improve search UX by graying out non-matches ([#554](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/554) by [@starpit](https://github.com/starpit))
|
|
20
|
+
|
|
21
|
+
* **Internal**
|
|
22
|
+
* Add Node.js v16.x to CI and update GitHub actions ([#539](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/539) by [@amareshsm](https://github.com/amareshsm))
|
|
23
|
+
|
|
24
|
+
## 4.7.0
|
|
25
|
+
|
|
26
|
+
* **New Feature**
|
|
27
|
+
* Add the ability to filter to displaying only initial chunks per entrypoint ([#519](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/519) by [@pas-trop-de-zele](https://github.com/pas-trop-de-zele))
|
|
28
|
+
|
|
15
29
|
## 4.6.1
|
|
16
30
|
|
|
17
31
|
* **Bug Fix**
|
package/README.md
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
[![npm][npm]][npm-url]
|
|
2
2
|
[![node][node]][node-url]
|
|
3
|
-
[![deps][deps]][deps-url]
|
|
4
3
|
[![tests][tests]][tests-url]
|
|
5
4
|
[![downloads][downloads]][downloads-url]
|
|
6
5
|
|
|
@@ -58,7 +57,7 @@ new BundleAnalyzerPlugin(options?: object)
|
|
|
58
57
|
|:--:|:--:|:----------|
|
|
59
58
|
|**`analyzerMode`**|One of: `server`, `static`, `json`, `disabled`|Default: `server`. In `server` mode analyzer will start HTTP server to show bundle report. In `static` mode single HTML file with bundle report will be generated. In `json` mode single JSON file with bundle report will be generated. In `disabled` mode you can use this plugin to just generate Webpack Stats JSON file by setting `generateStatsFile` to `true`. |
|
|
60
59
|
|**`analyzerHost`**|`{String}`|Default: `127.0.0.1`. Host that will be used in `server` mode to start HTTP server.|
|
|
61
|
-
|**`analyzerPort`**|`{Number}` or `auto`|Default: `8888`. Port that will be used in `server` mode to start HTTP server
|
|
60
|
+
|**`analyzerPort`**|`{Number}` or `auto`|Default: `8888`. Port that will be used in `server` mode to start HTTP server. If `analyzerPort` is `auto`, the operating system will assign an arbitrary unused port |
|
|
62
61
|
|**`analyzerUrl`**|`{Function}` called with `{ listenHost: string, listenHost: string, boundAddress: server.address}`. [server.address comes from Node.js](https://nodejs.org/api/net.html#serveraddress)| Default: `http://${listenHost}:${boundAddress.port}`. The URL printed to console with server mode.|
|
|
63
62
|
|**`reportFilename`**|`{String}`|Default: `report.html`. Path to bundle report file that will be generated in `static` mode. It can be either an absolute path or a path relative to a bundle output directory (which is output.path in webpack config).|
|
|
64
63
|
|**`reportTitle`**|`{String\|function}`|Default: function that returns pretty printed current date and time. Content of the HTML `title` element; or a function of the form `() => string` that provides the content.|
|
|
@@ -211,9 +210,6 @@ To get more information about it you can read [issue #147](https://github.com/we
|
|
|
211
210
|
[node]: https://img.shields.io/node/v/webpack-bundle-analyzer.svg
|
|
212
211
|
[node-url]: https://nodejs.org
|
|
213
212
|
|
|
214
|
-
[deps]: https://david-dm.org/webpack-contrib/webpack-bundle-analyzer.svg
|
|
215
|
-
[deps-url]: https://david-dm.org/webpack-contrib/webpack-bundle-analyzer
|
|
216
|
-
|
|
217
213
|
[tests]: http://img.shields.io/travis/webpack-contrib/webpack-bundle-analyzer.svg
|
|
218
214
|
[tests-url]: https://travis-ci.org/webpack-contrib/webpack-bundle-analyzer
|
|
219
215
|
|
package/lib/analyzer.js
CHANGED
|
@@ -8,6 +8,10 @@ const _ = require('lodash');
|
|
|
8
8
|
|
|
9
9
|
const gzipSize = require('gzip-size');
|
|
10
10
|
|
|
11
|
+
const {
|
|
12
|
+
parseChunked
|
|
13
|
+
} = require('@discoveryjs/json-ext');
|
|
14
|
+
|
|
11
15
|
const Logger = require('./Logger');
|
|
12
16
|
|
|
13
17
|
const Folder = require('./tree/Folder').default;
|
|
@@ -155,22 +159,30 @@ function getViewerData(bundleStats, bundleDir, opts) {
|
|
|
155
159
|
asset.tree = createModulesTree(asset.modules);
|
|
156
160
|
return result;
|
|
157
161
|
}, {});
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
162
|
+
const chunkToInitialByEntrypoint = getChunkToInitialByEntrypoint(bundleStats);
|
|
163
|
+
return Object.entries(assets).map(([filename, asset]) => {
|
|
164
|
+
var _chunkToInitialByEntr;
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
label: filename,
|
|
168
|
+
isAsset: true,
|
|
169
|
+
// Not using `asset.size` here provided by Webpack because it can be very confusing when `UglifyJsPlugin` is used.
|
|
170
|
+
// In this case all module sizes from stats file will represent unminified module sizes, but `asset.size` will
|
|
171
|
+
// be the size of minified bundle.
|
|
172
|
+
// Using `asset.size` only if current asset doesn't contain any modules (resulting size equals 0)
|
|
173
|
+
statSize: asset.tree.size || asset.size,
|
|
174
|
+
parsedSize: asset.parsedSize,
|
|
175
|
+
gzipSize: asset.gzipSize,
|
|
176
|
+
groups: _.invokeMap(asset.tree.children, 'toChartData'),
|
|
177
|
+
isInitialByEntrypoint: (_chunkToInitialByEntr = chunkToInitialByEntrypoint[filename]) !== null && _chunkToInitialByEntr !== void 0 ? _chunkToInitialByEntr : {}
|
|
178
|
+
};
|
|
179
|
+
});
|
|
170
180
|
}
|
|
171
181
|
|
|
172
182
|
function readStatsFromFile(filename) {
|
|
173
|
-
return
|
|
183
|
+
return parseChunked(fs.createReadStream(filename, {
|
|
184
|
+
encoding: 'utf8'
|
|
185
|
+
}));
|
|
174
186
|
}
|
|
175
187
|
|
|
176
188
|
function getChildAssetBundles(bundleStats, assetName) {
|
|
@@ -200,4 +212,23 @@ function createModulesTree(modules) {
|
|
|
200
212
|
modules.forEach(module => root.addModule(module));
|
|
201
213
|
root.mergeNestedFolders();
|
|
202
214
|
return root;
|
|
203
|
-
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function getChunkToInitialByEntrypoint(bundleStats) {
|
|
218
|
+
if (bundleStats == null) {
|
|
219
|
+
return {};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const chunkToEntrypointInititalMap = {};
|
|
223
|
+
Object.values(bundleStats.entrypoints || {}).forEach(entrypoint => {
|
|
224
|
+
for (const asset of entrypoint.assets) {
|
|
225
|
+
var _chunkToEntrypointIni;
|
|
226
|
+
|
|
227
|
+
chunkToEntrypointInititalMap[asset.name] = (_chunkToEntrypointIni = chunkToEntrypointInititalMap[asset.name]) !== null && _chunkToEntrypointIni !== void 0 ? _chunkToEntrypointIni : {};
|
|
228
|
+
chunkToEntrypointInititalMap[asset.name][entrypoint.name] = true;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
return chunkToEntrypointInititalMap;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
;
|
package/lib/bin/analyzer.js
CHANGED
|
@@ -64,45 +64,47 @@ if (mode === 'server') {
|
|
|
64
64
|
if (!SIZES.has(defaultSizes)) showHelp(`Invalid default sizes option. Possible values are: ${[...SIZES].join(', ')}`);
|
|
65
65
|
bundleStatsFile = resolve(bundleStatsFile);
|
|
66
66
|
if (!bundleDir) bundleDir = dirname(bundleStatsFile);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
logger
|
|
105
|
-
|
|
67
|
+
parseAndAnalyse(bundleStatsFile);
|
|
68
|
+
|
|
69
|
+
async function parseAndAnalyse(bundleStatsFile) {
|
|
70
|
+
try {
|
|
71
|
+
const bundleStats = await analyzer.readStatsFromFile(bundleStatsFile);
|
|
72
|
+
|
|
73
|
+
if (mode === 'server') {
|
|
74
|
+
viewer.startServer(bundleStats, {
|
|
75
|
+
openBrowser,
|
|
76
|
+
port,
|
|
77
|
+
host,
|
|
78
|
+
defaultSizes,
|
|
79
|
+
reportTitle,
|
|
80
|
+
bundleDir,
|
|
81
|
+
excludeAssets,
|
|
82
|
+
logger: new Logger(logLevel),
|
|
83
|
+
analyzerUrl: utils.defaultAnalyzerUrl
|
|
84
|
+
});
|
|
85
|
+
} else if (mode === 'static') {
|
|
86
|
+
viewer.generateReport(bundleStats, {
|
|
87
|
+
openBrowser,
|
|
88
|
+
reportFilename: resolve(reportFilename || 'report.html'),
|
|
89
|
+
reportTitle,
|
|
90
|
+
defaultSizes,
|
|
91
|
+
bundleDir,
|
|
92
|
+
excludeAssets,
|
|
93
|
+
logger: new Logger(logLevel)
|
|
94
|
+
});
|
|
95
|
+
} else if (mode === 'json') {
|
|
96
|
+
viewer.generateJSONReport(bundleStats, {
|
|
97
|
+
reportFilename: resolve(reportFilename || 'report.json'),
|
|
98
|
+
bundleDir,
|
|
99
|
+
excludeAssets,
|
|
100
|
+
logger: new Logger(logLevel)
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
} catch (err) {
|
|
104
|
+
logger.error(`Couldn't read webpack bundle stats from "${bundleStatsFile}":\n${err}`);
|
|
105
|
+
logger.debug(err.stack);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
function showHelp(error) {
|
package/lib/template.js
CHANGED
|
@@ -45,6 +45,7 @@ function renderViewer({
|
|
|
45
45
|
title,
|
|
46
46
|
enableWebSocket,
|
|
47
47
|
chartData,
|
|
48
|
+
entrypoints,
|
|
48
49
|
defaultSizes,
|
|
49
50
|
mode
|
|
50
51
|
} = {}) {
|
|
@@ -66,6 +67,7 @@ function renderViewer({
|
|
|
66
67
|
<div id="app"></div>
|
|
67
68
|
<script>
|
|
68
69
|
window.chartData = ${escapeJson(chartData)};
|
|
70
|
+
window.entrypoints = ${escapeJson(entrypoints)};
|
|
69
71
|
window.defaultSizes = ${escapeJson(defaultSizes)};
|
|
70
72
|
</script>
|
|
71
73
|
</body>
|
package/lib/viewer.js
CHANGED
|
@@ -42,6 +42,7 @@ module.exports = {
|
|
|
42
42
|
startServer,
|
|
43
43
|
generateReport,
|
|
44
44
|
generateJSONReport,
|
|
45
|
+
getEntrypoints,
|
|
45
46
|
// deprecated
|
|
46
47
|
start: startServer
|
|
47
48
|
};
|
|
@@ -63,6 +64,7 @@ async function startServer(bundleStats, opts) {
|
|
|
63
64
|
excludeAssets
|
|
64
65
|
};
|
|
65
66
|
let chartData = getChartData(analyzerOpts, bundleStats, bundleDir);
|
|
67
|
+
const entrypoints = getEntrypoints(bundleStats);
|
|
66
68
|
if (!chartData) return;
|
|
67
69
|
const sirvMiddleware = sirv(`${projectRoot}/public`, {
|
|
68
70
|
// disables caching and traverse the file system on every request
|
|
@@ -74,6 +76,7 @@ async function startServer(bundleStats, opts) {
|
|
|
74
76
|
mode: 'server',
|
|
75
77
|
title: resolveTitle(reportTitle),
|
|
76
78
|
chartData,
|
|
79
|
+
entrypoints,
|
|
77
80
|
defaultSizes,
|
|
78
81
|
enableWebSocket: true
|
|
79
82
|
});
|
|
@@ -145,11 +148,13 @@ async function generateReport(bundleStats, opts) {
|
|
|
145
148
|
logger,
|
|
146
149
|
excludeAssets
|
|
147
150
|
}, bundleStats, bundleDir);
|
|
151
|
+
const entrypoints = getEntrypoints(bundleStats);
|
|
148
152
|
if (!chartData) return;
|
|
149
153
|
const reportHtml = renderViewer({
|
|
150
154
|
mode: 'static',
|
|
151
155
|
title: resolveTitle(reportTitle),
|
|
152
156
|
chartData,
|
|
157
|
+
entrypoints,
|
|
153
158
|
defaultSizes,
|
|
154
159
|
enableWebSocket: false
|
|
155
160
|
});
|
|
@@ -204,4 +209,12 @@ function getChartData(analyzerOpts, ...args) {
|
|
|
204
209
|
}
|
|
205
210
|
|
|
206
211
|
return chartData;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function getEntrypoints(bundleStats) {
|
|
215
|
+
if (bundleStats === null || bundleStats === undefined) {
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return Object.values(bundleStats.entrypoints || {}).map(entrypoint => entrypoint.name);
|
|
207
220
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webpack-bundle-analyzer",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.0",
|
|
4
4
|
"description": "Webpack plugin and CLI utility that represents bundle content as convenient interactive zoomable treemap",
|
|
5
5
|
"author": "Yury Grunin <grunin.ya@ya.ru>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"lib"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"@discoveryjs/json-ext": "0.5.7",
|
|
35
36
|
"acorn": "^8.0.4",
|
|
36
37
|
"acorn-walk": "^8.0.0",
|
|
37
38
|
"chalk": "^4.1.0",
|
|
@@ -84,7 +85,7 @@
|
|
|
84
85
|
"url-loader": "4.1.1",
|
|
85
86
|
"webpack": "5.37.1",
|
|
86
87
|
"webpack-cli": "3.3.12",
|
|
87
|
-
"webpack-dev-server": "3.11.
|
|
88
|
+
"webpack-dev-server": "3.11.3"
|
|
88
89
|
},
|
|
89
90
|
"keywords": [
|
|
90
91
|
"webpack",
|