webpack-bundle-analyzer 3.1.0 → 3.3.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/src/analyzer.js CHANGED
@@ -9,7 +9,8 @@ const Folder = require('./tree/Folder').default;
9
9
  const {parseBundle} = require('./parseUtils');
10
10
  const {createAssetsFilter} = require('./utils');
11
11
 
12
- const FILENAME_QUERY_REGEXP = /\?.*$/;
12
+ const FILENAME_QUERY_REGEXP = /\?.*$/u;
13
+ const FILENAME_EXTENSIONS = /\.(js|mjs)$/iu;
13
14
 
14
15
  module.exports = {
15
16
  getViewerData,
@@ -29,13 +30,13 @@ function getViewerData(bundleStats, bundleDir, opts) {
29
30
  bundleStats = bundleStats.children[0];
30
31
  }
31
32
 
32
- // Picking only `*.js` assets from bundle that has non-empty `chunks` array
33
+ // Picking only `*.js or *.mjs` assets from bundle that has non-empty `chunks` array
33
34
  bundleStats.assets = _.filter(bundleStats.assets, asset => {
34
35
  // Removing query part from filename (yes, somebody uses it for some reason and Webpack supports it)
35
36
  // See #22
36
37
  asset.name = asset.name.replace(FILENAME_QUERY_REGEXP, '');
37
38
 
38
- return _.endsWith(asset.name, '.js') && !_.isEmpty(asset.chunks) && isAssetIncluded(asset.name);
39
+ return FILENAME_EXTENSIONS.test(asset.name) && !_.isEmpty(asset.chunks) && isAssetIncluded(asset.name);
39
40
  });
40
41
 
41
42
  // Trying to parse bundle assets and get real module sizes if `bundleDir` is provided
@@ -93,6 +94,7 @@ function getViewerData(bundleStats, bundleDir, opts) {
93
94
  return _.transform(assets, (result, asset, filename) => {
94
95
  result.push({
95
96
  label: filename,
97
+ isAsset: true,
96
98
  // Not using `asset.size` here provided by Webpack because it can be very confusing when `UglifyJsPlugin` is used.
97
99
  // In this case all module sizes from stats file will represent unminified module sizes, but `asset.size` will
98
100
  // be the size of minified bundle.
@@ -32,7 +32,9 @@ const program = commander
32
32
  'server'
33
33
  )
34
34
  .option(
35
- '-h, --host <host>',
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
  )
@@ -125,7 +127,7 @@ if (mode === 'server') {
125
127
  }
126
128
 
127
129
  function showHelp(error) {
128
- if (error) console.log(`\n ${magenta(error)}`);
130
+ if (error) console.log(`\n ${magenta(error)}\n`);
129
131
  program.outputHelp();
130
132
  process.exit(1);
131
133
  }
package/src/tree/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import _ from 'lodash';
2
2
 
3
- const MULTI_MODULE_REGEXP = /^multi /;
3
+ const MULTI_MODULE_REGEXP = /^multi /u;
4
4
 
5
5
  export function getModulePathParts(moduleData) {
6
6
  if (MULTI_MODULE_REGEXP.test(moduleData.identifier)) {
package/src/utils.js CHANGED
@@ -9,7 +9,7 @@ function createAssetsFilter(excludePatterns) {
9
9
  .compact()
10
10
  .map(pattern => {
11
11
  if (typeof pattern === 'string') {
12
- pattern = new RegExp(pattern);
12
+ pattern = new RegExp(pattern, 'u');
13
13
  }
14
14
 
15
15
  if (_.isRegExp(pattern)) {
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 JSON.stringify(chartData) },
55
- defaultSizes: JSON.stringify(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: JSON.stringify(chartData),
136
+ chartData,
137
+ defaultSizes,
138
+ enableWebSocket: false,
139
+ // Helpers
134
140
  assetContent: getAssetContent,
135
- defaultSizes: JSON.stringify(defaultSizes),
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
- return fs.readFileSync(`${projectRoot}/public/${filename}`, 'utf8');
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
@@ -4,5 +4,5 @@
4
4
  <%- assetContent(filename) %>
5
5
  </script>
6
6
  <% } else { %>
7
- <script src="/<%= filename %>"></script>
7
+ <script src="<%= filename %>"></script>
8
8
  <% } %>
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>