| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 | "use strict";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); } }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); }); }; }const path = require('path');const fs = require('fs');const http = require('http');const WebSocket = require('ws');const _ = require('lodash');const express = require('express');const ejs = require('ejs');const opener = require('opener');const mkdir = require('mkdirp');const {  bold} = require('chalk');const Logger = require('./Logger');const analyzer = require('./analyzer');const projectRoot = path.resolve(__dirname, '..');const assetsRoot = path.join(projectRoot, 'public');function resolveTitle(reportTitle) {  if (typeof reportTitle === 'function') {    return reportTitle();  } else {    return reportTitle;  }}module.exports = {  startServer,  generateReport,  generateJSONReport,  // deprecated  start: startServer};function startServer(_x, _x2) {  return _startServer.apply(this, arguments);}function _startServer() {  _startServer = _asyncToGenerator(function* (bundleStats, opts) {    const {      port = 8888,      host = '127.0.0.1',      openBrowser = true,      bundleDir = null,      logger = new Logger(),      defaultSizes = 'parsed',      excludeAssets = null,      reportTitle    } = opts || {};    const analyzerOpts = {      logger,      excludeAssets    };    let chartData = getChartData(analyzerOpts, bundleStats, bundleDir);    if (!chartData) return;    const app = express(); // Explicitly using our `ejs` dependency to render templates    // Fixes #17    app.engine('ejs', require('ejs').renderFile);    app.set('view engine', 'ejs');    app.set('views', `${projectRoot}/views`);    app.use(express.static(`${projectRoot}/public`));    app.use('/', (req, res) => {      res.render('viewer', {        mode: 'server',        title: resolveTitle(reportTitle),        get chartData() {          return chartData;        },        defaultSizes,        enableWebSocket: true,        // Helpers        escapeJson      });    });    const server = http.createServer(app);    yield new Promise(resolve => {      server.listen(port, host, () => {        resolve();        const url = `http://${host}:${server.address().port}`;        logger.info(`${bold('Webpack Bundle Analyzer')} is started at ${bold(url)}\n` + `Use ${bold('Ctrl+C')} to close it`);        if (openBrowser) {          opener(url);        }      });    });    const wss = new WebSocket.Server({      server    });    wss.on('connection', ws => {      ws.on('error', err => {        // Ignore network errors like `ECONNRESET`, `EPIPE`, etc.        if (err.errno) return;        logger.info(err.message);      });    });    return {      ws: wss,      http: server,      updateChartData    };    function updateChartData(bundleStats) {      const newChartData = getChartData(analyzerOpts, bundleStats, bundleDir);      if (!newChartData) return;      chartData = newChartData;      wss.clients.forEach(client => {        if (client.readyState === WebSocket.OPEN) {          client.send(JSON.stringify({            event: 'chartDataUpdated',            data: newChartData          }));        }      });    }  });  return _startServer.apply(this, arguments);}function generateReport(_x3, _x4) {  return _generateReport.apply(this, arguments);}function _generateReport() {  _generateReport = _asyncToGenerator(function* (bundleStats, opts) {    const {      openBrowser = true,      reportFilename,      reportTitle,      bundleDir = null,      logger = new Logger(),      defaultSizes = 'parsed',      excludeAssets = null    } = opts || {};    const chartData = getChartData({      logger,      excludeAssets    }, bundleStats, bundleDir);    if (!chartData) return;    yield new Promise((resolve, reject) => {      ejs.renderFile(`${projectRoot}/views/viewer.ejs`, {        mode: 'static',        title: resolveTitle(reportTitle),        chartData,        defaultSizes,        enableWebSocket: false,        // Helpers        assetContent: getAssetContent,        escapeJson      }, (err, reportHtml) => {        try {          if (err) {            logger.error(err);            reject(err);            return;          }          const reportFilepath = path.resolve(bundleDir || process.cwd(), reportFilename);          mkdir.sync(path.dirname(reportFilepath));          fs.writeFileSync(reportFilepath, reportHtml);          logger.info(`${bold('Webpack Bundle Analyzer')} saved report to ${bold(reportFilepath)}`);          if (openBrowser) {            opener(`file://${reportFilepath}`);          }          resolve();        } catch (e) {          reject(e);        }      });    });  });  return _generateReport.apply(this, arguments);}function generateJSONReport(_x5, _x6) {  return _generateJSONReport.apply(this, arguments);}function _generateJSONReport() {  _generateJSONReport = _asyncToGenerator(function* (bundleStats, opts) {    const {      reportFilename,      bundleDir = null,      logger = new Logger(),      excludeAssets = null    } = opts || {};    const chartData = getChartData({      logger,      excludeAssets    }, bundleStats, bundleDir);    if (!chartData) return;    mkdir.sync(path.dirname(reportFilename));    fs.writeFileSync(reportFilename, JSON.stringify(chartData));    logger.info(`${bold('Webpack Bundle Analyzer')} saved JSON report to ${bold(reportFilename)}`);  });  return _generateJSONReport.apply(this, arguments);}function getAssetContent(filename) {  const assetPath = path.join(assetsRoot, filename);  if (!assetPath.startsWith(assetsRoot)) {    throw new Error(`"${filename}" is outside of the assets root`);  }  return fs.readFileSync(assetPath, 'utf8');}/** * Escapes `<` characters in JSON to safely use it in `<script>` tag. */function escapeJson(json) {  return JSON.stringify(json).replace(/</gu, '\\u003c');}function getChartData(analyzerOpts, ...args) {  let chartData;  const {    logger  } = analyzerOpts;  try {    chartData = analyzer.getViewerData(...args, analyzerOpts);  } catch (err) {    logger.error(`Could't analyze webpack bundle:\n${err}`);    logger.debug(err.stack);    chartData = null;  }  if (_.isPlainObject(chartData) && _.isEmpty(chartData)) {    logger.error("Could't find any javascript bundles in provided stats file");    chartData = null;  }  return chartData;}
 |