webpack-bundle-analyzer 2.13.1 → 3.0.2

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 CHANGED
@@ -14,6 +14,40 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
14
14
 
15
15
  <!-- Add changelog entries for new changes under this section -->
16
16
 
17
+ ## 3.0.2
18
+
19
+ * **Improvements**
20
+ * Drop `@babel/runtime` dependency ([#209](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/209), [@realityking](https://github.com/realityking))
21
+ * Properly specify minimal Node.js version in `.babelrc` ([#209](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/209), [@realityking](https://github.com/realityking))
22
+
23
+ * **Bug Fix**
24
+ * Move some "dependencies" to "devDependencies" ([#209](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/209), [@realityking](https://github.com/realityking))
25
+
26
+ ## 3.0.1
27
+
28
+ * **Bug Fix**
29
+ * Small UI fixes
30
+
31
+ ## 3.0.0
32
+
33
+ * **Breaking change**
34
+ * Dropped support for Node.js v4. Minimal required version now is v6.14.4
35
+ * Contents of concatenated modules are now hidden by default because of a number of related issues ([details](https://github.com/webpack-contrib/webpack-bundle-analyzer/issues/188)), but can be shown using a new checkbox in the sidebar.
36
+
37
+ * **New Feature**
38
+ * Added modules search
39
+ * Added ability to pin and resize the sidebar
40
+ * Added button to toggle the sidebar
41
+ * Added checkbox to show/hide contents of concatenated modules
42
+
43
+ * **Improvements**
44
+ * Nested folders that contain only one child folder are now visually merged i.e. `folder1 => folder2 => file1` is now shown like `folder1/folder2 => file1` (thanks to [@varun-singh-1](https://github.com/varun-singh-1) for the idea)
45
+
46
+ * **Internal**
47
+ * Dropped support for Node.js v4
48
+ * Using MobX for state management
49
+ * Updated dependencies
50
+
17
51
  ## 2.13.1
18
52
 
19
53
  * **Improvement**
package/README.md CHANGED
@@ -61,7 +61,7 @@ new BundleAnalyzerPlugin(options?: object)
61
61
  |**`openAnalyzer`**|`{Boolean}`|Default: `true`. Automatically open report in default browser.|
62
62
  |**`generateStatsFile`**|`{Boolean}`|Default: `false`. If `true`, webpack stats JSON file will be generated in bundle output directory|
63
63
  |**`statsFilename`**|`{String}`|Default: `stats.json`. Name of webpack stats JSON file that will be generated if `generateStatsFile` is `true`. Relative to bundle output directory.|
64
- |**`statsOptions`**|`null` or `{Object}`|Default: `null`. Options for `stats.toJson()` method. For example you can exclude sources of your modules from stats file with `source: false` option. [See more options here](https://github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21). |
64
+ |**`statsOptions`**|`null` or `{Object}`|Default: `null`. Options for `stats.toJson()` method. For example you can exclude sources of your modules from stats file with `source: false` option. [See more options here](https://webpack.js.org/configuration/stats/). |
65
65
  |**`excludeAssets`**|`{null\|pattern\|pattern[]}` where `pattern` equals to `{String\|RegExp\|function}`|Default: `null`. Patterns that will be used to match against asset names to exclude them from the report. If pattern is a string it will be converted to RegExp via `new RegExp(str)`. If pattern is a function it should have the following signature `(assetName: string) => boolean` and should return `true` to *exclude* matching asset. If multiple patterns are provided asset should match at least one of them to be excluded. |
66
66
  |**`logLevel`**|One of: `info`, `warn`, `error`, `silent`|Default: `info`. Used to control how much details the plugin outputs.|
67
67
 
@@ -1,26 +1,30 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
4
 
5
- function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
5
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
6
6
 
7
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
8
8
 
9
- var bfj = require('bfj-node4');
10
- var path = require('path');
11
- var mkdir = require('mkdirp');
9
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
12
10
 
13
- var _require = require('chalk'),
14
- bold = _require.bold;
11
+ const bfj = require('bfj');
15
12
 
16
- var Logger = require('./Logger');
17
- var viewer = require('./viewer');
13
+ const path = require('path');
18
14
 
19
- var BundleAnalyzerPlugin = function () {
20
- function BundleAnalyzerPlugin(opts) {
21
- _classCallCheck(this, BundleAnalyzerPlugin);
15
+ const mkdir = require('mkdirp');
22
16
 
23
- this.opts = Object.assign({
17
+ const {
18
+ bold
19
+ } = require('chalk');
20
+
21
+ const Logger = require('./Logger');
22
+
23
+ const viewer = require('./viewer');
24
+
25
+ class BundleAnalyzerPlugin {
26
+ constructor(opts) {
27
+ this.opts = _objectSpread({
24
28
  analyzerMode: 'server',
25
29
  analyzerHost: '127.0.0.1',
26
30
  analyzerPort: 8888,
@@ -35,134 +39,106 @@ var BundleAnalyzerPlugin = function () {
35
39
  // deprecated
36
40
  startAnalyzer: true
37
41
  }, opts);
38
-
39
42
  this.server = null;
40
43
  this.logger = new Logger(this.opts.logLevel);
41
44
  }
42
45
 
43
- _createClass(BundleAnalyzerPlugin, [{
44
- key: 'apply',
45
- value: function apply(compiler) {
46
- var _this = this;
47
-
48
- this.compiler = compiler;
49
-
50
- var done = function done(stats) {
51
- stats = stats.toJson(_this.opts.statsOptions);
52
-
53
- var actions = [];
54
-
55
- if (_this.opts.generateStatsFile) {
56
- actions.push(function () {
57
- return _this.generateStatsFile(stats);
58
- });
59
- }
60
-
61
- // Handling deprecated `startAnalyzer` flag
62
- if (_this.opts.analyzerMode === 'server' && !_this.opts.startAnalyzer) {
63
- _this.opts.analyzerMode = 'disabled';
64
- }
65
-
66
- if (_this.opts.analyzerMode === 'server') {
67
- actions.push(function () {
68
- return _this.startAnalyzerServer(stats);
69
- });
70
- } else if (_this.opts.analyzerMode === 'static') {
71
- actions.push(function () {
72
- return _this.generateStaticReport(stats);
73
- });
74
- }
75
-
76
- if (actions.length) {
77
- // Making analyzer logs to be after all webpack logs in the console
78
- setImmediate(function () {
79
- actions.forEach(function (action) {
80
- return action();
81
- });
82
- });
83
- }
84
- };
85
-
86
- if (compiler.hooks) {
87
- compiler.hooks.done.tap('webpack-bundle-analyzer', done);
88
- } else {
89
- compiler.plugin('done', done);
46
+ apply(compiler) {
47
+ this.compiler = compiler;
48
+
49
+ const done = stats => {
50
+ stats = stats.toJson(this.opts.statsOptions);
51
+ const actions = [];
52
+
53
+ if (this.opts.generateStatsFile) {
54
+ actions.push(() => this.generateStatsFile(stats));
55
+ } // Handling deprecated `startAnalyzer` flag
56
+
57
+
58
+ if (this.opts.analyzerMode === 'server' && !this.opts.startAnalyzer) {
59
+ this.opts.analyzerMode = 'disabled';
90
60
  }
91
- }
92
- }, {
93
- key: 'generateStatsFile',
94
- value: function () {
95
- var _ref = _asyncToGenerator(function* (stats) {
96
- var statsFilepath = path.resolve(this.compiler.outputPath, this.opts.statsFilename);
97
- mkdir.sync(path.dirname(statsFilepath));
98
-
99
- try {
100
- yield bfj.write(statsFilepath, stats, {
101
- space: 2,
102
- promises: 'ignore',
103
- buffers: 'ignore',
104
- maps: 'ignore',
105
- iterables: 'ignore',
106
- circular: 'ignore'
107
- });
108
-
109
- this.logger.info(`${bold('Webpack Bundle Analyzer')} saved stats file to ${bold(statsFilepath)}`);
110
- } catch (error) {
111
- this.logger.error(`${bold('Webpack Bundle Analyzer')} error saving stats file to ${bold(statsFilepath)}: ${error}`);
112
- }
113
- });
114
-
115
- function generateStatsFile(_x) {
116
- return _ref.apply(this, arguments);
61
+
62
+ if (this.opts.analyzerMode === 'server') {
63
+ actions.push(() => this.startAnalyzerServer(stats));
64
+ } else if (this.opts.analyzerMode === 'static') {
65
+ actions.push(() => this.generateStaticReport(stats));
117
66
  }
118
67
 
119
- return generateStatsFile;
120
- }()
121
- }, {
122
- key: 'startAnalyzerServer',
123
- value: function () {
124
- var _ref2 = _asyncToGenerator(function* (stats) {
125
- if (this.server) {
126
- (yield this.server).updateChartData(stats);
127
- } else {
128
- this.server = viewer.startServer(stats, {
129
- openBrowser: this.opts.openAnalyzer,
130
- host: this.opts.analyzerHost,
131
- port: this.opts.analyzerPort,
132
- bundleDir: this.getBundleDirFromCompiler(),
133
- logger: this.logger,
134
- defaultSizes: this.opts.defaultSizes,
135
- excludeAssets: this.opts.excludeAssets
136
- });
137
- }
138
- });
139
-
140
- function startAnalyzerServer(_x2) {
141
- return _ref2.apply(this, arguments);
68
+ if (actions.length) {
69
+ // Making analyzer logs to be after all webpack logs in the console
70
+ setImmediate(() => {
71
+ actions.forEach(action => action());
72
+ });
142
73
  }
74
+ };
143
75
 
144
- return startAnalyzerServer;
145
- }()
146
- }, {
147
- key: 'generateStaticReport',
148
- value: function generateStaticReport(stats) {
149
- viewer.generateReport(stats, {
150
- openBrowser: this.opts.openAnalyzer,
151
- reportFilename: path.resolve(this.compiler.outputPath, this.opts.reportFilename),
152
- bundleDir: this.getBundleDirFromCompiler(),
153
- logger: this.logger,
154
- defaultSizes: this.opts.defaultSizes,
155
- excludeAssets: this.opts.excludeAssets
156
- });
157
- }
158
- }, {
159
- key: 'getBundleDirFromCompiler',
160
- value: function getBundleDirFromCompiler() {
161
- return this.compiler.outputFileSystem.constructor.name === 'MemoryFileSystem' ? null : this.compiler.outputPath;
76
+ if (compiler.hooks) {
77
+ compiler.hooks.done.tap('webpack-bundle-analyzer', done);
78
+ } else {
79
+ compiler.plugin('done', done);
162
80
  }
163
- }]);
81
+ }
82
+
83
+ generateStatsFile(stats) {
84
+ var _this = this;
85
+
86
+ return _asyncToGenerator(function* () {
87
+ const statsFilepath = path.resolve(_this.compiler.outputPath, _this.opts.statsFilename);
88
+ mkdir.sync(path.dirname(statsFilepath));
89
+
90
+ try {
91
+ yield bfj.write(statsFilepath, stats, {
92
+ space: 2,
93
+ promises: 'ignore',
94
+ buffers: 'ignore',
95
+ maps: 'ignore',
96
+ iterables: 'ignore',
97
+ circular: 'ignore'
98
+ });
99
+
100
+ _this.logger.info(`${bold('Webpack Bundle Analyzer')} saved stats file to ${bold(statsFilepath)}`);
101
+ } catch (error) {
102
+ _this.logger.error(`${bold('Webpack Bundle Analyzer')} error saving stats file to ${bold(statsFilepath)}: ${error}`);
103
+ }
104
+ })();
105
+ }
106
+
107
+ startAnalyzerServer(stats) {
108
+ var _this2 = this;
109
+
110
+ return _asyncToGenerator(function* () {
111
+ if (_this2.server) {
112
+ (yield _this2.server).updateChartData(stats);
113
+ } else {
114
+ _this2.server = viewer.startServer(stats, {
115
+ openBrowser: _this2.opts.openAnalyzer,
116
+ host: _this2.opts.analyzerHost,
117
+ port: _this2.opts.analyzerPort,
118
+ bundleDir: _this2.getBundleDirFromCompiler(),
119
+ logger: _this2.logger,
120
+ defaultSizes: _this2.opts.defaultSizes,
121
+ excludeAssets: _this2.opts.excludeAssets
122
+ });
123
+ }
124
+ })();
125
+ }
126
+
127
+ generateStaticReport(stats) {
128
+ viewer.generateReport(stats, {
129
+ openBrowser: this.opts.openAnalyzer,
130
+ reportFilename: path.resolve(this.compiler.outputPath, this.opts.reportFilename),
131
+ bundleDir: this.getBundleDirFromCompiler(),
132
+ logger: this.logger,
133
+ defaultSizes: this.opts.defaultSizes,
134
+ excludeAssets: this.opts.excludeAssets
135
+ });
136
+ }
137
+
138
+ getBundleDirFromCompiler() {
139
+ return this.compiler.outputFileSystem.constructor.name === 'MemoryFileSystem' ? null : this.compiler.outputPath;
140
+ }
164
141
 
165
- return BundleAnalyzerPlugin;
166
- }();
142
+ }
167
143
 
168
144
  module.exports = BundleAnalyzerPlugin;
package/lib/Logger.js CHANGED
@@ -1,94 +1,38 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
- var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
4
-
5
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
6
-
7
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8
-
9
- var LEVELS = ['debug', 'info', 'warn', 'error', 'silent'];
10
-
11
- var LEVEL_TO_CONSOLE_METHOD = new Map([['debug', 'log'], ['info', 'log'], ['warn', 'log']]);
12
-
13
- var Logger = function () {
14
- function Logger() {
15
- var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Logger.defaultLevel;
16
-
17
- _classCallCheck(this, Logger);
3
+ const LEVELS = ['debug', 'info', 'warn', 'error', 'silent'];
4
+ const LEVEL_TO_CONSOLE_METHOD = new Map([['debug', 'log'], ['info', 'log'], ['warn', 'log']]);
18
5
 
6
+ class Logger {
7
+ constructor(level = Logger.defaultLevel) {
19
8
  this.activeLevels = new Set();
20
9
  this.setLogLevel(level);
21
10
  }
22
11
 
23
- _createClass(Logger, [{
24
- key: 'setLogLevel',
25
- value: function setLogLevel(level) {
26
- var levelIndex = LEVELS.indexOf(level);
27
-
28
- if (levelIndex === -1) throw new Error(`Invalid log level "${level}". Use one of these: ${LEVELS.join(', ')}`);
29
-
30
- this.activeLevels.clear();
31
-
32
- var _iteratorNormalCompletion = true;
33
- var _didIteratorError = false;
34
- var _iteratorError = undefined;
35
-
36
- try {
37
- for (var _iterator = LEVELS.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
38
- var _ref = _step.value;
12
+ setLogLevel(level) {
13
+ const levelIndex = LEVELS.indexOf(level);
14
+ if (levelIndex === -1) throw new Error(`Invalid log level "${level}". Use one of these: ${LEVELS.join(', ')}`);
15
+ this.activeLevels.clear();
39
16
 
40
- var _ref2 = _slicedToArray(_ref, 2);
41
-
42
- var i = _ref2[0];
43
- var _level = _ref2[1];
44
-
45
- if (i >= levelIndex) this.activeLevels.add(_level);
46
- }
47
- } catch (err) {
48
- _didIteratorError = true;
49
- _iteratorError = err;
50
- } finally {
51
- try {
52
- if (!_iteratorNormalCompletion && _iterator.return) {
53
- _iterator.return();
54
- }
55
- } finally {
56
- if (_didIteratorError) {
57
- throw _iteratorError;
58
- }
59
- }
60
- }
17
+ for (const [i, level] of LEVELS.entries()) {
18
+ if (i >= levelIndex) this.activeLevels.add(level);
61
19
  }
62
- }, {
63
- key: '_log',
64
- value: function _log(level) {
65
- var _console;
66
-
67
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
68
- args[_key - 1] = arguments[_key];
69
- }
20
+ }
70
21
 
71
- (_console = console)[LEVEL_TO_CONSOLE_METHOD.get(level) || level].apply(_console, args);
72
- }
73
- }]);
22
+ _log(level, ...args) {
23
+ console[LEVEL_TO_CONSOLE_METHOD.get(level) || level](...args);
24
+ }
74
25
 
75
- return Logger;
76
- }();
26
+ }
77
27
 
78
28
  Logger.levels = LEVELS;
79
29
  Logger.defaultLevel = 'info';
80
30
  ;
81
-
82
- LEVELS.forEach(function (level) {
31
+ LEVELS.forEach(level => {
83
32
  if (level === 'silent') return;
84
33
 
85
- Logger.prototype[level] = function () {
86
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
87
- args[_key2] = arguments[_key2];
88
- }
89
-
90
- if (this.activeLevels.has(level)) this._log.apply(this, [level].concat(args));
34
+ Logger.prototype[level] = function (...args) {
35
+ if (this.activeLevels.has(level)) this._log(level, ...args);
91
36
  };
92
37
  });
93
-
94
38
  module.exports = Logger;
package/lib/analyzer.js CHANGED
@@ -1,93 +1,72 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
- var fs = require('fs');
4
- var path = require('path');
3
+ const fs = require('fs');
5
4
 
6
- var _ = require('lodash');
7
- var gzipSize = require('gzip-size');
5
+ const path = require('path');
8
6
 
9
- var Logger = require('./Logger');
10
- var Folder = require('./tree/Folder').default;
7
+ const _ = require('lodash');
11
8
 
12
- var _require = require('./parseUtils'),
13
- parseBundle = _require.parseBundle;
9
+ const gzipSize = require('gzip-size');
14
10
 
15
- var _require2 = require('./utils'),
16
- createAssetsFilter = _require2.createAssetsFilter;
11
+ const Logger = require('./Logger');
17
12
 
18
- var FILENAME_QUERY_REGEXP = /\?.*$/;
13
+ const Folder = require('./tree/Folder').default;
19
14
 
15
+ const {
16
+ parseBundle
17
+ } = require('./parseUtils');
18
+
19
+ const {
20
+ createAssetsFilter
21
+ } = require('./utils');
22
+
23
+ const FILENAME_QUERY_REGEXP = /\?.*$/;
20
24
  module.exports = {
21
25
  getViewerData,
22
26
  readStatsFromFile
23
27
  };
24
28
 
25
29
  function getViewerData(bundleStats, bundleDir, opts) {
26
- var _ref = opts || {},
27
- _ref$logger = _ref.logger,
28
- logger = _ref$logger === undefined ? new Logger() : _ref$logger,
29
- _ref$excludeAssets = _ref.excludeAssets,
30
- excludeAssets = _ref$excludeAssets === undefined ? null : _ref$excludeAssets;
30
+ const {
31
+ logger = new Logger(),
32
+ excludeAssets = null
33
+ } = opts || {};
34
+ const isAssetIncluded = createAssetsFilter(excludeAssets); // Sometimes all the information is located in `children` array (e.g. problem in #10)
31
35
 
32
- var isAssetIncluded = createAssetsFilter(excludeAssets);
33
-
34
- // Sometimes all the information is located in `children` array (e.g. problem in #10)
35
36
  if (_.isEmpty(bundleStats.assets) && !_.isEmpty(bundleStats.children)) {
36
37
  bundleStats = bundleStats.children[0];
37
- }
38
+ } // Picking only `*.js` assets from bundle that has non-empty `chunks` array
38
39
 
39
- // Picking only `*.js` assets from bundle that has non-empty `chunks` array
40
- bundleStats.assets = _.filter(bundleStats.assets, function (asset) {
40
+
41
+ bundleStats.assets = _.filter(bundleStats.assets, asset => {
41
42
  // Removing query part from filename (yes, somebody uses it for some reason and Webpack supports it)
42
43
  // See #22
43
44
  asset.name = asset.name.replace(FILENAME_QUERY_REGEXP, '');
44
-
45
45
  return _.endsWith(asset.name, '.js') && !_.isEmpty(asset.chunks) && isAssetIncluded(asset.name);
46
- });
46
+ }); // Trying to parse bundle assets and get real module sizes if `bundleDir` is provided
47
47
 
48
- // Trying to parse bundle assets and get real module sizes if `bundleDir` is provided
49
- var bundlesSources = null;
50
- var parsedModules = null;
48
+ let bundlesSources = null;
49
+ let parsedModules = null;
51
50
 
52
51
  if (bundleDir) {
53
52
  bundlesSources = {};
54
53
  parsedModules = {};
55
54
 
56
- var _iteratorNormalCompletion = true;
57
- var _didIteratorError = false;
58
- var _iteratorError = undefined;
59
-
60
- try {
61
- for (var _iterator = bundleStats.assets[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
62
- var statAsset = _step.value;
63
-
64
- var assetFile = path.join(bundleDir, statAsset.name);
65
- var bundleInfo = void 0;
55
+ for (const statAsset of bundleStats.assets) {
56
+ const assetFile = path.join(bundleDir, statAsset.name);
57
+ let bundleInfo;
66
58
 
67
- try {
68
- bundleInfo = parseBundle(assetFile);
69
- } catch (err) {
70
- var msg = err.code === 'ENOENT' ? 'no such file' : err.message;
71
- logger.warn(`Error parsing bundle asset "${assetFile}": ${msg}`);
72
- continue;
73
- }
74
-
75
- bundlesSources[statAsset.name] = bundleInfo.src;
76
- _.assign(parsedModules, bundleInfo.modules);
77
- }
78
- } catch (err) {
79
- _didIteratorError = true;
80
- _iteratorError = err;
81
- } finally {
82
59
  try {
83
- if (!_iteratorNormalCompletion && _iterator.return) {
84
- _iterator.return();
85
- }
86
- } finally {
87
- if (_didIteratorError) {
88
- throw _iteratorError;
89
- }
60
+ bundleInfo = parseBundle(assetFile);
61
+ } catch (err) {
62
+ const msg = err.code === 'ENOENT' ? 'no such file' : err.message;
63
+ logger.warn(`Error parsing bundle asset "${assetFile}": ${msg}`);
64
+ continue;
90
65
  }
66
+
67
+ bundlesSources[statAsset.name] = bundleInfo.src;
68
+
69
+ _.assign(parsedModules, bundleInfo.modules);
91
70
  }
92
71
 
93
72
  if (_.isEmpty(bundlesSources)) {
@@ -97,28 +76,26 @@ function getViewerData(bundleStats, bundleDir, opts) {
97
76
  }
98
77
  }
99
78
 
100
- var modules = getBundleModules(bundleStats);
101
- var assets = _.transform(bundleStats.assets, function (result, statAsset) {
102
- var asset = result[statAsset.name] = _.pick(statAsset, 'size');
79
+ const modules = getBundleModules(bundleStats);
80
+
81
+ const assets = _.transform(bundleStats.assets, (result, statAsset) => {
82
+ const asset = result[statAsset.name] = _.pick(statAsset, 'size');
103
83
 
104
84
  if (bundlesSources && _.has(bundlesSources, statAsset.name)) {
105
85
  asset.parsedSize = bundlesSources[statAsset.name].length;
106
86
  asset.gzipSize = gzipSize.sync(bundlesSources[statAsset.name]);
107
- }
87
+ } // Picking modules from current bundle script
108
88
 
109
- // Picking modules from current bundle script
110
- asset.modules = _(modules).filter(function (statModule) {
111
- return assetHasModule(statAsset, statModule);
112
- }).each(function (statModule) {
89
+
90
+ asset.modules = _(modules).filter(statModule => assetHasModule(statAsset, statModule)).each(statModule => {
113
91
  if (parsedModules) {
114
92
  statModule.parsedSrc = parsedModules[statModule.id];
115
93
  }
116
94
  });
117
-
118
95
  asset.tree = createModulesTree(asset.modules);
119
96
  }, {});
120
97
 
121
- return _.transform(assets, function (result, asset, filename) {
98
+ return _.transform(assets, (result, asset, filename) => {
122
99
  result.push({
123
100
  label: filename,
124
101
  // Not using `asset.size` here provided by Webpack because it can be very confusing when `UglifyJsPlugin` is used.
@@ -143,17 +120,14 @@ function getBundleModules(bundleStats) {
143
120
 
144
121
  function assetHasModule(statAsset, statModule) {
145
122
  // Checking if this module is the part of asset chunks
146
- return _.some(statModule.chunks, function (moduleChunk) {
147
- return _.includes(statAsset.chunks, moduleChunk);
148
- });
123
+ return _.some(statModule.chunks, moduleChunk => _.includes(statAsset.chunks, moduleChunk));
149
124
  }
150
125
 
151
126
  function createModulesTree(modules) {
152
- var root = new Folder('.');
127
+ const root = new Folder('.');
153
128
 
154
- _.each(modules, function (module) {
155
- return root.addModule(module);
156
- });
129
+ _.each(modules, module => root.addModule(module));
157
130
 
131
+ root.mergeNestedFolders();
158
132
  return root;
159
133
  }