devghost
Version:
👻 Find dead code, dead imports, and dead dependencies before they haunt your project
158 lines • 4.97 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeDependencies = analyzeDependencies;
const path = __importStar(require("node:path"));
const fs_1 = require("../utils/fs");
const tsparser_1 = require("../utils/tsparser");
/**
* Get all packages imported across all project files
*/
function getAllImportedPackages(files) {
const allPackages = new Set();
for (const file of files) {
const sourceFile = (0, tsparser_1.parseFile)(file);
if (!sourceFile) {
continue;
}
const packages = (0, tsparser_1.getImportedPackages)(sourceFile);
for (const pkg of packages) {
allPackages.add(pkg);
}
}
return allPackages;
}
/**
* Node.js built-in modules (should not be considered as dependencies)
*/
const BUILTIN_MODULES = new Set([
'assert',
'async_hooks',
'buffer',
'child_process',
'cluster',
'console',
'constants',
'crypto',
'dgram',
'diagnostics_channel',
'dns',
'domain',
'events',
'fs',
'http',
'http2',
'https',
'inspector',
'module',
'net',
'os',
'path',
'perf_hooks',
'process',
'punycode',
'querystring',
'readline',
'repl',
'stream',
'string_decoder',
'sys',
'timers',
'tls',
'trace_events',
'tty',
'url',
'util',
'v8',
'vm',
'wasi',
'worker_threads',
'zlib',
]);
/**
* Analyze dependencies to find unused packages
*/
async function analyzeDependencies(files, packageJson, projectRoot, includeDev = false) {
const unusedDependencies = [];
// Get all imported packages from the codebase
const importedPackages = getAllImportedPackages(files);
// Get dependencies from package.json
const dependencies = packageJson.dependencies || {};
const devDependencies = includeDev ? packageJson.devDependencies || {} : {};
// Check each dependency
for (const [depName, _version] of Object.entries(dependencies)) {
if (BUILTIN_MODULES.has(depName)) {
continue;
}
// Check if this dependency is imported anywhere
if (!importedPackages.has(depName)) {
// Calculate size in node_modules
const depPath = path.join(projectRoot, 'node_modules', depName);
const size = (0, fs_1.getDirectorySize)(depPath);
unusedDependencies.push({
name: depName,
type: 'dependency',
size,
});
}
}
// Check devDependencies if requested
if (includeDev) {
for (const [depName, _version] of Object.entries(devDependencies)) {
if (BUILTIN_MODULES.has(depName)) {
continue;
}
// Skip type packages - they're often not directly imported
if (depName.startsWith('@types/')) {
// Check if the base package is imported
const basePackage = depName.replace('@types/', '');
if (importedPackages.has(basePackage)) {
continue;
}
}
if (!importedPackages.has(depName)) {
const depPath = path.join(projectRoot, 'node_modules', depName);
const size = (0, fs_1.getDirectorySize)(depPath);
unusedDependencies.push({
name: depName,
type: 'devDependency',
size,
});
}
}
}
return unusedDependencies;
}
//# sourceMappingURL=deps.js.map