Local NPM modules not installing correctly - node.js

Local NPM modules are no longer installing correctly for me in my projects node_modules dir. This has just started happening.
I set up a test dir with a package.json:
{
"name": "test",
"version": "0.0.0"
}
Then ran this command:
npm install grunt --save-dev
This is what I get in my node_modules dir:
Opening the grunt dir you can see there’s no node_modules:
Some of the NPM modules that appear in the root are what appears to be NPM modules belonging to the grunt NPM module, and some I have no idea where they are coming from? E.g. abbrev, esprima, graceful-fs, etc.
I used to get this:
project
│
└───node_modules
| │
| └───grunt
|
└───package.json
I’ve tried completely removing Node.js and NPM from my machine (Mac OS X 10.10.5) following these instructions. Then reinstalling it outside of Homebrew (where it was previously installed) which didn’t change anything. Then completely removing Node.js and NPM again and reinstalling it with Homebrew but this time I applied this. Again this didn’t fix anything.
Not sure what’s going on?

This is expected behavior. When you install grunt, npm recursively installs all its dependencies. These may be put to grunt/node_modules or may be put on the same level as grunt (directly in the top level node_modules). Both these options will work, which is because of how node works: if grunt requires some package (for example, colors) and node does not find it in grunt's node_modules directory, node tries to find the package in the parent's dir, then in grandparents dir and so on.
Out of these two options, older npm versions prefer the first option, newer versions prefer second option (i.e. more flat dependency tree), which is exactly your case.
In your case, packages such as 'async' or 'colors' are grunt dependencies (check out its package.json), 'abbrev' is not direct dependency of grunt, but probably it is dependency of some other dependency.
More reading:
https://docs.npmjs.com/cli/dedupe
https://github.com/alexanderGugel/ied
https://docs.npmjs.com/cli/shrinkwrap

Related

How do I check node_modules directory for unnecessary packages?

My node_modules has packages that are not listed in my package.json's dependencies, so I'm guessing that those packages are dependencies of my dependencies. How would I be able to check this? I want to make sure that there aren't any unnecessary packages in my node_modules directory.
If your dependency list won't take too long to reinstall, a simple option is a table-flip: remove the node_modules directory entirely and run npm install to re-create it.
If you don't want to do that, you can try tools that inspect your dependencies, like depcheck as #sagar-gopale suggests in their answer.
Related: Run npm -v to find out if you are running npm v2 or v3. Like #cartant says in their answer, with v3, your node_modules directory will be maximally flat, which means things that used to appear as subdirectories of other modules (when installed with npm v2) will now appear at the top level of node_modules itself. That may be the reason you see more modules than you expect.
If you are using NPM 3, you will likely see a large number of modules that you were not expecting to see in the node_modules directory, as NPM 3 flattens the dependency hierarchy.
Whichever version you are using, if you run the npm list command, NPM should highlight any extraneous modules that are not required.
Please checkout this package.
https://www.npmjs.com/package/depcheck
Since packages can require other packages, just because there are packages in the node_modules folder that don't exist in your packages.json file doesn't mean they aren't needed by one of your specified packages.
If you run an npm prune command on the root directory of your solution it will read the dependency tree and remove the packages that are truly no longer needed.

npm install generate more folders than needed

I've been using ember for a while and when I wanted to install the node dependencies of a project, I just needed to use npm install to create the folder node_modules with all the dependencies (as it's described in http://ember-cli.com/user-guide/).
Since I was using an old version of node I unisntalled node and npm and installed nvm with the versions node v5.0.0 and npm v3.3.6but now, when I try to use npm install to install the dependencies of a project as I used to do before, instead of the dependencies of the package.json file, I get many, many more from things I'm not sure where they come (I think they are dependencies that npm handles by itself in a globally way but now it's adding them to my project locally, but I'm not sure).
Why am I getting all those unknown (for me) dependencies?
Notice that, when I run ember new it generates the correct dependencies in node_modules but if I delete this folder and run npm install happens the same.
That's one of the changes introduced by npm v3.0:
Your dependencies will now be installed flat - by default. If
possible, all of your dependencies, and their dependencies, and their
dependencies will be installed in your project's node_modules folder
without nesting. Nesting will only occur when two or more modules have
conflicting dependencies.
Read more at http://www.felixrieseberg.com/npm-v3-is-out-and-its-a-really-big-deal-for-windows/

