UNPKG

@stacker/remove-unused-deps

Version:

A CLI tool to remove unused dependencies from your project

191 lines (168 loc) • 5.83 kB
const { execSync } = require('child_process'); const depcheck = require('depcheck'); const fs = require('fs'); const path = require('path'); const inquirer = require('inquirer'); const ora = require('ora'); const chalk = require('chalk'); // Get the current working directory where the command is executed const projectDir = process.cwd(); function getPackageManager() { if (fs.existsSync(path.join(projectDir, 'pnpm-lock.yaml'))) { return 'pnpm'; } if (fs.existsSync(path.join(projectDir, 'yarn.lock'))) { return 'yarn'; } return 'npm'; } function removePackage(dep) { const packageManager = getPackageManager(); const commands = { pnpm: `pnpm remove ${dep}`, yarn: `yarn remove ${dep}`, npm: `npm uninstall ${dep}` }; const command = commands[packageManager]; return execSync(command, { stdio: 'inherit' }); } function installPackage(dep) { const packageManager = getPackageManager(); const commands = { pnpm: `pnpm add ${dep}`, yarn: `yarn add ${dep}`, npm: `npm install ${dep}` }; const command = commands[packageManager]; return execSync(command, { stdio: 'inherit' }); } async function handleDependencies() { try { const spinner = ora({ text: 'Scanning dependencies...', color: 'yellow' }).start(); const unused = await depcheck(projectDir, {}); const { dependencies, devDependencies, missing } = unused; const missingDeps = Object.keys(missing); spinner.stop(); if (dependencies.length === 0 && devDependencies.length === 0 && missingDeps.length === 0) { console.log(chalk.green('āœ” All dependencies are properly configured')); return; } // Print summary console.log(chalk.bold('\nšŸ“¦ Dependencies Status')); if (dependencies.length > 0 || devDependencies.length > 0) { console.log( chalk.yellow('āš ļø Unused Dependencies: ') + chalk.red(`${dependencies.length} unused`) ); console.log( chalk.yellow('āš ļø Unused DevDependencies: ') + chalk.red(`${devDependencies.length} unused`) ); } if (missingDeps.length > 0) { console.log( chalk.yellow('āš ļø Missing Dependencies: ') + chalk.red(`${missingDeps.length} missing`) ); } console.log(); // Create choices for both unused and missing dependencies const choices = [ ...(dependencies.length > 0 ? [ new inquirer.Separator(chalk.bold.blue('═══ Unused Dependencies ═══')), ...dependencies.map(dep => ({ name: `${chalk.yellow(dep)} ${chalk.gray('(remove)')}`, value: { name: dep, action: 'remove' }, type: 'dependencies' })) ] : []), ...(devDependencies.length > 0 ? [ new inquirer.Separator(chalk.bold.magenta('═══ Unused DevDependencies ═══')), ...devDependencies.map(dep => ({ name: `${chalk.yellow(dep)} ${chalk.gray('(remove)')}`, value: { name: dep, action: 'remove' }, type: 'devDependencies' })) ] : []), ...(missingDeps.length > 0 ? [ new inquirer.Separator(chalk.bold.green('═══ Missing Dependencies ═══')), ...missingDeps.map(dep => ({ name: `${chalk.yellow(dep)} ${chalk.gray('(install)')}`, value: { name: dep, action: 'install' }, type: 'missing' })) ] : []) ]; const { selectedDeps } = await inquirer.prompt([ { type: 'checkbox', name: 'selectedDeps', message: chalk.cyan('Select dependencies to manage:'), choices, pageSize: 10, loop: false } ]); if (selectedDeps.length === 0) { console.log(chalk.yellow('\nāš ļø No dependencies selected. Operation cancelled.')); return; } // Group selected dependencies by action const toRemove = selectedDeps.filter(dep => dep.action === 'remove').map(dep => dep.name); const toInstall = selectedDeps.filter(dep => dep.action === 'install').map(dep => dep.name); // Show summary of actions if (toRemove.length > 0) { console.log(chalk.yellow('\nPackages to remove:')); console.log(chalk.red(toRemove.join(', '))); } if (toInstall.length > 0) { console.log(chalk.yellow('\nPackages to install:')); console.log(chalk.green(toInstall.join(', '))); } const { confirm } = await inquirer.prompt([ { type: 'confirm', name: 'confirm', message: chalk.yellow('āš ļø Are you sure you want to proceed with these changes?'), default: false } ]); if (!confirm) { console.log(chalk.yellow('\nāš ļø Operation cancelled')); return; } // Execute removal for (const dep of toRemove) { try { const removalSpinner = ora({ text: `Removing ${chalk.cyan(dep)}...`, color: 'yellow' }).start(); removePackage(dep); removalSpinner.succeed(`Removed ${chalk.cyan(dep)}`); } catch (error) { console.error(chalk.red(`\nāŒ Error while removing ${dep}:`), error); } } // Execute installation for (const dep of toInstall) { try { const installSpinner = ora({ text: `Installing ${chalk.cyan(dep)}...`, color: 'yellow' }).start(); installPackage(dep); installSpinner.succeed(`Installed ${chalk.cyan(dep)}`); } catch (error) { console.error(chalk.red(`\nāŒ Error while installing ${dep}:`), error); } } console.log(chalk.green('\n✨ All selected operations completed successfully!')); } catch (error) { console.error(chalk.red('\nāŒ Error while checking dependencies:'), error); } } handleDependencies();