316

Is there a way to get npm to unbuild all the modules under node_modules? Something like npm rebuild that removes all build artifacts but doesn't rebuild them?

8
  • 4
    Thought you'd never ask. I've been checking my node_modules directory into git as recommended in mikealrogers.com/posts/nodemodules-in-git.html. When I add a new module or update a current one, I end up with build artifacts in git that shouldn't be there and have to clean them up. I was thinking if I could clean them first the process would go a little more smoothly. Commented Jul 5, 2012 at 20:24
  • 1
    One quick note: now that NPM supports shrinkwrap (see npmjs.org/doc/shrinkwrap.html), you can lock the versions of ALL your dependencies (instead of just the top level ones). Commented Jul 5, 2012 at 22:39
  • 2
    Not having this feature sucks for cross platform development as well. We develop on Mac and run CI on Linux, and need to remove the node_modules directory and completely re-install each time we do a build on Linux, which wastes a ton of time. Commented Aug 15, 2014 at 16:45
  • 7
    @JBCP you're doing it wrong. What you should be doing is installing modules in packages.json (using npm --save) and putting the node_modules directory in .gitignore (if using git). CI should not pull your node_modules, but execute npm install. Finally, if downloading from npm registry takes too long, use something like sinopia to cache it. Commented Jul 1, 2015 at 7:28
  • 1
    @BojanMarkovic - You are correct, this is how our projects are setup now. My comment above was from about a year ago. There are (were) a few projects that recommended committing node_modules into Git, but that is definitely not correct. Commented Jul 2, 2015 at 16:52

11 Answers 11

236

There is actually special command for this job

npm ci 

It will delete node_modules directory and will install packages with respect your package-lock.json file

More info: https://docs.npmjs.com/cli/ci.html

Sign up to request clarification or add additional context in comments.

3 Comments

Actually if you working with other team members and they updated some dependencies you should always do npm ci and not just npm i. The main reason that npm i also updates the lock file and this is probably that you don't want todo.
The OP didn't specify that they were building a fresh project, so just be careful with this when you are the one doing the updating of dependencies as the only way to update the package-lock file would be to run npm i. Its a little misleading because it's called "clean install" but thats not necessarily what it does. Would be better named like rebase or something. If you rely on your project version to be in package.json as well, package-lock doesn't get updated either until you do an npm i, though thats not as big of a deal.
@FDisk you saved my day
226

You can just delete the node_module directory

rm -rf node_modules/ 

12 Comments

This would remove the source of the node_modules as well as the compiled output, so doesn't answer the question.
If you have dependencies linked with npm link it might as well delete these modules source in it's source directory which can be quite painful...
I added this to my package.json: "clean": "rm -rf node_modules", "reinstall": "npm run clean && npm install", "rebuild": "npm run clean && npm install && npm run build",. Seems to work well.
For windows> rd node_modules /s
@Lucas you should post this an an answer as it's the most suitable one
|
102

I added this to my package.json:

"build": "npm build", "clean": "rm -rf node_modules", "reinstall": "npm run clean && npm install", "rebuild": "npm run clean && npm install && npm run build", 

Seems to work well.

6 Comments

use 'rm -rf node_modules' in case linux based machine, incase of windows 'rmdir /s /q node_modules'
To use these you can't call "npm clean" since clean isn't one of the accepted names on npm. You need to do "npm run clean".
Note that your reinstall is now built-in command: npm ci
npm ci does not simply delete and reinstall all modules; it is mainly meant for deploy envs, and doesnt modify the package-lock.
rm -rf will not work on windows. Script's should be multiplatform compatible.
|
32

Try https://github.com/voidcosmos/npkill

npx npkill 

it will find all node_modules and let you remove them.

npkill

2 Comments

thank you for your answer. out of curiosity, could you share how did you do the animation? :)
22

npm ci works for this scenario, but only when your package.json and package-lock.json are in sync, which might not always be the case if you have been working on either one to resolve conflicts quickly or are updating on the directory level by removing directories/symbolic links. A comprehensive answer to the question would be this..

  1. Edit the package.json with what ever you want and remove what you dont need.
  2. Generate the package-lock.json like this, npm install --package-lock-only
  3. Run npm ci. This should remove all artifacts and shouldn't rebuild them.

