npm: using 'npm uninstall' vs. just removing the folder - npm

I wanted to try grunt-babel, so I opened up a terminal in my Home folder and did npm install --save-dev grunt-babel babel-preset-es2015 according to the plugin's instructions.
I was doing this too hastily, and realized I should probably have done this in my new project folder where I am dabbling with ES6 code. I had not even done npm init in that folder nor in the Home folder from where I executed the install command.
When I do npm uninstall grunt-babel, the preset files are removed but 91 folders of different dependencies remain in the node_modules folder.
Can I simply remove the folder instead of running npm uninstall 91 times?
This guy asked a similar question but none of the answers address his subquestion of just removing the folder: how to uninstall npm modules in node js?

npm uninstall <name> removes the module from node_modules, but not package.json.
npm uninstall <name> --save to also delete the dependency from package.json.
npm rm <package_name> removes the packages when uninstall not working
npm prune <name> (see docs) for extraneous packages and packages that are not listed on the parent package's dependencies list.
If you don't want to uninstall one by one run
rm -rf node_modules && npm cache clean && npm install
It's a good way for being sure the packages you uninstall are no more in the packages json.
Now in 2021 npm uninstall <name> will also removed it from package.json

UPDATED answer (2020):
These are all aliases to uninstall:
remove, rm, r, un, unlink
And today there is no need for --save flag since it is the default. The same goes for install BTW.

Use npm list as a tool to understand your changes. I usually use the time to make a capture file like:
npm list >1307
do some change
npm list >1309
so then:
cat 13??
or an editor lets me see what npm thinks it did.
For uninstall, only packages on the root all size of 'whole package' get removed. Other then that, the command is politely ignored...
For example:
├── safe-stable-stringify#1.1.0
├── semver#6.3.0
├─┬ tableify#1.1.0
│ └─┬ optimist#0.6.1
│ ├── minimist#0.0.8 deduped
│ └── wordwrap#0.0.3
safe-stable-stringify is a removal candidate, but wordwrap is not. Think about it, this is entirely reasonable !
npm uninstall pkgtoyank -save
updates packages.json by removing it from there as well.
npm is very well designed to say the least. I usually hugely avoid directly poking under it in ./node_modules I will copy things out from there to look at them, but why yank on a leash of a BIG CAT and get bit. it works; use it as its intended....

Related

How to remove optional peer dependency from NPM project?

I am participating in building a webapp that used to use node-sass. We migrated to sass in the meantime but we have still node-sass in our package-lock.json. I want to fix that.
In the beginning, we had something like this
$ npm ls node-sass
cookbook#0.9.13 /home/private/Documents/Projekte/nextcloud-apps/nextcloud-app-dev/volumes/custom_apps/cookbook
├── node-sass#7.0.1
└─┬ sass-loader#13.0.2
└── node-sass#7.0.1 deduped
OK, lets remove the dependency by calling npm uninstall node-sass. The result is
$ npm ls node-sass
cookbook#0.9.13 /home/private/Documents/Projekte/nextcloud-apps/nextcloud-app-dev/volumes/custom_apps/cookbook
└─┬ sass-loader#13.0.2
└── node-sass#7.0.1
I do not get the reason, why sass-loader is still depending on node-sass. OK, let's have a closer look:
$ npm why node-sass
node-sass#7.0.1 optional peer
node_modules/node-sass
peerOptional node-sass#"^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" from sass-loader#13.0.2
node_modules/sass-loader
sass-loader#"^13.0.2" from the root project
peer sass-loader#"^13.0.1" from #nextcloud/webpack-vue-config#5.3.0
node_modules/#nextcloud/webpack-vue-config
dev #nextcloud/webpack-vue-config#"^5.0.0" from the root project
Now I am a bit surprised. The package node-sass is only installed as a peer dependency. So, why is it installed at all? I thought the idea of peer dependencies is to allow for the root project to select the version in use.
Also, it is only optional. So, it should be able to remove it (eventually there might be a warning during removal but nothing serious).
I am not working on the #nextcloud/webpack-vue-config package. It is a mere dev dependency of the webapp. So, NPM should not install the node-sass as a dev dependency on any of my dependencies.
How can I remove the node-sass package from my project's package-lock.json? It is still anchored in the package-lock.json and thus installed on each build.
I could use the --no-optional CLI option of npm to skip over all optional dependencies. I do not want to do that. The "problem" with this is that the GitHub dependency checker will not consider the node-sass module as skipped and continue complaining. Also, other optional dependencies might be skipped as well, although we would like to have them.
I ran into this with node-sass and sass-loader the other day.
Easy solve for me was to remove #nextcloud/webpack-vue-config from my package.json, do an npm install then put it back and rerun npm install
that was enough to get the internals reset to make node-sass go away.

Can I re-create node_modules from package-lock.json?