NPM installing package with multiple folders for package

I recently started a new node project and ran npm install *name* --save for both express and nodemon and noticed that 20-30 folders appear in my node_modules folder related to the two packages instead of just express and nodemon. This has never happened when I have run this command with previous projects. Is there any reason why this is happening now?
I expected my node_modules folder to only have "express" and "nodemon"
npm version: 3.3.6
node version: 5.0.0
Stumbled upon your post with a Google Search and thought I'd link the answer :
Your dependencies will now be installed maximally flat. Insofar as is
possible, all of your dependencies, and their dependencies, and THEIR
dependencies will be installed in your project's node_modules folder
with no nesting. You'll only see modules nested underneath one another
when two (or more) modules have conflicting dependencies.
See npm#3's release notes.

How to prevent npm install <package> --save-dev from reordering devDependencies

Background
We're having issues with a Windows build system hitting the file path too long error when the node modules folder has items within it that have paths which are over 260 characters.
We've discovered adding a deeply nested dependency to the top of the devDependencies section fixes this issue. The assumption is that when npm sees a nested dependency C.1 require package A, which is already declared and available in devDependencies, npm will not add dependency A to dependency C.1's node_modules directory.
Issue
The problem I'm seeing on my local machine is that running npm install <package> --save-dev reorders the packages in devDependencies alphabetically, but the order npm process packages and their dependencies matters. If I check this in, then the build system will hit the same file path too long error.
ie If package A comes after package C and dependency C.1 requires package A, then npm will add package A to the node_modules folder of dependency C.1.
I'm not sure if this reordering is only on my machine since I haven't seen npm reorder dependencies on my home machine before.
Has anyone seen this before or know how to stop this behavior?
Versions
Node: v0.10.32
NPM: v1.4.28
Side note: I've read that npm 2.0 or future versions will analyze the dependency hierarchy, find duplicated packages, and only reference them once on the file system, but the upgrade to npm 2.0 is not in the picture at this time.
The only way I see this working is to have some sort of preinstall script which [hopefully] will run after the dependencies file has been updated but before the package is installed. From the npm site:
In the current version of node, the standard way to do this is using a
.gyp file. If you have a file with a .gyp extension in the root of
your package, then npm will run the appropriate node-gyp commands
automatically at install time
If that doesn't work, you will need to use MakeFile and rewrite the package.json file. This is not too out of the ordinary as some projects require some sort of pre-compilation - you would just instruct your team to run a separate command for installing npm packages.

path is also the name of a node core module

I've just got back into node after a few months, and I'm a bit hazy on what I'm doing
I updated npm, node and gulp. My gulp file seems to work, but I just went to install gulp-compile-handlebars but I get the following:
Cooldude-MacBook-Air:_overlay cooldude$ sudo npm install --save-dev gulp-compile-handlebars
Password:
npm WARN package.json path#0.4.9 path is also the name of a node core module.
gulp-compile-handlebars#0.2.0 node_modules/gulp-compile-handlebars
├── through2#0.4.2 (readable-stream#1.0.27-1, xtend#2.1.2)
└── handlebars#2.0.0-alpha.4 (optimist#0.3.7, uglify-js#2.3.6)
Cooldude-MacBook-Air:_overlay cooldude$ ls
gulpfile.js.old node_modules src
I've not seen this before - what should I do to fix this?
This is not due to the gulp-compile-handlebars module since he has (and none of it's dependencies) no call to the path module.
I think that you have directly in the package.json of your project a reference to the path dependency that you need to remove because this is now a core module, so you don't have to put it in the dependencies of your project.
If it's not referenced, it certainly means that one of your dependencies has the path dependency. You can't do anything about that (expect a PR or an issue on the repo if available).
By the way it's just a Warning npm shows you, not an error so don't need to worry about that.

Resources