123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- 'use strict';
- var fs = require('fs');
- var path = require('path');
- var _ = require('lodash');
- var gzipSize = require('gzip-size');
- var Logger = require('./Logger');
- var Folder = require('./tree/Folder').default;
- var _require = require('./parseUtils'),
- parseBundle = _require.parseBundle;
- var _require2 = require('./utils'),
- createAssetsFilter = _require2.createAssetsFilter;
- var FILENAME_QUERY_REGEXP = /\?.*$/;
- module.exports = {
- getViewerData,
- readStatsFromFile
- };
- function getViewerData(bundleStats, bundleDir, opts) {
- var _ref = opts || {},
- _ref$logger = _ref.logger,
- logger = _ref$logger === undefined ? new Logger() : _ref$logger,
- _ref$excludeAssets = _ref.excludeAssets,
- excludeAssets = _ref$excludeAssets === undefined ? null : _ref$excludeAssets;
- var isAssetIncluded = createAssetsFilter(excludeAssets);
- // Sometimes all the information is located in `children` array (e.g. problem in #10)
- if (_.isEmpty(bundleStats.assets) && !_.isEmpty(bundleStats.children)) {
- bundleStats = bundleStats.children[0];
- }
- // Picking only `*.js` assets from bundle that has non-empty `chunks` array
- bundleStats.assets = _.filter(bundleStats.assets, function (asset) {
- // Removing query part from filename (yes, somebody uses it for some reason and Webpack supports it)
- // See #22
- asset.name = asset.name.replace(FILENAME_QUERY_REGEXP, '');
- return _.endsWith(asset.name, '.js') && !_.isEmpty(asset.chunks) && isAssetIncluded(asset.name);
- });
- // Trying to parse bundle assets and get real module sizes if `bundleDir` is provided
- var bundlesSources = null;
- var parsedModules = null;
- if (bundleDir) {
- bundlesSources = {};
- parsedModules = {};
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = bundleStats.assets[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var statAsset = _step.value;
- var assetFile = path.join(bundleDir, statAsset.name);
- var bundleInfo = void 0;
- try {
- bundleInfo = parseBundle(assetFile);
- } catch (err) {
- var msg = err.code === 'ENOENT' ? 'no such file' : err.message;
- logger.warn(`Error parsing bundle asset "${assetFile}": ${msg}`);
- continue;
- }
- bundlesSources[statAsset.name] = bundleInfo.src;
- _.assign(parsedModules, bundleInfo.modules);
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- if (_.isEmpty(bundlesSources)) {
- bundlesSources = null;
- parsedModules = null;
- logger.warn('\nNo bundles were parsed. Analyzer will show only original module sizes from stats file.\n');
- }
- }
- var modules = getBundleModules(bundleStats);
- var assets = _.transform(bundleStats.assets, function (result, statAsset) {
- var asset = result[statAsset.name] = _.pick(statAsset, 'size');
- if (bundlesSources && _.has(bundlesSources, statAsset.name)) {
- asset.parsedSize = bundlesSources[statAsset.name].length;
- asset.gzipSize = gzipSize.sync(bundlesSources[statAsset.name]);
- }
- // Picking modules from current bundle script
- asset.modules = _(modules).filter(function (statModule) {
- return assetHasModule(statAsset, statModule);
- }).each(function (statModule) {
- if (parsedModules) {
- statModule.parsedSrc = parsedModules[statModule.id];
- }
- });
- asset.tree = createModulesTree(asset.modules);
- }, {});
- return _.transform(assets, function (result, asset, filename) {
- result.push({
- label: filename,
- // Not using `asset.size` here provided by Webpack because it can be very confusing when `UglifyJsPlugin` is used.
- // In this case all module sizes from stats file will represent unminified module sizes, but `asset.size` will
- // be the size of minified bundle.
- // Using `asset.size` only if current asset doesn't contain any modules (resulting size equals 0)
- statSize: asset.tree.size || asset.size,
- parsedSize: asset.parsedSize,
- gzipSize: asset.gzipSize,
- groups: _.invokeMap(asset.tree.children, 'toChartData')
- });
- }, []);
- }
- function readStatsFromFile(filename) {
- return JSON.parse(fs.readFileSync(filename, 'utf8'));
- }
- function getBundleModules(bundleStats) {
- return _(bundleStats.chunks).map('modules').concat(bundleStats.modules).compact().flatten().uniqBy('id').value();
- }
- function assetHasModule(statAsset, statModule) {
- // Checking if this module is the part of asset chunks
- return _.some(statModule.chunks, function (moduleChunk) {
- return _.includes(statAsset.chunks, moduleChunk);
- });
- }
- function createModulesTree(modules) {
- var root = new Folder('.');
- _.each(modules, function (module) {
- return root.addModule(module);
- });
- return root;
- }
|