I cloned a repository from github which has a package-lock.json (but no package.json). Then in a git bash terminal I go to the directory and run npm install but I just get a message saying there is no package.json and then everything in package-lock.json gets deleted so it's basically empty except for the project name and version.
I thought running npm install with a package-lock.json in the directory was enough to re-create node_modules, but am I seriously misunderstanding how this works? By the way I have node 8.12.0 and npm 6.4.1 and am running on Windows 10. Also, I think the package-lock.json was created on a unix system so could there be problems when using package-lock.json on a different OS?
I already tried running npm init just to get a package.json file and then running npm install but that still didn't get me a node_modules folder.
Starting from Mar 5, 2018, you can run npm ci to install packages from package-lock.json.
npm ci bypasses a package’s package.json to install modules from a
package’s lockfile.
https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable
package-lock.json records the exact version and url of packages need to install, thus you can use npm to install them accordingly:
npm can install from urls that point to tarballs
--no-package-lock option to tell npm to not touch package-lock.json file
For example, to install all packages in package-lock.json:
cat package-lock.json | jq '.dependencies[].resolved' | xargs npm i --no-package-lock
jq is a command line tool to pares jq, you can write a simple JavaScript script to parse it instead (if you do not want to install jq or learn jq's query syntax).
AFAIK, the package-lock.json file relies on the presence of a package.json file, so you'll not be able to recreate your node_modules folder from the package-lock.json file alone (happy to be proved wrong here).
Therefore, your best bet is to (mis)use a module like auto-install that is capable of generating the package.json file based on a project's dependencies, as they appear in the files.
Install it globally (npm install -g auto-install), then you'll need to generate an empty package.json file for it to run (use npm init -y in your project root). Kick things off with the command auto-install and it should add the dependencies to the package.json file.
HTH

Package.json pasting a package name in bad?

What happens differently when you go into your package.json and paste a package name in and do npm i vs. doing it the real npm i package-name?
package.json:
"dep": 1.0.0
vs
npm i dep --save
We have a build error and learned can bypass it by pasting. I know it isn't kosher but I really want to know why and what consequences that causes?
npm install dep doesn't add the dependency to the package.json file.
You have to add --save or --save-dev to add it to the package.json file.
Besides that, npm install will always serve you the latest build (in most cases the version tagged as latest (see npm docs)), unless you specify a specific version.
If you want your lock file to update, you have to delete the file before running npm install to generate a lock file with the dependency included (for more info check out this GitHub issue)
In conclussion it shouldn't make much of a difference if you manually add the dependency to package.json file and install it with npm install, unless the latest version of your dependency is broken.

Move a module from devDependencies to dependencies in npm package.json

Is there any short command to move a module from devDependencies to dependencies in package.json?
I find myself always doing this:
npm uninstall <module_name> --save-dev
npm install <module_name> --save
Is there a shorter approach to this?
Shorthand to move from devDependencies to dependencies (prod):
npm i <module_name> -P
If you want to do the opposite (i.e. move a module from dependencies to devDependencies) just do:
npm install <module_name> --save-dev
or shorthand:
npm i <module_name> -D
Yes! to move a module from devDependencies to dependencies:
npm install <module_name> --save-prod
In yarn:
Move a module from devDependencies to dependencies:
yarn remove <module_name> --dev && yarn add <module_name>
Move a module from dependencies to devDependencies :
yarn remove <module_name> && yarn add <module_name> --dev
As said in the comments, the command actually deletes the module and reinstall it in the new place.
The problem with using npm or yarn commands is that there is a chance that the version that is re-added is a different version than the one that is currently used. If this is what you want - both a move and an upgrade - then go ahead and use the accepted answer.
If not, simply manually edit your package.json to move the line from the devDependencies object to the dependencies object (creating it if necessary). You can go the other direction too.
The lock file doesn't hold any information about if things are prod or dev dependencies, so that doesn't need to be updated. You can do a npm/yarn install afterwards to fix up any flags in the lock files.
The issue of using npm install is that you end up with updated versions. What worked for me is:
Moving them to the intended part (dev, or prod)
Removing them from node_modules folder
Execute npm install
That kept all versions intact.
If your project doesn't have a lockfile or a shrinkwrap file yet, you can simply move the corresponding line in your package.json.
(I'm not recommending not using lockfiles)
I was trying to find an answer for this question for people that uses Yarn, but it hasn't a command for this matter yet.
Although, I believe it is not essential anyway.
Physically (in the Node modules folder) there are no difference between a dependency listed for production and the ones listed for development in your package.json, they'll go to the same place (node_modules).
So, if you need to switch a dependency from devDependencies to dependecies you can go to your package.json and move manually with no need to run a new install or remove the dependency and then install it again with the dev flag.
For me, it's not so great at all to manage the package.json manually, but Yarn is not as advanced as NPM in all functionalities, thus that's a thing to consider.
For Yarn, I moved them manually inside package.json and then ran yarn install. Yarn lock file does not get updated, so I think this is fine.

How to change npm path

All my npm packages work, but my npm package list shows empty. I am sure this is issue with a path but not sure how to fix it.
Which gulp gives me >
[~] ruby-2.2.3 $ which gulp
/usr/local/bin/gulp
Which npm gives me >
[~] ruby-2.2.3 $ which npm
/usr/local/bin/npm
npm list gives me >
[~] ruby-2.2.3 $ npm list
/Users/kimmo
└── (empty)
It looks like you are confusing packages that are installed globally with those locally. The paths for gulp and npm look like the global install locations. Packages you install locally will be found under a node_modules folder in the root of your project.
You can confirm this by comparing the results from:
npm ls -g --depth=0
npm ls --depth=0
The first command will show the globally installed packages. The second will show the local packages.
At the top of the resulting output, each shows the directory where the global or local install is located.
Finally, the --depth=0 flag only shows the packages that were required and not the dependencies of those packages (and those packages, etc). I find that most of the time, that's all I care about. If you agree, you can easily make this a default with npm config set depth 0 or by editing your .npmrc file in your home directory.
So! My guess is that you installed gulp with the -g flag but you haven't installed anything locally (with no flag, so to speak). That's why there's a difference between what which is showing and npm ls is showing.