webpack-bundle-analyzer 3.9.0 → 4.2.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.
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+
3
+ /* eslint-disable max-len */
4
+ const path = require('path');
5
+
6
+ const fs = require('fs');
7
+
8
+ const _ = require('lodash');
9
+
10
+ const projectRoot = path.resolve(__dirname, '..');
11
+ const assetsRoot = path.join(projectRoot, 'public');
12
+ exports.renderViewer = renderViewer;
13
+ /**
14
+ * Escapes `<` characters in JSON to safely use it in `<script>` tag.
15
+ */
16
+
17
+ function escapeJson(json) {
18
+ return JSON.stringify(json).replace(/</gu, '\\u003c');
19
+ }
20
+
21
+ function getAssetContent(filename) {
22
+ const assetPath = path.join(assetsRoot, filename);
23
+
24
+ if (!assetPath.startsWith(assetsRoot)) {
25
+ throw new Error(`"${filename}" is outside of the assets root`);
26
+ }
27
+
28
+ return fs.readFileSync(assetPath, 'utf8');
29
+ }
30
+
31
+ function html(strings, ...values) {
32
+ return strings.map((string, index) => `${string}${values[index] || ''}`).join('');
33
+ }
34
+
35
+ function getScript(filename, mode) {
36
+ if (mode === 'static') {
37
+ return `<!-- ${_.escape(filename)} -->
38
+ <script>${getAssetContent(filename)}</script>`;
39
+ } else {
40
+ return `<script src="${_.escape(filename)}"></script>`;
41
+ }
42
+ }
43
+
44
+ function renderViewer({
45
+ title,
46
+ enableWebSocket,
47
+ chartData,
48
+ defaultSizes,
49
+ mode
50
+ } = {}) {
51
+ return html`<!DOCTYPE html>
52
+ <html>
53
+ <head>
54
+ <meta charset="UTF-8"/>
55
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
56
+ <title>${_.escape(title)}</title>
57
+ <link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
58
+
59
+ <script>
60
+ window.enableWebSocket = ${escapeJson(enableWebSocket)};
61
+ </script>
62
+ ${getScript('viewer.js', mode)}
63
+ </head>
64
+
65
+ <body>
66
+ <div id="app"></div>
67
+ <script>
68
+ window.chartData = ${escapeJson(chartData)};
69
+ window.defaultSizes = ${escapeJson(defaultSizes)};
70
+ </script>
71
+ </body>
72
+ </html>`;
73
+ }
@@ -69,8 +69,7 @@ class BaseFolder extends _Node.default {
69
69
 
70
70
  walk(walker, state = {}, deep = true) {
71
71
  let stopped = false;
72
-
73
- _lodash.default.each(this.children, child => {
72
+ Object.values(this.children).forEach(child => {
74
73
  if (deep && child.walk) {
75
74
  state = child.walk(walker, state, stop);
76
75
  } else {
@@ -79,7 +78,6 @@ class BaseFolder extends _Node.default {
79
78
 
80
79
  if (stopped) return false;
81
80
  });
82
-
83
81
  return state;
84
82
 
85
83
  function stop(finalState) {
@@ -17,12 +17,6 @@ var _utils = require("./utils");
17
17
 
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
 
20
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
21
-
22
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
23
-
24
- 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; }
25
-
26
20
  class ConcatenatedModule extends _Module.default {
27
21
  constructor(name, data, parent) {
28
22
  super(name, data, parent);
@@ -32,7 +26,7 @@ class ConcatenatedModule extends _Module.default {
32
26
  }
33
27
 
34
28
  fillContentModules() {
35
- _lodash.default.each(this.data.modules, moduleData => this.addContentModule(moduleData));
29
+ this.data.modules.forEach(moduleData => this.addContentModule(moduleData));
36
30
  }
37
31
 
38
32
  addContentModule(moduleData) {
@@ -44,8 +38,7 @@ class ConcatenatedModule extends _Module.default {
44
38
 
45
39
  const [folders, fileName] = [pathParts.slice(0, -1), _lodash.default.last(pathParts)];
46
40
  let currentFolder = this;
47
-
48
- _lodash.default.each(folders, folderName => {
41
+ folders.forEach(folderName => {
49
42
  let childFolder = currentFolder.getChild(folderName);
50
43
 
51
44
  if (!childFolder) {
@@ -54,7 +47,6 @@ class ConcatenatedModule extends _Module.default {
54
47
 
55
48
  currentFolder = childFolder;
56
49
  });
57
-
58
50
  const module = new _ContentModule.default(fileName, moduleData, this);
59
51
  currentFolder.addChildModule(module);
60
52
  }
@@ -79,10 +71,10 @@ class ConcatenatedModule extends _Module.default {
79
71
  }
80
72
 
81
73
  toChartData() {
82
- return _objectSpread({}, super.toChartData(), {
74
+ return { ...super.toChartData(),
83
75
  concatenated: true,
84
76
  groups: _lodash.default.invokeMap(this.children, 'toChartData')
85
- });
77
+ };
86
78
  }
87
79
 
88
80
  }
@@ -9,12 +9,6 @@ var _BaseFolder = _interopRequireDefault(require("./BaseFolder"));
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
13
-
14
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
15
-
16
- 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; }
17
-
18
12
  class ContentFolder extends _BaseFolder.default {
19
13
  constructor(name, ownerModule, parent) {
20
14
  super(name, parent);
@@ -38,11 +32,11 @@ class ContentFolder extends _BaseFolder.default {
38
32
  }
39
33
 
40
34
  toChartData() {
41
- return _objectSpread({}, super.toChartData(), {
35
+ return { ...super.toChartData(),
42
36
  parsedSize: this.parsedSize,
43
37
  gzipSize: this.gzipSize,
44
38
  inaccurateSizes: true
45
- });
39
+ };
46
40
  }
47
41
 
48
42
  }
@@ -9,12 +9,6 @@ var _Module = _interopRequireDefault(require("./Module"));
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
13
-
14
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
15
-
16
- 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; }
17
-
18
12
  class ContentModule extends _Module.default {
19
13
  constructor(name, data, ownerModule, parent) {
20
14
  super(name, data, parent);
@@ -38,9 +32,9 @@ class ContentModule extends _Module.default {
38
32
  }
39
33
 
40
34
  toChartData() {
41
- return _objectSpread({}, super.toChartData(), {
35
+ return { ...super.toChartData(),
42
36
  inaccurateSizes: true
43
- });
37
+ };
44
38
  }
45
39
 
46
40
  }
@@ -19,12 +19,6 @@ var _utils = require("./utils");
19
19
 
20
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
21
 
22
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
23
-
24
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
25
-
26
- 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; }
27
-
28
22
  class Folder extends _BaseFolder.default {
29
23
  get parsedSize() {
30
24
  return this.src ? this.src.length : 0;
@@ -47,8 +41,7 @@ class Folder extends _BaseFolder.default {
47
41
 
48
42
  const [folders, fileName] = [pathParts.slice(0, -1), _lodash.default.last(pathParts)];
49
43
  let currentFolder = this;
50
-
51
- _lodash.default.each(folders, folderName => {
44
+ folders.forEach(folderName => {
52
45
  let childNode = currentFolder.getChild(folderName);
53
46
 
54
47
  if ( // Folder is not created yet
@@ -62,17 +55,16 @@ class Folder extends _BaseFolder.default {
62
55
 
63
56
  currentFolder = childNode;
64
57
  });
65
-
66
58
  const ModuleConstructor = moduleData.modules ? _ConcatenatedModule.default : _Module.default;
67
59
  const module = new ModuleConstructor(fileName, moduleData, this);
68
60
  currentFolder.addChildModule(module);
69
61
  }
70
62
 
71
63
  toChartData() {
72
- return _objectSpread({}, super.toChartData(), {
64
+ return { ...super.toChartData(),
73
65
  parsedSize: this.parsedSize,
74
66
  gzipSize: this.gzipSize
75
- });
67
+ };
76
68
  }
77
69
 
78
70
  }
package/lib/utils.js CHANGED
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
2
 
3
3
  const {
4
- inspect
4
+ inspect,
5
+ types
5
6
  } = require('util');
6
7
 
7
8
  const _ = require('lodash');
8
9
 
10
+ const opener = require('opener');
11
+
9
12
  const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
10
13
  exports.createAssetsFilter = createAssetsFilter;
11
14
 
@@ -15,11 +18,11 @@ function createAssetsFilter(excludePatterns) {
15
18
  pattern = new RegExp(pattern, 'u');
16
19
  }
17
20
 
18
- if (_.isRegExp(pattern)) {
21
+ if (types.isRegExp(pattern)) {
19
22
  return asset => pattern.test(asset);
20
23
  }
21
24
 
22
- if (!_.isFunction(pattern)) {
25
+ if (typeof pattern !== 'function') {
23
26
  throw new TypeError(`Pattern should be either string, RegExp or a function, but "${inspect(pattern, {
24
27
  depth: 0
25
28
  })}" got.`);
@@ -29,7 +32,7 @@ function createAssetsFilter(excludePatterns) {
29
32
  }).value();
30
33
 
31
34
  if (excludeFunctions.length) {
32
- return asset => _.every(excludeFunctions, fn => fn(asset) !== true);
35
+ return asset => excludeFunctions.every(fn => fn(asset) !== true);
33
36
  } else {
34
37
  return () => true;
35
38
  }
@@ -49,4 +52,16 @@ exports.defaultTitle = function () {
49
52
  const minute = `0${time.getMinutes()}`.slice(-2);
50
53
  const currentTime = `${day} ${month} ${year} at ${hour}:${minute}`;
51
54
  return `${process.env.npm_package_name || 'Webpack Bundle Analyzer'} [${currentTime}]`;
55
+ };
56
+ /**
57
+ * Calls opener on a URI, but silently try / catches it.
58
+ */
59
+
60
+
61
+ exports.open = function (uri, logger) {
62
+ try {
63
+ opener(uri);
64
+ } catch (err) {
65
+ logger.debug(`Opener failed to open "${uri}":\n${err}`);
66
+ }
52
67
  };
package/lib/viewer.js CHANGED
@@ -1,9 +1,5 @@
1
1
  "use strict";
2
2
 
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
-
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
-
7
3
  const path = require('path');
8
4
 
9
5
  const fs = require('fs');
@@ -16,12 +12,6 @@ const _ = require('lodash');
16
12
 
17
13
  const express = require('express');
18
14
 
19
- const ejs = require('ejs');
20
-
21
- const opener = require('opener');
22
-
23
- const mkdir = require('mkdirp');
24
-
25
15
  const {
26
16
  bold
27
17
  } = require('chalk');
@@ -30,8 +20,15 @@ const Logger = require('./Logger');
30
20
 
31
21
  const analyzer = require('./analyzer');
32
22
 
23
+ const {
24
+ open
25
+ } = require('./utils');
26
+
27
+ const {
28
+ renderViewer
29
+ } = require('./template');
30
+
33
31
  const projectRoot = path.resolve(__dirname, '..');
34
- const assetsRoot = path.join(projectRoot, 'public');
35
32
 
36
33
  function resolveTitle(reportTitle) {
37
34
  if (typeof reportTitle === 'function') {
@@ -49,192 +46,132 @@ module.exports = {
49
46
  start: startServer
50
47
  };
51
48
 
52
- function startServer(_x, _x2) {
53
- return _startServer.apply(this, arguments);
54
- }
55
-
56
- function _startServer() {
57
- _startServer = _asyncToGenerator(function* (bundleStats, opts) {
58
- const {
59
- port = 8888,
60
- host = '127.0.0.1',
61
- openBrowser = true,
62
- bundleDir = null,
63
- logger = new Logger(),
64
- defaultSizes = 'parsed',
65
- excludeAssets = null,
66
- reportTitle
67
- } = opts || {};
68
- const analyzerOpts = {
69
- logger,
70
- excludeAssets
71
- };
72
- let chartData = getChartData(analyzerOpts, bundleStats, bundleDir);
73
- if (!chartData) return;
74
- const app = express(); // Explicitly using our `ejs` dependency to render templates
75
- // Fixes #17
76
-
77
- app.engine('ejs', require('ejs').renderFile);
78
- app.set('view engine', 'ejs');
79
- app.set('views', `${projectRoot}/views`);
80
- app.use(express.static(`${projectRoot}/public`));
81
- app.use('/', (req, res) => {
82
- res.render('viewer', {
83
- mode: 'server',
84
- title: resolveTitle(reportTitle),
85
-
86
- get chartData() {
87
- return chartData;
88
- },
89
-
90
- defaultSizes,
91
- enableWebSocket: true,
92
- // Helpers
93
- escapeJson
94
- });
95
- });
96
- const server = http.createServer(app);
97
- yield new Promise(resolve => {
98
- server.listen(port, host, () => {
99
- resolve();
100
- const url = `http://${host}:${server.address().port}`;
101
- logger.info(`${bold('Webpack Bundle Analyzer')} is started at ${bold(url)}\n` + `Use ${bold('Ctrl+C')} to close it`);
102
-
103
- if (openBrowser) {
104
- opener(url);
105
- }
106
- });
49
+ async function startServer(bundleStats, opts) {
50
+ const {
51
+ port = 8888,
52
+ host = '127.0.0.1',
53
+ openBrowser = true,
54
+ bundleDir = null,
55
+ logger = new Logger(),
56
+ defaultSizes = 'parsed',
57
+ excludeAssets = null,
58
+ reportTitle
59
+ } = opts || {};
60
+ const analyzerOpts = {
61
+ logger,
62
+ excludeAssets
63
+ };
64
+ let chartData = getChartData(analyzerOpts, bundleStats, bundleDir);
65
+ if (!chartData) return;
66
+ const app = express();
67
+ app.use(express.static(`${projectRoot}/public`));
68
+ app.get('/', (req, res) => {
69
+ res.writeHead(200, {
70
+ 'Content-Type': 'text/html'
107
71
  });
108
- const wss = new WebSocket.Server({
109
- server
72
+ const html = renderViewer({
73
+ mode: 'server',
74
+ title: resolveTitle(reportTitle),
75
+ chartData,
76
+ defaultSizes,
77
+ enableWebSocket: true
110
78
  });
111
- wss.on('connection', ws => {
112
- ws.on('error', err => {
113
- // Ignore network errors like `ECONNRESET`, `EPIPE`, etc.
114
- if (err.errno) return;
115
- logger.info(err.message);
116
- });
79
+ return res.end(html);
80
+ });
81
+ const server = http.createServer(app);
82
+ await new Promise(resolve => {
83
+ server.listen(port, host, () => {
84
+ resolve();
85
+ const url = `http://${host}:${server.address().port}`;
86
+ logger.info(`${bold('Webpack Bundle Analyzer')} is started at ${bold(url)}\n` + `Use ${bold('Ctrl+C')} to close it`);
87
+
88
+ if (openBrowser) {
89
+ open(url, logger);
90
+ }
117
91
  });
118
- return {
119
- ws: wss,
120
- http: server,
121
- updateChartData
122
- };
123
-
124
- function updateChartData(bundleStats) {
125
- const newChartData = getChartData(analyzerOpts, bundleStats, bundleDir);
126
- if (!newChartData) return;
127
- chartData = newChartData;
128
- wss.clients.forEach(client => {
129
- if (client.readyState === WebSocket.OPEN) {
130
- client.send(JSON.stringify({
131
- event: 'chartDataUpdated',
132
- data: newChartData
133
- }));
134
- }
135
- });
136
- }
137
92
  });
138
- return _startServer.apply(this, arguments);
139
- }
140
-
141
- function generateReport(_x3, _x4) {
142
- return _generateReport.apply(this, arguments);
143
- }
144
-
145
- function _generateReport() {
146
- _generateReport = _asyncToGenerator(function* (bundleStats, opts) {
147
- const {
148
- openBrowser = true,
149
- reportFilename,
150
- reportTitle,
151
- bundleDir = null,
152
- logger = new Logger(),
153
- defaultSizes = 'parsed',
154
- excludeAssets = null
155
- } = opts || {};
156
- const chartData = getChartData({
157
- logger,
158
- excludeAssets
159
- }, bundleStats, bundleDir);
160
- if (!chartData) return;
161
- yield new Promise((resolve, reject) => {
162
- ejs.renderFile(`${projectRoot}/views/viewer.ejs`, {
163
- mode: 'static',
164
- title: resolveTitle(reportTitle),
165
- chartData,
166
- defaultSizes,
167
- enableWebSocket: false,
168
- // Helpers
169
- assetContent: getAssetContent,
170
- escapeJson
171
- }, (err, reportHtml) => {
172
- try {
173
- if (err) {
174
- logger.error(err);
175
- reject(err);
176
- return;
177
- }
178
-
179
- const reportFilepath = path.resolve(bundleDir || process.cwd(), reportFilename);
180
- mkdir.sync(path.dirname(reportFilepath));
181
- fs.writeFileSync(reportFilepath, reportHtml);
182
- logger.info(`${bold('Webpack Bundle Analyzer')} saved report to ${bold(reportFilepath)}`);
183
-
184
- if (openBrowser) {
185
- opener(`file://${reportFilepath}`);
186
- }
187
-
188
- resolve();
189
- } catch (e) {
190
- reject(e);
191
- }
192
- });
93
+ const wss = new WebSocket.Server({
94
+ server
95
+ });
96
+ wss.on('connection', ws => {
97
+ ws.on('error', err => {
98
+ // Ignore network errors like `ECONNRESET`, `EPIPE`, etc.
99
+ if (err.errno) return;
100
+ logger.info(err.message);
193
101
  });
194
102
  });
195
- return _generateReport.apply(this, arguments);
196
- }
197
-
198
- function generateJSONReport(_x5, _x6) {
199
- return _generateJSONReport.apply(this, arguments);
103
+ return {
104
+ ws: wss,
105
+ http: server,
106
+ updateChartData
107
+ };
108
+
109
+ function updateChartData(bundleStats) {
110
+ const newChartData = getChartData(analyzerOpts, bundleStats, bundleDir);
111
+ if (!newChartData) return;
112
+ chartData = newChartData;
113
+ wss.clients.forEach(client => {
114
+ if (client.readyState === WebSocket.OPEN) {
115
+ client.send(JSON.stringify({
116
+ event: 'chartDataUpdated',
117
+ data: newChartData
118
+ }));
119
+ }
120
+ });
121
+ }
200
122
  }
201
123
 
202
- function _generateJSONReport() {
203
- _generateJSONReport = _asyncToGenerator(function* (bundleStats, opts) {
204
- const {
205
- reportFilename,
206
- bundleDir = null,
207
- logger = new Logger(),
208
- excludeAssets = null
209
- } = opts || {};
210
- const chartData = getChartData({
211
- logger,
212
- excludeAssets
213
- }, bundleStats, bundleDir);
214
- if (!chartData) return;
215
- mkdir.sync(path.dirname(reportFilename));
216
- fs.writeFileSync(reportFilename, JSON.stringify(chartData));
217
- logger.info(`${bold('Webpack Bundle Analyzer')} saved JSON report to ${bold(reportFilename)}`);
124
+ async function generateReport(bundleStats, opts) {
125
+ const {
126
+ openBrowser = true,
127
+ reportFilename,
128
+ reportTitle,
129
+ bundleDir = null,
130
+ logger = new Logger(),
131
+ defaultSizes = 'parsed',
132
+ excludeAssets = null
133
+ } = opts || {};
134
+ const chartData = getChartData({
135
+ logger,
136
+ excludeAssets
137
+ }, bundleStats, bundleDir);
138
+ if (!chartData) return;
139
+ const reportHtml = renderViewer({
140
+ mode: 'static',
141
+ title: resolveTitle(reportTitle),
142
+ chartData,
143
+ defaultSizes,
144
+ enableWebSocket: false
218
145
  });
219
- return _generateJSONReport.apply(this, arguments);
220
- }
221
-
222
- function getAssetContent(filename) {
223
- const assetPath = path.join(assetsRoot, filename);
146
+ const reportFilepath = path.resolve(bundleDir || process.cwd(), reportFilename);
147
+ fs.mkdirSync(path.dirname(reportFilepath), {
148
+ recursive: true
149
+ });
150
+ fs.writeFileSync(reportFilepath, reportHtml);
151
+ logger.info(`${bold('Webpack Bundle Analyzer')} saved report to ${bold(reportFilepath)}`);
224
152
 
225
- if (!assetPath.startsWith(assetsRoot)) {
226
- throw new Error(`"${filename}" is outside of the assets root`);
153
+ if (openBrowser) {
154
+ open(`file://${reportFilepath}`, logger);
227
155
  }
228
-
229
- return fs.readFileSync(assetPath, 'utf8');
230
156
  }
231
- /**
232
- * Escapes `<` characters in JSON to safely use it in `<script>` tag.
233
- */
234
-
235
157
 
236
- function escapeJson(json) {
237
- return JSON.stringify(json).replace(/</gu, '\\u003c');
158
+ async function generateJSONReport(bundleStats, opts) {
159
+ const {
160
+ reportFilename,
161
+ bundleDir = null,
162
+ logger = new Logger(),
163
+ excludeAssets = null
164
+ } = opts || {};
165
+ const chartData = getChartData({
166
+ logger,
167
+ excludeAssets
168
+ }, bundleStats, bundleDir);
169
+ if (!chartData) return;
170
+ await fs.promises.mkdir(path.dirname(reportFilename), {
171
+ recursive: true
172
+ });
173
+ await fs.promises.writeFile(reportFilename, JSON.stringify(chartData));
174
+ logger.info(`${bold('Webpack Bundle Analyzer')} saved JSON report to ${bold(reportFilename)}`);
238
175
  }
239
176
 
240
177
  function getChartData(analyzerOpts, ...args) {