2 Comments

For anyone who ran this command and it failed, try npm ci --legacy-peer-deps
This worked for me. Even when the node_modules folder is gone and you do npm ci or npm install --force, it is not enough and can fail. That npm install --package-lock-only and then doing npm ci worked!!!! Thank you.
9

You can take advantage of the 'npm cache' command which downloads the package tarball and unpacks it into the npm cache directory.

The source can then be copied in.

Using ideas gleaned from https://groups.google.com/forum/?fromgroups=#!topic/npm-/mwLuZZkHkfU I came up with the following node script. No warranties, YMMV, etcetera.

var fs = require('fs'), path = require('path'), exec = require('child_process').exec, util = require('util'); var packageFileName = 'package.json'; var modulesDirName = 'node_modules'; var cacheDirectory = process.cwd(); var npmCacheAddMask = 'npm cache add %s@%s; echo %s'; var sourceDirMask = '%s/%s/%s/package'; var targetDirMask = '%s/node_modules/%s'; function deleteFolder(folder) { if (fs.existsSync(folder)) { var files = fs.readdirSync(folder); files.forEach(function(file) { file = folder + "/" + file; if (fs.lstatSync(file).isDirectory()) { deleteFolder(file); } else { fs.unlinkSync(file); } }); fs.rmdirSync(folder); } } function downloadSource(folder) { var packageFile = path.join(folder, packageFileName); if (fs.existsSync(packageFile)) { var data = fs.readFileSync(packageFile); var package = JSON.parse(data); function getVersion(data) { var version = data.match(/-([^-]+)\.tgz/); return version[1]; } var callback = function(error, stdout, stderr) { var dependency = stdout.trim(); var version = getVersion(stderr); var sourceDir = util.format(sourceDirMask, cacheDirectory, dependency, version); var targetDir = util.format(targetDirMask, folder, dependency); var modulesDir = folder + '/' + modulesDirName; if (!fs.existsSync(modulesDir)) { fs.mkdirSync(modulesDir); } fs.renameSync(sourceDir, targetDir); deleteFolder(cacheDirectory + '/' + dependency); downloadSource(targetDir); }; for (dependency in package.dependencies) { var version = package.dependencies[dependency]; exec(util.format(npmCacheAddMask, dependency, version, dependency), callback); } } } if (!fs.existsSync(path.join(process.cwd(), packageFileName))) { console.log(util.format("Unable to find file '%s'.", packageFileName)); process.exit(); } deleteFolder(path.join(process.cwd(), modulesDirName)); process.env.npm_config_cache = cacheDirectory; downloadSource(process.cwd()); 

1 Comment

I find it very strange that such a basic functionality, that is actually recommended by npm, requires a hack to achieve. What does everyone else do? Just ignore the recommendation and use npm install?
7

npm ci

As mentioned by FDisk You can use npm ci to remove node modules folder and re-install npm packages from scratch.

npm prune

Alternatively, you can also use npm prune to remove extraneous packages installed inside your node_modules folder that aren't defined inside the package.json


References:

Comments

6

In a word no.

In two, not yet.

There is, however, an open issue for a --no-build flag to npm install to perform an installation without building, which could be used to do what you're asking.

See this open issue.

Comments

5

For windows environment:

"scripts": { "clean": "rmdir /s /q node_modules", ... } 

Comments

5

I have added few lines inside package.json:

"scripts": { ... "clean": "rmdir /s /q node_modules", "reinstall": "npm run clean && npm install", "rebuild": "npm run clean && npm install && rmdir /s /q dist && npm run build --prod", ... } 

If you want to clean only you can use this rimraf node_modules.

1 Comment

For Mac or Linux users: "clean": "rm -rf node_modules",
4

I have done this in my package.json

"scripts": { "clean": "rm -rf ./node_modules package-lock.json .cache dist && npm i", } 

1 Comment

it is better to use rm -r using the f parameter is not recommended

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.