Skip to content

Instantly share code, notes, and snippets.

@amalitsky
Created November 2, 2018 13:17
Show Gist options
  • Select an option

  • Save amalitsky/25a139e1468c6a72b7eaa46bb8c95989 to your computer and use it in GitHub Desktop.

Select an option

Save amalitsky/25a139e1468c6a72b7eaa46bb8c95989 to your computer and use it in GitHub Desktop.
Returns AngularJS dependencies (injectables) list grouped by AngularJS app module. Run this script from console in Chrome.
(function angularJsDepsAnalyzer(angular) {
'use strict';
//console.time('total execution time');
function naturalSort(a = '', b = '') {
return `${a}`.localeCompare(`${b}`, undefined, {numeric: true});
}
const modules = [
'list',
'of',
'your',
'app',
'modules'
].sort(naturalSort);
function getDependencyType(provider, type) {
switch (provider) {
case '$controllerProvider':
return 'controller';
case '$filterProvider':
return 'filter';
case '$compileProvider':
case '$provide':
return type;
default:
throw Error(`unknown combination of provider '${provider}' and type '${type}'`);
}
}
const {modules: modulesHash} = angular.element('body').injector();
function moduleIsPresent(moduleName) {
return moduleName in modulesHash;
}
function getModuleDepsHash(moduleName) {
const {_invokeQueue: queue} = angular.module(moduleName);
const depsHash = {};
queue.forEach(([provider, type, args]) => {
const depType = getDependencyType(provider, type);
if (!(depType in depsHash)) {
depsHash[depType] = [];
}
const [name] = args;
if (typeof name !== 'string') {
console.error(args);
throw Error(`${depType} dependency has unexpected signature`);
}
depsHash[depType].push(name);
});
return depsHash;
}
const moduleDeps = [];
console.time('parsing dependency tree');
modules.forEach(moduleName => {
if (!moduleIsPresent(moduleName)) {
console.warn(`module ${moduleName} is not present`);
return;
}
const moduleDepsHash = getModuleDepsHash(moduleName);
const total = Object.values(moduleDepsHash).reduce((acc, list) => acc + list.length, 0);
moduleDeps.push({
name: moduleName,
depsHash: moduleDepsHash,
total
});
});
console.timeEnd('parsing dependency tree');
const totalHash = {};
let counter = 0;
function renderModuleDeps({name, total, depsHash}) {
console.groupCollapsed(`module ${name}: ${total}`);
Object.keys(depsHash).sort().forEach(type => {
const list = depsHash[type];
const {length} = list;
if (!(type in totalHash)) {
totalHash[type] = {
type,
count: 0,
list: []
};
}
totalHash[type].count += length;
totalHash[type].list.push(...list);
console.groupCollapsed(`${type}: ${length}`);
console.table(list.sort(naturalSort));
console.groupEnd();
});
counter += total;
console.groupEnd();
}
moduleDeps.forEach(renderModuleDeps);
console.log(`${moduleDeps.length} modules with ${counter} dependencies`);
console.groupCollapsed('Through all modules by type');
console.table(
Object.values(totalHash)
.reduce((hash, {type, count}) => {
hash[type] = count;
return hash;
}, {})
);
console.groupEnd();
//console.log(JSON.stringify(totalHash)); // uncomment for export
//console.timeEnd('total execution time');
})(angular);
@amalitsky
Copy link
Author

Output example for angularjs.org, modules homepage and download-data:

screen shot 2018-11-02 at 16 21 08

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment