Skip to content

Instantly share code, notes, and snippets.

@mpowaga
Created November 25, 2016 16:34
Show Gist options
  • Save mpowaga/a5557fba6c3eeda69563f31211250f2c to your computer and use it in GitHub Desktop.
Save mpowaga/a5557fba6c3eeda69563f31211250f2c to your computer and use it in GitHub Desktop.
var babylon = require('babylon');
var traverse = require('babel-traverse').default;
var fs = require('fs');
var zlib = require('zlib');
var _ = require('lodash');
console.time('finished in');
var code = fs.readFileSync('./bundle.js').toString();
var ast = babylon.parse(code);
var packages = {};
traverse(ast, {
UnaryExpression: function(path) {
if (!path.scope.parent) {
this.unaryExpNode = path.node;
path.traverse({
CallExpression: function(path) {
if (path.parent === this.unaryExpNode && !path.scope.parent) {
this.callExpNode = path.node;
path.traverse({
VariableDeclaration: {
enter: function(path) {
if (path.scope.parent && !path.scope.parent.parent && !this.deps) {
this.deps = _.uniq(_.filter(_.map(path.node.declarations, function (decl) {
if (decl.init && decl.init.type === 'MemberExpression' &&
decl.init.object.type === 'MemberExpression' &&
decl.init.object.object.type === 'Identifier' &&
decl.init.object.object.name === 'Package') {
if (decl.init.object.property.type === 'Identifier') {
return decl.init.object.property.name;
}
if (decl.init.object.property.type === 'StringLiteral') {
return decl.init.object.property.value;
}
}
}), function (x) { return !!x; }));
}
}
},
FunctionExpression: {
enter: function(path) {
var node = path.node;
if (path.parent === this.callExpNode) {
path.traverse({
AssignmentExpression: function(path) {
var left = path.node.left;
if (left.object && left.object.name === 'Package') {
path.traverse({
MemberExpression: function (path) {
var property = path.node.property;
this.pkg = property.value || property.name;
this.node = node;
}
});
}
}
});
}
},
exit: function (path) {
if (path.node === this.node) {
var node = path.parent;
var chunk = code.substr(node.start, node.end - node.start);
if (this.pkg === 'modules') {
console.log(code.substr(node.start, node.end - node.start));
}
packages[this.pkg] = {
bytes: {
raw: Buffer.byteLength(chunk, 'utf-8'),
gzip: Buffer.byteLength(zlib.gzipSync(chunk), 'utf-8')
},
dependencies: this.deps
};
this.deps = undefined;
}
}
}
});
}
}
});
}
}
});
var totalBytesRaw = _.reduce(_.keys(packages), packageBytesReducer('raw'), 0);
var totalBytesGzip = _.reduce(_.keys(packages), packageBytesReducer('gzip'), 0);
var output = _.reduce(_.keys(packages), function (result, packageName) {
var package = packages[packageName];
var dependencies = _.filter(_.keys(packages), function (key) {
return _.includes(package.dependencies, key);
});
var dependenciesBytesRaw = _.reduce(dependencies, packageBytesReducer('raw'), 0);
var dependenciesBytesGzip = _.reduce(dependencies, packageBytesReducer('gzip'), 0);
var dependants = _.filter(_.keys(packages), function (key) {
return _.includes(packages[key].dependencies, packageName);
});
var dependantsBytesRaw = _.reduce(dependants, packageBytesReducer('raw'), 0);
var dependantsBytesGzip = _.reduce(dependants, packageBytesReducer('gzip'), 0);
return _.union(result, [{
package: packageName,
bytes: {
raw: package.bytes.raw,
gzip: package.bytes.gzip,
percentRaw: (package.bytes.raw / totalBytesRaw) * 100,
percentGzip: (package.bytes.gzip / totalBytesGzip) * 100
},
dependencies: {
packages: dependencies,
bytes: {
raw: dependenciesBytesRaw,
gzip: dependenciesBytesGzip,
percentRaw: (dependenciesBytesRaw / totalBytesRaw) * 100,
percentGzip: (dependenciesBytesGzip / totalBytesGzip) * 100
}
},
dependants: {
packages: dependants,
bytes: {
raw: _.reduce(dependants, packageBytesReducer('raw'), 0),
gzip: _.reduce(dependants, packageBytesReducer('gzip'), 0),
percentRaw: (dependantsBytesRaw / totalBytesRaw) * 100,
percentGzip: (dependantsBytesGzip / totalBytesGzip) * 100
}
}
}]);
}, []);
fs.writeFileSync('./output.json', JSON.stringify(output));
console.timeEnd('finished in');
function packageBytesReducer (key) {
return function (result, packageName) {
return result + packages[packageName].bytes[key];
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment