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 +34 -0
- package/README.md +1 -1
- package/lib/BundleAnalyzerPlugin.js +109 -133
- package/lib/Logger.js +19 -75
- package/lib/analyzer.js +51 -77
- package/lib/bin/analyzer.js +32 -37
- package/lib/index.js +4 -3
- package/lib/parseUtils.js +50 -75
- package/lib/tree/BaseFolder.js +92 -101
- package/lib/tree/ConcatenatedModule.js +57 -90
- package/lib/tree/ContentFolder.js +29 -49
- package/lib/tree/ContentModule.js +27 -47
- package/lib/tree/Folder.js +49 -84
- package/lib/tree/Module.js +51 -77
- package/lib/tree/Node.js +18 -23
- package/lib/tree/utils.js +8 -16
- package/lib/utils.js +12 -17
- package/lib/viewer.js +96 -112
- package/package.json +47 -35
- package/public/viewer.js +40 -1
- package/public/viewer.js.map +1 -1
- package/src/BundleAnalyzerPlugin.js +2 -2
- package/src/analyzer.js +3 -2
- package/src/bin/analyzer.js +2 -2
- package/src/index.js +1 -1
- package/src/tree/BaseFolder.js +27 -1
- package/src/tree/ConcatenatedModule.js +5 -1
- package/src/tree/Folder.js +1 -1
- package/src/tree/Node.js +4 -0
- package/src/utils.js +2 -2
- package/src/viewer.js +5 -5
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://
|
|
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
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
14
|
-
bold = _require.bold;
|
|
11
|
+
const bfj = require('bfj');
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
var viewer = require('./viewer');
|
|
13
|
+
const path = require('path');
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
function BundleAnalyzerPlugin(opts) {
|
|
21
|
-
_classCallCheck(this, BundleAnalyzerPlugin);
|
|
15
|
+
const mkdir = require('mkdirp');
|
|
22
16
|
|
|
23
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
166
|
-
}();
|
|
142
|
+
}
|
|
167
143
|
|
|
168
144
|
module.exports = BundleAnalyzerPlugin;
|
package/lib/Logger.js
CHANGED
|
@@ -1,94 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
22
|
+
_log(level, ...args) {
|
|
23
|
+
console[LEVEL_TO_CONSOLE_METHOD.get(level) || level](...args);
|
|
24
|
+
}
|
|
74
25
|
|
|
75
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
var gzipSize = require('gzip-size');
|
|
5
|
+
const path = require('path');
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
var Folder = require('./tree/Folder').default;
|
|
7
|
+
const _ = require('lodash');
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
parseBundle = _require.parseBundle;
|
|
9
|
+
const gzipSize = require('gzip-size');
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
createAssetsFilter = _require2.createAssetsFilter;
|
|
11
|
+
const Logger = require('./Logger');
|
|
17
12
|
|
|
18
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
40
|
-
bundleStats.assets = _.filter(bundleStats.assets,
|
|
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
|
-
|
|
49
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
110
|
-
asset.modules = _(modules).filter(
|
|
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,
|
|
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,
|
|
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
|
-
|
|
127
|
+
const root = new Folder('.');
|
|
153
128
|
|
|
154
|
-
_.each(modules,
|
|
155
|
-
return root.addModule(module);
|
|
156
|
-
});
|
|
129
|
+
_.each(modules, module => root.addModule(module));
|
|
157
130
|
|
|
131
|
+
root.mergeNestedFolders();
|
|
158
132
|
return root;
|
|
159
133
|
}
|