Search code examples
node.jsnpmdropbox

How to ignore node_modules recursively in Dropbox on a Mac


I want to keep all my node projects saved in Dropbox except I want to exclude all node_modules directories from being synced to Dropbox.

I used to accomplish this by keeping these directories symlinked in a different location but recent versions of npm have broken the ability to do this by not allowing npm_modules to be a symlink.


Solution

  • The following command will find and add all top-level node_module directories from Dropbox. That is to say that it will add node_module directories but not node_module directories somewhere inside of another node_modules directory (because the top-level directory will already be ignored.

    find ~/Dropbox  -type d | grep 'node_modules$' | grep -v '/node_modules/' | xargs -I {} -t -L 1 xattr -w com.dropbox.ignored 1 "{}"
    

    Command breakdown:

    • find all directories in ~/Dropbox
    • use grep to filter to only the directories that end in node_modules
    • use grep to exclude from these directories that also include node_modules/ **
    • use xargs to pass this directory as an argument
    • to the xattr command to tell dropbox to ignore it

    ** If a directory ends with node_modules but also includes node_modules/ then that directory is contained in a higher level node_modules directory so we can skip it because we will already be ignoring the higher level directory.


    Thanks to @shuckster for the following suggestion that eliminates the extra grep steps:

    The -prune find option can perform the above task more quickly than the two grep pipes:

    find ~/Dropbox -name node_modules -prune | xargs -I {} -t -L 1 xattr -w com.dropbox.ignored 1 "{}"
    

    The full command explained here.


    Thanks to @shuckster for the following bash function that will automatically do run this after an npm install

    Also, I have found it helpful to create a function in my .bashrc for npm that performs the permissions-update after an installation:

    npm() {
      case "$1" in
        "install"|"i"|"ci")
          command npm "$@"
    
          if [[ $? -eq 0 && -d ./node_modules ]]; then
            xattr -w com.dropbox.ignored 1 ./node_modules
            echo "Added Dropbox-ignore permission to node_modules"
          fi
          ;;
        *)
          command npm "$@"
          ;;
      esac
    }