1000 ways to npm clean
Tags: npm, clean, javascript, git
Published: 2019-12-03 01:41:29

---
title: 1000 ways to npm clean
published: true
description: 1000 ways to npm clean
tags: npm, clean, javascript, git
---

Ok, well there's not really 1000 ways to npm clean, but it certainly feels like it. Below is my journey figuring out the best approach. And yes, I finally stumbled upon [**the holy grail**](https://medium.com/@codejamninja/1000-ways-to-npm-clean-1a514525a13c#30ab) of npm clean.

> SPOILER ALERT: Skip to the last approach if you don't have the patience to read through all of this.

rm -r
=====

Yep, classic Unix commands are probably the easiest way to create an npm clean script. This was my goto for quite a while because it just made sense coming from a Unix world.

It has drawbacks though . . . **windows != Unix**, so don't expect it to work on windows.

*package.json*

```json
{
  "scripts": {
    "clean": "rm -rf .cache .tmp lib build"
  }
}
```

rimraf
======

So, the solution to a cross-platform npm clean script is [rimraf](https://www.npmjs.com/package/rimraf). [rimraf](https://www.npmjs.com/package/rimraf) was bulit by the creator of npm in 2011 (back in the day when NodeJS was just beginning to gain traction). It works almost like *rm -r*.

I guess the only drawback is that you have to install it as a dev dependency.

*package.json*

```json
{
  "scripts": {
    "clean": "rimraf .cache .tmp lib build"\
  },
  "devDependencies": {
    "rimraf": "^2.6.2"
  }
}
```

clean script
============

Sometimes your build is so complex you need to describe the process in JavaScript. In this case, building a designated script for cleaning makes sense. If you build it right, you can simply add it to the *package.json* clean script.

This approach certainly has the drawback of requiring a lot of code for a simple task.

*package.json*

```
{
  "scripts": {
    "build": "node tools/build.js",
    "clean": "node tools/clean.js"
  },
  "devDependencies": {
    "fs-extra": "^7.0.1"
  }
}
```

*tools/clean.js*

```js
import fs from 'fs-extra';

import path from 'path';async function main() {\
  await clean();\
}

export default async function clean() {
  await fs.remove(path.resolve(__dirname, '../.cache'));
  await fs.remove(path.resolve(__dirname, '../.tmp'));
  await fs.remove(path.resolve(__dirname, '../lib'));
  await fs.remove(path.resolve(__dirname, '../build'));
}

if (typeof require !== 'undefined' && require.main === module) {
  main();
}
```

*tools/build.js*

```js
import clean from './clean';async function main() {
  await clean();
  await build();
}

export default async function build() {
  console.log('building something special . . .');
}

if (typeof require !== 'undefined' && require.main === module) {
  main();
}
```

git clean
=========

So . . . I did promise the **holy grail of npm clean**. It is probably safe to assume your node project is in a git repo. If it is, why not use git to clean your repo. I stumbled upon this fairly recently, and it is amazing. The *.gitignore* file already tells me everything I don't want in my repo.

The following command will remove all files from your git repo that are in your *.gitignore* file.

```sh
git clean -fXd
```

However, when I clean my repo, I don't want to remove all my dependencies in the process. Simply adding *!node_modules* and *!node_modules/**/** to the exclude flag will keep that folder. It's a double negative. You're basically saying **do not exclude node_modules**. Make sure you escape the bang so bash can understand it.

```sh
git clean -fXd -e \!node_modules -e \!node_modules/**/*
```

When adding it to our *package.json* clean script, we have to escape the escape symbol so JSON can parse it, hence it becomes *\\!node_modules* and *\\!node_modules/**/**.

The only drawback to this approach is it does not work unless you are in a git repo.

*package.json*

```json
{
  "scripts": {
    "clean": "git clean -fXd -e \\!node_modules -e \\!node_modules/**/*"
  }
}
```

If you have used other approaches for cleaning npm repositories, please let me know in the comments.