webpack-bundle-analyzer 3.3.0 → 3.4.1
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 +33 -2
- package/README.md +2 -18
- package/lib/BundleAnalyzerPlugin.js +22 -9
- package/lib/bin/analyzer.js +11 -4
- package/lib/tree/ConcatenatedModule.js +3 -1
- package/lib/tree/ContentFolder.js +3 -1
- package/lib/tree/ContentModule.js +3 -1
- package/lib/tree/Folder.js +3 -1
- package/lib/viewer.js +26 -7
- package/package.json +3 -2
- package/public/viewer.js +1 -1
- package/public/viewer.js.map +1 -1
- package/src/BundleAnalyzerPlugin.js +16 -8
- package/src/bin/analyzer.js +10 -5
- package/src/viewer.js +25 -7
- package/views/script.ejs +1 -1
- package/views/viewer.ejs +3 -3
|
@@ -8,11 +8,10 @@ const viewer = require('./viewer');
|
|
|
8
8
|
|
|
9
9
|
class BundleAnalyzerPlugin {
|
|
10
10
|
|
|
11
|
-
constructor(opts) {
|
|
11
|
+
constructor(opts = {}) {
|
|
12
12
|
this.opts = {
|
|
13
13
|
analyzerMode: 'server',
|
|
14
14
|
analyzerHost: '127.0.0.1',
|
|
15
|
-
analyzerPort: 8888,
|
|
16
15
|
reportFilename: 'report.html',
|
|
17
16
|
defaultSizes: 'parsed',
|
|
18
17
|
openAnalyzer: true,
|
|
@@ -23,7 +22,8 @@ class BundleAnalyzerPlugin {
|
|
|
23
22
|
logLevel: 'info',
|
|
24
23
|
// deprecated
|
|
25
24
|
startAnalyzer: true,
|
|
26
|
-
...opts
|
|
25
|
+
...opts,
|
|
26
|
+
analyzerPort: 'analyzerPort' in opts ? (opts.analyzerPort === 'auto' ? 0 : opts.analyzerPort) : 8888
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
this.server = null;
|
|
@@ -35,12 +35,11 @@ class BundleAnalyzerPlugin {
|
|
|
35
35
|
|
|
36
36
|
const done = (stats, callback) => {
|
|
37
37
|
callback = callback || (() => {});
|
|
38
|
-
stats = stats.toJson(this.opts.statsOptions);
|
|
39
38
|
|
|
40
39
|
const actions = [];
|
|
41
40
|
|
|
42
41
|
if (this.opts.generateStatsFile) {
|
|
43
|
-
actions.push(() => this.generateStatsFile(stats));
|
|
42
|
+
actions.push(() => this.generateStatsFile(stats.toJson(this.opts.statsOptions)));
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
// Handling deprecated `startAnalyzer` flag
|
|
@@ -49,9 +48,9 @@ class BundleAnalyzerPlugin {
|
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
if (this.opts.analyzerMode === 'server') {
|
|
52
|
-
actions.push(() => this.startAnalyzerServer(stats));
|
|
51
|
+
actions.push(() => this.startAnalyzerServer(stats.toJson()));
|
|
53
52
|
} else if (this.opts.analyzerMode === 'static') {
|
|
54
|
-
actions.push(() => this.generateStaticReport(stats));
|
|
53
|
+
actions.push(() => this.generateStaticReport(stats.toJson()));
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
if (actions.length) {
|
|
@@ -128,7 +127,16 @@ class BundleAnalyzerPlugin {
|
|
|
128
127
|
}
|
|
129
128
|
|
|
130
129
|
getBundleDirFromCompiler() {
|
|
131
|
-
|
|
130
|
+
switch (this.compiler.outputFileSystem.constructor.name) {
|
|
131
|
+
case 'MemoryFileSystem':
|
|
132
|
+
return null;
|
|
133
|
+
// Detect AsyncMFS used by Nuxt 2.5 that replaces webpack's MFS during development
|
|
134
|
+
// Related: #274
|
|
135
|
+
case 'AsyncMFS':
|
|
136
|
+
return null;
|
|
137
|
+
default:
|
|
138
|
+
return this.compiler.outputPath;
|
|
139
|
+
}
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
}
|
package/src/bin/analyzer.js
CHANGED
|
@@ -32,14 +32,15 @@ const program = commander
|
|
|
32
32
|
'server'
|
|
33
33
|
)
|
|
34
34
|
.option(
|
|
35
|
-
|
|
35
|
+
// Had to make `host` parameter optional in order to let `-h` flag output help message
|
|
36
|
+
// Fixes https://github.com/webpack-contrib/webpack-bundle-analyzer/issues/239
|
|
37
|
+
'-h, --host [host]',
|
|
36
38
|
'Host that will be used in `server` mode to start HTTP server.',
|
|
37
39
|
'127.0.0.1'
|
|
38
40
|
)
|
|
39
41
|
.option(
|
|
40
42
|
'-p, --port <n>',
|
|
41
43
|
'Port that will be used in `server` mode to start HTTP server.',
|
|
42
|
-
Number,
|
|
43
44
|
8888
|
|
44
45
|
)
|
|
45
46
|
.option(
|
|
@@ -86,8 +87,12 @@ const logger = new Logger(logLevel);
|
|
|
86
87
|
|
|
87
88
|
if (!bundleStatsFile) showHelp('Provide path to Webpack Stats file as first argument');
|
|
88
89
|
if (mode !== 'server' && mode !== 'static') showHelp('Invalid mode. Should be either `server` or `static`.');
|
|
89
|
-
if (mode === 'server'
|
|
90
|
-
if (
|
|
90
|
+
if (mode === 'server') {
|
|
91
|
+
if (!host) showHelp('Invalid host name');
|
|
92
|
+
|
|
93
|
+
port = port === 'auto' ? 0 : Number(port);
|
|
94
|
+
if (isNaN(port)) showHelp('Invalid port. Should be a number or `auto`');
|
|
95
|
+
}
|
|
91
96
|
if (!SIZES.has(defaultSizes)) showHelp(`Invalid default sizes option. Possible values are: ${[...SIZES].join(', ')}`);
|
|
92
97
|
|
|
93
98
|
bundleStatsFile = resolve(bundleStatsFile);
|
|
@@ -125,7 +130,7 @@ if (mode === 'server') {
|
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
function showHelp(error) {
|
|
128
|
-
if (error) console.log(`\n ${magenta(error)}`);
|
|
133
|
+
if (error) console.log(`\n ${magenta(error)}\n`);
|
|
129
134
|
program.outputHelp();
|
|
130
135
|
process.exit(1);
|
|
131
136
|
}
|
package/src/viewer.js
CHANGED
|
@@ -14,6 +14,7 @@ const Logger = require('./Logger');
|
|
|
14
14
|
const analyzer = require('./analyzer');
|
|
15
15
|
|
|
16
16
|
const projectRoot = path.resolve(__dirname, '..');
|
|
17
|
+
const assetsRoot = path.join(projectRoot, 'public');
|
|
17
18
|
|
|
18
19
|
module.exports = {
|
|
19
20
|
startServer,
|
|
@@ -51,9 +52,11 @@ async function startServer(bundleStats, opts) {
|
|
|
51
52
|
app.use('/', (req, res) => {
|
|
52
53
|
res.render('viewer', {
|
|
53
54
|
mode: 'server',
|
|
54
|
-
get chartData() { return
|
|
55
|
-
defaultSizes
|
|
56
|
-
enableWebSocket: true
|
|
55
|
+
get chartData() { return chartData },
|
|
56
|
+
defaultSizes,
|
|
57
|
+
enableWebSocket: true,
|
|
58
|
+
// Helpers
|
|
59
|
+
escapeJson
|
|
57
60
|
});
|
|
58
61
|
});
|
|
59
62
|
|
|
@@ -130,10 +133,12 @@ async function generateReport(bundleStats, opts) {
|
|
|
130
133
|
`${projectRoot}/views/viewer.ejs`,
|
|
131
134
|
{
|
|
132
135
|
mode: 'static',
|
|
133
|
-
chartData
|
|
136
|
+
chartData,
|
|
137
|
+
defaultSizes,
|
|
138
|
+
enableWebSocket: false,
|
|
139
|
+
// Helpers
|
|
134
140
|
assetContent: getAssetContent,
|
|
135
|
-
|
|
136
|
-
enableWebSocket: false
|
|
141
|
+
escapeJson
|
|
137
142
|
},
|
|
138
143
|
(err, reportHtml) => {
|
|
139
144
|
try {
|
|
@@ -165,7 +170,20 @@ async function generateReport(bundleStats, opts) {
|
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
function getAssetContent(filename) {
|
|
168
|
-
|
|
173
|
+
const assetPath = path.join(assetsRoot, filename);
|
|
174
|
+
|
|
175
|
+
if (!assetPath.startsWith(assetsRoot)) {
|
|
176
|
+
throw new Error(`"${filename}" is outside of the assets root`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return fs.readFileSync(assetPath, 'utf8');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Escapes `<` characters in JSON to safely use it in `<script>` tag.
|
|
184
|
+
*/
|
|
185
|
+
function escapeJson(json) {
|
|
186
|
+
return JSON.stringify(json).replace(/</gu, '\\u003c');
|
|
169
187
|
}
|
|
170
188
|
|
|
171
189
|
function getChartData(analyzerOpts, ...args) {
|
package/views/script.ejs
CHANGED
package/views/viewer.ejs
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
<body>
|
|
12
12
|
<div id="app"></div>
|
|
13
13
|
<script>
|
|
14
|
-
window.chartData = <%- chartData %>;
|
|
15
|
-
window.defaultSizes = <%- defaultSizes %>;
|
|
16
|
-
window.enableWebSocket = <%- enableWebSocket %>;
|
|
14
|
+
window.chartData = <%- escapeJson(chartData) %>;
|
|
15
|
+
window.defaultSizes = <%- escapeJson(defaultSizes) %>;
|
|
16
|
+
window.enableWebSocket = <%- escapeJson(enableWebSocket) %>;
|
|
17
17
|
</script>
|
|
18
18
|
</body>
|
|
19
19
|
</html>
|