DEV Community

Cover image for Clean Up Your Hard Drive: A Script to Delete All Your node_modules Directories
Jay @ Designly
Jay @ Designly

Posted on • Originally published at blog.designly.biz

Clean Up Your Hard Drive: A Script to Delete All Your node_modules Directories

If you're like me, you have a GitHub directory in your Documents folder with tens or possibly hundreds of repos that use the Node Package Manager. Also, if you're like me, you tend to work on several projects simultaneously. And, once again, if you're like me, you tend to forget about the node_modules directory when you're either done working on the project, or don't plan to for quite some time.

If this sounds like you, then this script is for you! It's written in bash, which you can run on Linux or Mac, but to run it on Windows, you'll want to go ahead and download the Cmder (link at bottom) console emulator, which gives you all the GNU tools we know and love, like ls, nano, rm, find, and, of course sh.

Alright, here's the code:

#!/bin/bash

# Initialize dry-run flag to false
DRY_RUN=false

# Initialize exclusion file to empty
EXCLUDE_FILE=""

trim_string() {
    echo "$1" | awk '{$1=$1};1'
}

# Manually parse command-line options
while [ "$#" -gt 0 ]; do
    case "$1" in
    -d)
        DRY_RUN=true
        shift
        ;;
    -e)
        EXCLUDE_FILE="$2"
        shift 2
        ;;
    *)
        # Assume the remaining argument is the parent directory
        PARENT_DIR="$1"
        shift
        ;;
    esac
done

# Check if the parent directory is provided
if [ -z "$PARENT_DIR" ]; then
    echo "Usage: $0 [-d] [-e exclude_file] <parent_directory>"
    exit 1
fi

# Read the exclusion list into an array
EXCLUDE_DIRS=()
if [ -n "$EXCLUDE_FILE" ]; then
    echo "Reading exclusion list from $EXCLUDE_FILE"
    while read -r exclude; do
        echo "Excluding: $exclude"
        EXCLUDE_DIRS+=("$exclude")
    done <"$EXCLUDE_FILE"
fi

# Loop through each subdirectory in the parent directory
for directory in "$PARENT_DIR"/*; do
    # Skip if not a directory
    if [ ! -d "$directory" ]; then
        continue
    fi

    # Get the name of the subdirectory
    subdir_name=$(basename "$directory")
    trimmed_subdir_name=$(trim_string "$subdir_name")

    echo "Current subdir: $subdir_name"

    skip=false
    # Check if the subdirectory is in the exclusion list
    for exclude in "${EXCLUDE_DIRS[@]}"; do
        trimmed_exclude=$(trim_string "$exclude")
        if [ "$trimmed_subdir_name" = "$trimmed_exclude" ]; then
            skip=true
            break
        fi
    done

    if [ "$skip" = true ]; then
        echo "Skipping excluded directory: $subdir_name"
    else
        echo "Processing directory: $directory"

        # Delete or print node_modules
        if [ -d "$directory/node_modules" ]; then
            if [ "$DRY_RUN" = true ]; then
                echo "[Dry Run] Would delete node_modules in $directory"
            else
                echo "Deleting node_modules in $directory"
                rm -rf "$directory/node_modules"
            fi
        else
            echo "node_modules does not exist in $directory"
        fi

        # Delete or print package-lock.json
        if [ -f "$directory/package-lock.json" ]; then
            if [ "$DRY_RUN" = true ]; then
                echo "[Dry Run] Would delete package-lock.json in $directory"
            else
                echo "Deleting package-lock.json in $directory"
                rm -f "$directory/package-lock.json"
            fi
        else
            echo "package-lock.json does not exist in $directory"
        fi

        # Delete or print yarn.lock
        if [ -f "$directory/yarn.lock" ]; then
            if [ "$DRY_RUN" = true ]; then
                echo "[Dry Run] Would delete yarn.lock in $directory"
            else
                echo "Deleting yarn.lock in $directory"
                rm -f "$directory/yarn.lock"
            fi
        else
            echo "yarn.lock does not exist in $directory"
        fi

        # Delete or print pnpm-lock.yaml
        if [ -f "$directory/pnpm-lock.yaml" ]; then
            if [ "$DRY_RUN" = true ]; then
                echo "[Dry Run] Would delete pnpm-lock.yaml in $directory"
            else
                echo "Deleting pnpm-lock.yaml in $directory"
                rm -f "$directory/pnpm-lock.yaml"
            fi
        else
            echo "pnpm-lock.yaml does not exist in $directory"
        fi
    fi
done

echo "Done!"
Enter fullscreen mode Exit fullscreen mode

Here's how you can call the script. Open up Cmder and type:

sh C:\path\to\your\script.sh -d
Enter fullscreen mode Exit fullscreen mode

The -d flag does a dry run, so you can see how it's going to effect your directories before you willy-nilly start deleting directories.

There is also a -e option to supply a file with a list of excluded directories. You don't need the full directory path in the list, just the relative pathname. So, for example, if you were running the script on C:\github and you want to skip C:\github\project1 and C:\github\project2, you would create an exclude.txt file with the following:

project1
project2
Enter fullscreen mode Exit fullscreen mode

Then you run the command:

sh C:\path\to\your\script.sh -e C:\path\to\exclude.txt
Enter fullscreen mode Exit fullscreen mode

That's it! Hope you enjoy. I know your backup software will be really happy with you! 🤣🙃

Resources


Thank You!

Thank you for taking the time to read my article and I hope you found it useful (or at the very least, mildly entertaining). For more great information about web dev, systems administration and cloud computing, please read the Designly Blog. Also, please leave your comments! I love to hear thoughts from my readers.

If you want to support me, please follow me on Spotify!

Current Projects

  • Snoozle.io- An AI app that generates bedtime stories for kids ❤️
  • react-poptart - A React Notification / Alerts Library (under 20kB)
  • Spectravert - A cross-platform video converter (ffmpeg GUI)
  • Smartname.app - An AI name generator for a variety of purposes

Looking for a web developer? I'm available for hire! To inquire, please fill out a contact form.

Top comments (2)

Collapse
 
pxlmastrxd profile image
Pxlmastr

Dude - This is actually genius.
Everyone up vote this post
We must get everyone to see this

Collapse
 
designly profile image
Jay @ Designly

Haha thanks. I appreciate your kind feedback! :D