chushihua

This commit is contained in:
li
2026-01-26 23:20:48 +08:00
commit 7b5aab0206
22521 changed files with 3300090 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var bfj = require('bfj-node4');
var path = require('path');
var mkdir = require('mkdirp');
var _require = require('chalk'),
bold = _require.bold;
var Logger = require('./Logger');
var viewer = require('./viewer');
var BundleAnalyzerPlugin = function () {
function BundleAnalyzerPlugin(opts) {
_classCallCheck(this, BundleAnalyzerPlugin);
this.opts = Object.assign({
analyzerMode: 'server',
analyzerHost: '127.0.0.1',
analyzerPort: 8888,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'stats.json',
statsOptions: null,
excludeAssets: null,
logLevel: 'info',
// deprecated
startAnalyzer: true
}, opts);
this.server = null;
this.logger = new Logger(this.opts.logLevel);
}
_createClass(BundleAnalyzerPlugin, [{
key: 'apply',
value: function apply(compiler) {
var _this = this;
this.compiler = compiler;
var done = function done(stats) {
stats = stats.toJson(_this.opts.statsOptions);
var actions = [];
if (_this.opts.generateStatsFile) {
actions.push(function () {
return _this.generateStatsFile(stats);
});
}
// Handling deprecated `startAnalyzer` flag
if (_this.opts.analyzerMode === 'server' && !_this.opts.startAnalyzer) {
_this.opts.analyzerMode = 'disabled';
}
if (_this.opts.analyzerMode === 'server') {
actions.push(function () {
return _this.startAnalyzerServer(stats);
});
} else if (_this.opts.analyzerMode === 'static') {
actions.push(function () {
return _this.generateStaticReport(stats);
});
}
if (actions.length) {
// Making analyzer logs to be after all webpack logs in the console
setImmediate(function () {
actions.forEach(function (action) {
return action();
});
});
}
};
if (compiler.hooks) {
compiler.hooks.done.tap('webpack-bundle-analyzer', done);
} else {
compiler.plugin('done', done);
}
}
}, {
key: 'generateStatsFile',
value: function () {
var _ref = _asyncToGenerator(function* (stats) {
var statsFilepath = path.resolve(this.compiler.outputPath, this.opts.statsFilename);
mkdir.sync(path.dirname(statsFilepath));
try {
yield bfj.write(statsFilepath, stats, {
space: 2,
promises: 'ignore',
buffers: 'ignore',
maps: 'ignore',
iterables: 'ignore',
circular: 'ignore'
});
this.logger.info(`${bold('Webpack Bundle Analyzer')} saved stats file to ${bold(statsFilepath)}`);
} catch (error) {
this.logger.error(`${bold('Webpack Bundle Analyzer')} error saving stats file to ${bold(statsFilepath)}: ${error}`);
}
});
function generateStatsFile(_x) {
return _ref.apply(this, arguments);
}
return generateStatsFile;
}()
}, {
key: 'startAnalyzerServer',
value: function () {
var _ref2 = _asyncToGenerator(function* (stats) {
if (this.server) {
(yield this.server).updateChartData(stats);
} else {
this.server = viewer.startServer(stats, {
openBrowser: this.opts.openAnalyzer,
host: this.opts.analyzerHost,
port: this.opts.analyzerPort,
bundleDir: this.getBundleDirFromCompiler(),
logger: this.logger,
defaultSizes: this.opts.defaultSizes,
excludeAssets: this.opts.excludeAssets
});
}
});
function startAnalyzerServer(_x2) {
return _ref2.apply(this, arguments);
}
return startAnalyzerServer;
}()
}, {
key: 'generateStaticReport',
value: function generateStaticReport(stats) {
viewer.generateReport(stats, {
openBrowser: this.opts.openAnalyzer,
reportFilename: path.resolve(this.compiler.outputPath, this.opts.reportFilename),
bundleDir: this.getBundleDirFromCompiler(),
logger: this.logger,
defaultSizes: this.opts.defaultSizes,
excludeAssets: this.opts.excludeAssets
});
}
}, {
key: 'getBundleDirFromCompiler',
value: function getBundleDirFromCompiler() {
return this.compiler.outputFileSystem.constructor.name === 'MemoryFileSystem' ? null : this.compiler.outputPath;
}
}]);
return BundleAnalyzerPlugin;
}();
module.exports = BundleAnalyzerPlugin;
+94
View File
@@ -0,0 +1,94 @@
'use strict';
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var LEVELS = ['debug', 'info', 'warn', 'error', 'silent'];
var LEVEL_TO_CONSOLE_METHOD = new Map([['debug', 'log'], ['info', 'log'], ['warn', 'log']]);
var Logger = function () {
function Logger() {
var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Logger.defaultLevel;
_classCallCheck(this, Logger);
this.activeLevels = new Set();
this.setLogLevel(level);
}
_createClass(Logger, [{
key: 'setLogLevel',
value: function setLogLevel(level) {
var levelIndex = LEVELS.indexOf(level);
if (levelIndex === -1) throw new Error(`Invalid log level "${level}". Use one of these: ${LEVELS.join(', ')}`);
this.activeLevels.clear();
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = LEVELS.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var _ref2 = _slicedToArray(_ref, 2);
var i = _ref2[0];
var _level = _ref2[1];
if (i >= levelIndex) this.activeLevels.add(_level);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}, {
key: '_log',
value: function _log(level) {
var _console;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
(_console = console)[LEVEL_TO_CONSOLE_METHOD.get(level) || level].apply(_console, args);
}
}]);
return Logger;
}();
Logger.levels = LEVELS;
Logger.defaultLevel = 'info';
;
LEVELS.forEach(function (level) {
if (level === 'silent') return;
Logger.prototype[level] = function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
if (this.activeLevels.has(level)) this._log.apply(this, [level].concat(args));
};
});
module.exports = Logger;
+159
View File
@@ -0,0 +1,159 @@
'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;
}
+103
View File
@@ -0,0 +1,103 @@
#! /usr/bin/env node
'use strict';
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var _require = require('path'),
resolve = _require.resolve,
dirname = _require.dirname;
var _ = require('lodash');
var commander = require('commander');
var _require2 = require('chalk'),
magenta = _require2.magenta;
var analyzer = require('../analyzer');
var viewer = require('../viewer');
var Logger = require('../Logger');
var SIZES = new Set(['stat', 'parsed', 'gzip']);
var program = commander.version(require('../../package.json').version).usage(`<bundleStatsFile> [bundleDir] [options]
Arguments:
bundleStatsFile Path to Webpack Stats JSON file.
bundleDir Directory containing all generated bundles.
You should provided it if you want analyzer to show you the real parsed module sizes.
By default a directory of stats file is used.`).option('-m, --mode <mode>', 'Analyzer mode. Should be `server` or `static`.' + br('In `server` mode analyzer will start HTTP server to show bundle report.') + br('In `static` mode single HTML file with bundle report will be generated.'), 'server').option('-h, --host <host>', 'Host that will be used in `server` mode to start HTTP server.', '127.0.0.1').option('-p, --port <n>', 'Port that will be used in `server` mode to start HTTP server.', Number, 8888).option('-r, --report <file>', 'Path to bundle report file that will be generated in `static` mode.', 'report.html').option('-s, --default-sizes <type>', 'Module sizes to show in treemap by default.' + br(`Possible values: ${[].concat(_toConsumableArray(SIZES)).join(', ')}`), 'parsed').option('-O, --no-open', "Don't open report in default browser automatically.").option('-e, --exclude <regexp>', 'Assets that should be excluded from the report.' + br('Can be specified multiple times.'), array()).option('-l, --log-level <level>', 'Log level.' + br(`Possible values: ${[].concat(_toConsumableArray(Logger.levels)).join(', ')}`), Logger.defaultLevel).parse(process.argv);
var mode = program.mode,
host = program.host,
port = program.port,
reportFilename = program.report,
defaultSizes = program.defaultSizes,
logLevel = program.logLevel,
openBrowser = program.open,
excludeAssets = program.exclude,
_program$args = _slicedToArray(program.args, 2),
bundleStatsFile = _program$args[0],
bundleDir = _program$args[1];
var logger = new Logger(logLevel);
if (!bundleStatsFile) showHelp('Provide path to Webpack Stats file as first argument');
if (mode !== 'server' && mode !== 'static') showHelp('Invalid mode. Should be either `server` or `static`.');
if (mode === 'server' && !host) showHelp('Invalid host name');
if (mode === 'server' && isNaN(port)) showHelp('Invalid port number');
if (!SIZES.has(defaultSizes)) showHelp(`Invalid default sizes option. Possible values are: ${[].concat(_toConsumableArray(SIZES)).join(', ')}`);
bundleStatsFile = resolve(bundleStatsFile);
if (!bundleDir) bundleDir = dirname(bundleStatsFile);
var bundleStats = void 0;
try {
bundleStats = analyzer.readStatsFromFile(bundleStatsFile);
} catch (err) {
logger.error(`Could't read webpack bundle stats from "${bundleStatsFile}":\n${err}`);
logger.debug(err.stack);
process.exit(1);
}
if (mode === 'server') {
viewer.startServer(bundleStats, {
openBrowser,
port,
host,
defaultSizes,
bundleDir,
excludeAssets,
logger: new Logger(logLevel)
});
} else {
viewer.generateReport(bundleStats, {
openBrowser,
reportFilename: resolve(reportFilename),
defaultSizes,
bundleDir,
excludeAssets,
logger: new Logger(logLevel)
});
}
function showHelp(error) {
if (error) console.log(`\n ${magenta(error)}`);
program.outputHelp();
process.exit(1);
}
function br(str) {
return `\n${_.repeat(' ', 28)}${str}`;
}
function array() {
var arr = [];
return function (val) {
arr.push(val);
return arr;
};
}
+9
View File
@@ -0,0 +1,9 @@
'use strict';
var _require = require('./viewer'),
start = _require.start;
module.exports = {
start,
BundleAnalyzerPlugin: require('./BundleAnalyzerPlugin')
};
+198
View File
@@ -0,0 +1,198 @@
'use strict';
var fs = require('fs');
var _ = require('lodash');
var acorn = require('acorn');
var walk = require('acorn/dist/walk');
module.exports = {
parseBundle
};
function parseBundle(bundlePath) {
var content = fs.readFileSync(bundlePath, 'utf8');
var ast = acorn.parse(content, {
sourceType: 'script',
// I believe in a bright future of ECMAScript!
// Actually, it's set to `2050` to support the latest ECMAScript version that currently exists.
// Seems like `acorn` supports such weird option value.
ecmaVersion: 2050
});
var walkState = {
locations: null
};
walk.recursive(ast, walkState, {
CallExpression(node, state, c) {
if (state.locations) return;
var args = node.arguments;
// Main chunk with webpack loader.
// Modules are stored in first argument:
// (function (...) {...})(<modules>)
if (node.callee.type === 'FunctionExpression' && !node.callee.id && args.length === 1 && isSimpleModulesList(args[0])) {
state.locations = getModulesLocations(args[0]);
return;
}
// Async Webpack < v4 chunk without webpack loader.
// webpackJsonp([<chunks>], <modules>, ...)
// As function name may be changed with `output.jsonpFunction` option we can't rely on it's default name.
if (node.callee.type === 'Identifier' && mayBeAsyncChunkArguments(args) && isModulesList(args[1])) {
state.locations = getModulesLocations(args[1]);
return;
}
// Async Webpack v4 chunk without webpack loader.
// (window.webpackJsonp=window.webpackJsonp||[]).push([[<chunks>], <modules>, ...]);
// As function name may be changed with `output.jsonpFunction` option we can't rely on it's default name.
if (isAsyncChunkPushExpression(node)) {
state.locations = getModulesLocations(args[0].elements[1]);
return;
}
// Walking into arguments because some of plugins (e.g. `DedupePlugin`) or some Webpack
// features (e.g. `umd` library output) can wrap modules list into additional IIFE.
_.each(args, function (arg) {
return c(arg, state);
});
}
});
var modules = void 0;
if (walkState.locations) {
modules = _.mapValues(walkState.locations, function (loc) {
return content.slice(loc.start, loc.end);
});
} else {
modules = {};
}
return {
src: content,
modules
};
}
function isModulesList(node) {
return isSimpleModulesList(node) ||
// Modules are contained in expression `Array([minimum ID]).concat([<module>, <module>, ...])`
isOptimizedModulesArray(node);
}
function isSimpleModulesList(node) {
return (
// Modules are contained in hash. Keys are module ids.
isModulesHash(node) ||
// Modules are contained in array. Indexes are module ids.
isModulesArray(node)
);
}
function isModulesHash(node) {
return node.type === 'ObjectExpression' && _(node.properties).map('value').every(isModuleWrapper);
}
function isModulesArray(node) {
return node.type === 'ArrayExpression' && _.every(node.elements, function (elem) {
return (
// Some of array items may be skipped because there is no module with such id
!elem || isModuleWrapper(elem)
);
});
}
function isOptimizedModulesArray(node) {
// Checking whether modules are contained in `Array(<minimum ID>).concat(...modules)` array:
// https://github.com/webpack/webpack/blob/v1.14.0/lib/Template.js#L91
// The `<minimum ID>` + array indexes are module ids
return node.type === 'CallExpression' && node.callee.type === 'MemberExpression' &&
// Make sure the object called is `Array(<some number>)`
node.callee.object.type === 'CallExpression' && node.callee.object.callee.type === 'Identifier' && node.callee.object.callee.name === 'Array' && node.callee.object.arguments.length === 1 && isNumericId(node.callee.object.arguments[0]) &&
// Make sure the property X called for `Array(<some number>).X` is `concat`
node.callee.property.type === 'Identifier' && node.callee.property.name === 'concat' &&
// Make sure exactly one array is passed in to `concat`
node.arguments.length === 1 && isModulesArray(node.arguments[0]);
}
function isModuleWrapper(node) {
return (
// It's an anonymous function expression that wraps module
(node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') && !node.id ||
// If `DedupePlugin` is used it can be an ID of duplicated module...
isModuleId(node) ||
// or an array of shape [<module_id>, ...args]
node.type === 'ArrayExpression' && node.elements.length > 1 && isModuleId(node.elements[0])
);
}
function isModuleId(node) {
return node.type === 'Literal' && (isNumericId(node) || typeof node.value === 'string');
}
function isNumericId(node) {
return node.type === 'Literal' && Number.isInteger(node.value) && node.value >= 0;
}
function isChunkIds(node) {
// Array of numeric or string ids. Chunk IDs are strings when NamedChunksPlugin is used
return node.type === 'ArrayExpression' && _.every(node.elements, isModuleId);
}
function isAsyncChunkPushExpression(node) {
var callee = node.callee,
args = node.arguments;
return callee.type === 'MemberExpression' && callee.property.name === 'push' && callee.object.type === 'AssignmentExpression' && callee.object.left.object && (callee.object.left.object.name === 'window' ||
// Webpack 4 uses `this` instead of `window`
callee.object.left.object.type === 'ThisExpression') && args.length === 1 && args[0].type === 'ArrayExpression' && mayBeAsyncChunkArguments(args[0].elements) && isModulesList(args[0].elements[1]);
}
function mayBeAsyncChunkArguments(args) {
return args.length >= 2 && isChunkIds(args[0]);
}
function getModulesLocations(node) {
if (node.type === 'ObjectExpression') {
// Modules hash
var modulesNodes = node.properties;
return _.transform(modulesNodes, function (result, moduleNode) {
var moduleId = moduleNode.key.name || moduleNode.key.value;
result[moduleId] = getModuleLocation(moduleNode.value);
}, {});
}
var isOptimizedArray = node.type === 'CallExpression';
if (node.type === 'ArrayExpression' || isOptimizedArray) {
// Modules array or optimized array
var minId = isOptimizedArray ?
// Get the [minId] value from the Array() call first argument literal value
node.callee.object.arguments[0].value :
// `0` for simple array
0;
var _modulesNodes = isOptimizedArray ?
// The modules reside in the `concat()` function call arguments
node.arguments[0].elements : node.elements;
return _.transform(_modulesNodes, function (result, moduleNode, i) {
if (!moduleNode) return;
result[i + minId] = getModuleLocation(moduleNode);
}, {});
}
return {};
}
function getModuleLocation(node) {
return {
start: node.start,
end: node.end
};
}
+138
View File
@@ -0,0 +1,138 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _Node2 = require('./Node');
var _Node3 = _interopRequireDefault(_Node2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var BaseFolder = function (_Node) {
_inherits(BaseFolder, _Node);
function BaseFolder(name, parent) {
_classCallCheck(this, BaseFolder);
var _this = _possibleConstructorReturn(this, (BaseFolder.__proto__ || Object.getPrototypeOf(BaseFolder)).call(this, name, parent));
_this.children = Object.create(null);
return _this;
}
_createClass(BaseFolder, [{
key: 'getChild',
value: function getChild(name) {
return this.children[name];
}
}, {
key: 'addChildModule',
value: function addChildModule(module) {
var name = module.name;
var currentChild = this.children[name];
// For some reason we already have this node in children and it's a folder.
if (currentChild && currentChild instanceof BaseFolder) return;
if (currentChild) {
// We already have this node in children and it's a module.
// Merging it's data.
currentChild.mergeData(module.data);
} else {
// Pushing new module
module.parent = this;
this.children[name] = module;
}
delete this._size;
delete this._src;
}
}, {
key: 'addChildFolder',
value: function addChildFolder(folder) {
folder.parent = this;
this.children[folder.name] = folder;
delete this._size;
delete this._src;
return folder;
}
}, {
key: 'walk',
value: function walk(walker) {
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var deep = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var stopped = false;
_lodash2.default.each(this.children, function (child) {
if (deep && child.walk) {
state = child.walk(walker, state, stop);
} else {
state = walker(child, state, stop);
}
if (stopped) return false;
});
return state;
function stop(finalState) {
stopped = true;
return finalState;
}
}
}, {
key: 'toChartData',
value: function toChartData() {
return {
label: this.name,
path: this.path,
statSize: this.size,
groups: _lodash2.default.invokeMap(this.children, 'toChartData')
};
}
}, {
key: 'src',
get: function get() {
if (!_lodash2.default.has(this, '_src')) {
this._src = this.walk(function (node, src) {
return src += node.src || '';
}, '', false);
}
return this._src;
}
}, {
key: 'size',
get: function get() {
if (!_lodash2.default.has(this, '_size')) {
this._size = this.walk(function (node, size) {
return size + node.size;
}, 0, false);
}
return this._size;
}
}]);
return BaseFolder;
}(_Node3.default);
exports.default = BaseFolder;
;
+122
View File
@@ -0,0 +1,122 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _Module2 = require('./Module');
var _Module3 = _interopRequireDefault(_Module2);
var _ContentModule = require('./ContentModule');
var _ContentModule2 = _interopRequireDefault(_ContentModule);
var _ContentFolder = require('./ContentFolder');
var _ContentFolder2 = _interopRequireDefault(_ContentFolder);
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ConcatenatedModule = function (_Module) {
_inherits(ConcatenatedModule, _Module);
function ConcatenatedModule(name, data, parent) {
_classCallCheck(this, ConcatenatedModule);
var _this = _possibleConstructorReturn(this, (ConcatenatedModule.__proto__ || Object.getPrototypeOf(ConcatenatedModule)).call(this, name, data, parent));
_this.name += ' (concatenated)';
_this.children = Object.create(null);
_this.fillContentModules();
return _this;
}
_createClass(ConcatenatedModule, [{
key: 'fillContentModules',
value: function fillContentModules() {
var _this2 = this;
_lodash2.default.each(this.data.modules, function (moduleData) {
return _this2.addContentModule(moduleData);
});
}
}, {
key: 'addContentModule',
value: function addContentModule(moduleData) {
var _this3 = this;
var pathParts = (0, _utils.getModulePathParts)(moduleData);
if (!pathParts) {
return;
}
var _ref = [pathParts.slice(0, -1), _lodash2.default.last(pathParts)],
folders = _ref[0],
fileName = _ref[1];
var currentFolder = this;
_lodash2.default.each(folders, function (folderName) {
var childFolder = currentFolder.getChild(folderName);
if (!childFolder) {
childFolder = currentFolder.addChildFolder(new _ContentFolder2.default(folderName, _this3));
}
currentFolder = childFolder;
});
var module = new _ContentModule2.default(fileName, moduleData, this);
currentFolder.addChildModule(module);
}
}, {
key: 'getChild',
value: function getChild(name) {
return this.children[name];
}
}, {
key: 'addChildModule',
value: function addChildModule(module) {
module.parent = this;
this.children[module.name] = module;
}
}, {
key: 'addChildFolder',
value: function addChildFolder(folder) {
folder.parent = this;
this.children[folder.name] = folder;
return folder;
}
}, {
key: 'toChartData',
value: function toChartData() {
return Object.assign({}, _get(ConcatenatedModule.prototype.__proto__ || Object.getPrototypeOf(ConcatenatedModule.prototype), 'toChartData', this).call(this), {
concatenated: true,
groups: _lodash2.default.invokeMap(this.children, 'toChartData')
});
}
}]);
return ConcatenatedModule;
}(_Module3.default);
exports.default = ConcatenatedModule;
;
+69
View File
@@ -0,0 +1,69 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _BaseFolder2 = require('./BaseFolder');
var _BaseFolder3 = _interopRequireDefault(_BaseFolder2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ContentFolder = function (_BaseFolder) {
_inherits(ContentFolder, _BaseFolder);
function ContentFolder(name, ownerModule, parent) {
_classCallCheck(this, ContentFolder);
var _this = _possibleConstructorReturn(this, (ContentFolder.__proto__ || Object.getPrototypeOf(ContentFolder)).call(this, name, parent));
_this.ownerModule = ownerModule;
return _this;
}
_createClass(ContentFolder, [{
key: 'getSize',
value: function getSize(sizeType) {
var ownerModuleSize = this.ownerModule[sizeType];
if (ownerModuleSize !== undefined) {
return Math.floor(this.size / this.ownerModule.size * ownerModuleSize);
}
}
}, {
key: 'toChartData',
value: function toChartData() {
return Object.assign({}, _get(ContentFolder.prototype.__proto__ || Object.getPrototypeOf(ContentFolder.prototype), 'toChartData', this).call(this), {
parsedSize: this.parsedSize,
gzipSize: this.gzipSize,
inaccurateSizes: true
});
}
}, {
key: 'parsedSize',
get: function get() {
return this.getSize('parsedSize');
}
}, {
key: 'gzipSize',
get: function get() {
return this.getSize('gzipSize');
}
}]);
return ContentFolder;
}(_BaseFolder3.default);
exports.default = ContentFolder;
;
+67
View File
@@ -0,0 +1,67 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _Module2 = require('./Module');
var _Module3 = _interopRequireDefault(_Module2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ContentModule = function (_Module) {
_inherits(ContentModule, _Module);
function ContentModule(name, data, ownerModule, parent) {
_classCallCheck(this, ContentModule);
var _this = _possibleConstructorReturn(this, (ContentModule.__proto__ || Object.getPrototypeOf(ContentModule)).call(this, name, data, parent));
_this.ownerModule = ownerModule;
return _this;
}
_createClass(ContentModule, [{
key: 'getSize',
value: function getSize(sizeType) {
var ownerModuleSize = this.ownerModule[sizeType];
if (ownerModuleSize !== undefined) {
return Math.floor(this.size / this.ownerModule.size * ownerModuleSize);
}
}
}, {
key: 'toChartData',
value: function toChartData() {
return Object.assign({}, _get(ContentModule.prototype.__proto__ || Object.getPrototypeOf(ContentModule.prototype), 'toChartData', this).call(this), {
inaccurateSizes: true
});
}
}, {
key: 'parsedSize',
get: function get() {
return this.getSize('parsedSize');
}
}, {
key: 'gzipSize',
get: function get() {
return this.getSize('gzipSize');
}
}]);
return ContentModule;
}(_Module3.default);
exports.default = ContentModule;
;
+114
View File
@@ -0,0 +1,114 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _gzipSize = require('gzip-size');
var _gzipSize2 = _interopRequireDefault(_gzipSize);
var _Module = require('./Module');
var _Module2 = _interopRequireDefault(_Module);
var _BaseFolder2 = require('./BaseFolder');
var _BaseFolder3 = _interopRequireDefault(_BaseFolder2);
var _ConcatenatedModule = require('./ConcatenatedModule');
var _ConcatenatedModule2 = _interopRequireDefault(_ConcatenatedModule);
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Folder = function (_BaseFolder) {
_inherits(Folder, _BaseFolder);
function Folder() {
_classCallCheck(this, Folder);
return _possibleConstructorReturn(this, (Folder.__proto__ || Object.getPrototypeOf(Folder)).apply(this, arguments));
}
_createClass(Folder, [{
key: 'addModule',
value: function addModule(moduleData) {
var pathParts = (0, _utils.getModulePathParts)(moduleData);
if (!pathParts) {
return;
}
var _ref = [pathParts.slice(0, -1), _lodash2.default.last(pathParts)],
folders = _ref[0],
fileName = _ref[1];
var currentFolder = this;
_lodash2.default.each(folders, function (folderName) {
var childNode = currentFolder.getChild(folderName);
if (
// Folder is not created yet
!childNode ||
// In some situations (invalid usage of dynamic `require()`) webpack generates a module with empty require
// context, but it's moduleId points to a directory in filesystem.
// In this case we replace this `File` node with `Folder`.
// See `test/stats/with-invalid-dynamic-require.json` as an example.
!(childNode instanceof Folder)) {
childNode = currentFolder.addChildFolder(new Folder(folderName));
}
currentFolder = childNode;
});
var ModuleConstructor = moduleData.modules ? _ConcatenatedModule2.default : _Module2.default;
var module = new ModuleConstructor(fileName, moduleData, this);
currentFolder.addChildModule(module);
}
}, {
key: 'toChartData',
value: function toChartData() {
return Object.assign({}, _get(Folder.prototype.__proto__ || Object.getPrototypeOf(Folder.prototype), 'toChartData', this).call(this), {
parsedSize: this.parsedSize,
gzipSize: this.gzipSize
});
}
}, {
key: 'parsedSize',
get: function get() {
return this.src ? this.src.length : 0;
}
}, {
key: 'gzipSize',
get: function get() {
if (!_lodash2.default.has(this, '_gzipSize')) {
this._gzipSize = this.src ? _gzipSize2.default.sync(this.src) : 0;
}
return this._gzipSize;
}
}]);
return Folder;
}(_BaseFolder3.default);
exports.default = Folder;
;
+101
View File
@@ -0,0 +1,101 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _gzipSize = require('gzip-size');
var _gzipSize2 = _interopRequireDefault(_gzipSize);
var _Node2 = require('./Node');
var _Node3 = _interopRequireDefault(_Node2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Module = function (_Node) {
_inherits(Module, _Node);
function Module(name, data, parent) {
_classCallCheck(this, Module);
var _this = _possibleConstructorReturn(this, (Module.__proto__ || Object.getPrototypeOf(Module)).call(this, name, parent));
_this.data = data;
return _this;
}
_createClass(Module, [{
key: 'mergeData',
value: function mergeData(data) {
if (data.size) {
this.size += data.size;
}
if (data.parsedSrc) {
this.src = (this.src || '') + data.parsedSrc;
}
}
}, {
key: 'toChartData',
value: function toChartData() {
return {
id: this.data.id,
label: this.name,
path: this.path,
statSize: this.size,
parsedSize: this.parsedSize,
gzipSize: this.gzipSize
};
}
}, {
key: 'src',
get: function get() {
return this.data.parsedSrc;
},
set: function set(value) {
this.data.parsedSrc = value;
delete this._gzipSize;
}
}, {
key: 'size',
get: function get() {
return this.data.size;
},
set: function set(value) {
this.data.size = value;
}
}, {
key: 'parsedSize',
get: function get() {
return this.src ? this.src.length : undefined;
}
}, {
key: 'gzipSize',
get: function get() {
if (!_lodash2.default.has(this, '_gzipSize')) {
this._gzipSize = this.src ? _gzipSize2.default.sync(this.src) : undefined;
}
return this._gzipSize;
}
}]);
return Module;
}(_Node3.default);
exports.default = Module;
;
+38
View File
@@ -0,0 +1,38 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Node = function () {
function Node(name, parent) {
_classCallCheck(this, Node);
this.name = name;
this.parent = parent;
}
_createClass(Node, [{
key: 'path',
get: function get() {
var path = [];
var node = this;
while (node) {
path.push(node.name);
node = node.parent;
}
return path.reverse().join('/');
}
}]);
return Node;
}();
exports.default = Node;
;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getModulePathParts = getModulePathParts;
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var MULTI_MODULE_REGEXP = /^multi /;
function getModulePathParts(moduleData) {
if (MULTI_MODULE_REGEXP.test(moduleData.identifier)) {
return [moduleData.identifier];
}
var parsedPath = _lodash2.default
// Removing loaders from module path: they're joined by `!` and the last part is a raw module path
.last(moduleData.name.split('!'))
// Splitting module path into parts
.split('/')
// Removing first `.`
.slice(1)
// Replacing `~` with `node_modules`
.map(function (part) {
return part === '~' ? 'node_modules' : part;
});
return parsedPath.length ? parsedPath : null;
}
+40
View File
@@ -0,0 +1,40 @@
'use strict';
var _require = require('util'),
inspect = _require.inspect;
var _ = require('lodash');
exports.createAssetsFilter = createAssetsFilter;
function createAssetsFilter(excludePatterns) {
var excludeFunctions = _(excludePatterns).castArray().compact().map(function (pattern) {
if (typeof pattern === 'string') {
pattern = new RegExp(pattern);
}
if (_.isRegExp(pattern)) {
return function (asset) {
return pattern.test(asset);
};
}
if (!_.isFunction(pattern)) {
throw new TypeError(`Pattern should be either string, RegExp or a function, but "${inspect(pattern, { depth: 0 })}" got.`);
}
return pattern;
}).value();
if (excludeFunctions.length) {
return function (asset) {
return _.every(excludeFunctions, function (fn) {
return fn(asset) !== true;
});
};
} else {
return function () {
return true;
};
}
}
+197
View File
@@ -0,0 +1,197 @@
'use strict';
var startServer = function () {
var _ref = _asyncToGenerator(function* (bundleStats, opts) {
var _ref2 = opts || {},
_ref2$port = _ref2.port,
port = _ref2$port === undefined ? 8888 : _ref2$port,
_ref2$host = _ref2.host,
host = _ref2$host === undefined ? '127.0.0.1' : _ref2$host,
_ref2$openBrowser = _ref2.openBrowser,
openBrowser = _ref2$openBrowser === undefined ? true : _ref2$openBrowser,
_ref2$bundleDir = _ref2.bundleDir,
bundleDir = _ref2$bundleDir === undefined ? null : _ref2$bundleDir,
_ref2$logger = _ref2.logger,
logger = _ref2$logger === undefined ? new Logger() : _ref2$logger,
_ref2$defaultSizes = _ref2.defaultSizes,
defaultSizes = _ref2$defaultSizes === undefined ? 'parsed' : _ref2$defaultSizes,
_ref2$excludeAssets = _ref2.excludeAssets,
excludeAssets = _ref2$excludeAssets === undefined ? null : _ref2$excludeAssets;
var analyzerOpts = { logger, excludeAssets };
var chartData = getChartData(analyzerOpts, bundleStats, bundleDir);
if (!chartData) return;
var 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('/', function (req, res) {
res.render('viewer', {
mode: 'server',
get chartData() {
return JSON.stringify(chartData);
},
defaultSizes: JSON.stringify(defaultSizes)
});
});
var server = http.createServer(app);
yield new Promise(function (resolve) {
server.listen(port, host, function () {
resolve();
var 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);
}
});
});
var wss = new WebSocket.Server({ server });
wss.on('connection', function (ws) {
ws.on('error', function (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) {
var newChartData = getChartData(analyzerOpts, bundleStats, bundleDir);
if (!newChartData) return;
chartData = newChartData;
wss.clients.forEach(function (client) {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({
event: 'chartDataUpdated',
data: newChartData
}));
}
});
}
});
return function startServer(_x, _x2) {
return _ref.apply(this, arguments);
};
}();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var path = require('path');
var fs = require('fs');
var http = require('http');
var WebSocket = require('ws');
var _ = require('lodash');
var express = require('express');
var ejs = require('ejs');
var opener = require('opener');
var mkdir = require('mkdirp');
var _require = require('chalk'),
bold = _require.bold;
var Logger = require('./Logger');
var analyzer = require('./analyzer');
var projectRoot = path.resolve(__dirname, '..');
module.exports = {
startServer,
generateReport,
// deprecated
start: startServer
};
function generateReport(bundleStats, opts) {
var _ref3 = opts || {},
_ref3$openBrowser = _ref3.openBrowser,
openBrowser = _ref3$openBrowser === undefined ? true : _ref3$openBrowser,
_ref3$reportFilename = _ref3.reportFilename,
reportFilename = _ref3$reportFilename === undefined ? 'report.html' : _ref3$reportFilename,
_ref3$bundleDir = _ref3.bundleDir,
bundleDir = _ref3$bundleDir === undefined ? null : _ref3$bundleDir,
_ref3$logger = _ref3.logger,
logger = _ref3$logger === undefined ? new Logger() : _ref3$logger,
_ref3$defaultSizes = _ref3.defaultSizes,
defaultSizes = _ref3$defaultSizes === undefined ? 'parsed' : _ref3$defaultSizes,
_ref3$excludeAssets = _ref3.excludeAssets,
excludeAssets = _ref3$excludeAssets === undefined ? null : _ref3$excludeAssets;
var chartData = getChartData({ logger, excludeAssets }, bundleStats, bundleDir);
if (!chartData) return;
ejs.renderFile(`${projectRoot}/views/viewer.ejs`, {
mode: 'static',
chartData: JSON.stringify(chartData),
assetContent: getAssetContent,
defaultSizes: JSON.stringify(defaultSizes)
}, function (err, reportHtml) {
if (err) return logger.error(err);
var 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}`);
}
});
}
function getAssetContent(filename) {
return fs.readFileSync(`${projectRoot}/public/${filename}`, 'utf8');
}
function getChartData(analyzerOpts) {
var chartData = void 0;
var logger = analyzerOpts.logger;
try {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
chartData = analyzer.getViewerData.apply(analyzer, args.concat([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;
}