How can I unflatten the node module? - node.js

My current npm version is 3.7.3 . Previously, only the required packages were getting installed in my node modules. But right now they have all flattened and have 100 + folders visible when I look into node modules. I prefer the older way where you could go into individual folders and see their dependencies.
here is a similar thread:
Why does npm install many packages into "/node_modules" instead of only one?
I tried running npm uninstall without much success.

Basically, you are out of luck... NPM does not provide any configuration options regarding this. It will nest dependencies if it must in order to resolve version conflicts, but only in this case. Your only option is to downgrade NPM (not recommended). However, if you just need to see the dependencies nested for informational reasons, you can use npm ls. It will draw you a graph.
See this relevant NPM issue for more discussion: https://github.com/npm/npm/issues/9809

Now that node js' LTS doesn't include an NPMv2 I found myself stuck with this issue again.
For those of you also caught out, the link that #KevinBurdett mentioned, also has some answers.
You can force downgrade npm using npm itself (using sudo or equivalent for this). From https://github.com/npm/npm/issues/9809#issuecomment-179702479:
as root I simply do npm install -g 'npm#<3' on my system every time I
a new version of Node comes out; your mileage might vary, but it's
fairly trivial to "downgrade" :-)
Another alternative is to use the Node Version Manager (NVM): https://github.com/creationix/nvm. Your mileage may vary depending upon personal config/preferences/platform.
That said, npm 3 and the issue of flat dependency trees will be with us from hereafter... It's probably high time to start accepting that change.
My personal grudge with this is that it makes the node_modules folder incredibly difficult to work with in an IDE, especially when you need to look at the implementation of your immediate dependent modules, without first wading through 100's of sub-sub modules that are irrelevant to me. It seems that I'm not alone in this matter when you read the comments in the issue. It only leads me to question the viability of npm itself when such changes are made without a proper migration from old to new systems. For me, npm2 will always be king.

Related

Is there an option that can show me what semantic versions of a particular npm package will resolve to?

For instance, say I have "foo: ^1.0.0" listed in my package.json and that project's released versions are [1.0.0, 1.1.0, 1.2.0, 2.0.0]. I want to find out what ^1.0.0 resolves to without installing or looking it up manually. Does a tool for this exist? I would expect it to be something like npm resolve foo#^1.0.0
Yes there is!
If you're using npm use view
npm view foo#^1.0.0
Otherwise you could use yarn with info
yarn info foo#^1.0.0
And in case you want even better statistics check out bundlephobia. It gives size estimations for the given version as well as the others and also an analysis of the exports.

npm: find out which dependencies use a given package (indirectly)

I'm currently working on a node.js-project and I've been keeping up with the most recent node releases during development. Now that node 6 is out, I wanted to see if I could make that decision as well.
It turns out some of the modules I use are dependent on older versions of graceful-fs which doesn't support node 6. I get warnings when installing and executing my application, but I can't determine where the graceful-fs package is being used (indirectly).
How can I find out?
I am fairly certain this is what you want:
npm ls graceful-fs
See documentation here.
Copying from #Soufiane Ghzal's comment and the npm-ls docs:
To get a "bottoms up" view of why a given package is included in the tree at all, use npm explain.

Publishing an npm package that strictly requires a minimum Node version

If I write a package I am certain requires Node 4 or higher, I don't want it to be installable with older versions.
I know about the package.json engines field, but that's just advisory (only causes a warning). And enginesStrict has been deprecated.
So what can I do?
One idea is to have a preinstall script that checks the Node version and errors if it's not high enough, preventing installation from continuing. Are there any problems with doing that? And is there a better way?
If you want a good experience, make your CLI entrypoint standard ES5 and CommonJS, detect the node version (process.version), and print a detailed and helpful message then exit non-zero. Keep in mind your module may get installed with some node version then the user futzes with nvm or their PATH or whatever and then runs your code under a different version. Thus I think failing nicely at run time is the most important thing. You can also choose to fail at install time if you like.

Node app fails to run because of prerelease

I get invalid packages installing, even if the installation is a success. Btw, this question is related to the answer - question about versioning
npm install serialport
These are packages which is stuck far in the dependency tree.
npm ERR! invalid: readable-stream#1.0.27-1 /Users/snorre edwin/Code/raspberry-node-server/node_modules/serialport/node_modules/node-pre-gyp/node_modules/tar-pack/node_modules/readable-stream
npm ERR! invalid: string_decoder#0.10.25-1 /Users/snorre edwin/Code/raspberry-node-server/node_modules/serialport/node_modules/node-pre-gyp/node_modules/tar-pack/node_modules/readable-stream/node_modules/string_decoder
This ends up causing this error in my browser:
Uncaught TypeError: Cannot read property '_ansicursor' of undefined
Is there any way to sort up in this npm problem? Can I avoid these prerelease packages?
The github answere below gave me a lot of insight into npm and I thought I had to dig somewhere else for the issue. But it acctually just seemed like serialport does not work very well, anymore, with browserify. It used to work because i used if for two months, but something changed. When im saying it out loud, it just sounds stupid anyway. So dont browserify serialport.
I recieved an answere on github, issue answere, thought i would share it with the rest who might wonder:
The change in handling prerelease versions in semver#4 is one of the primary motivators for the major version bump to npm#2. All versions of npm 2 are affected by this change, which, put briefly, ensures that all version information to the right of - in version strings is ignored when doing semver range matching. When you upgrade from npm#1 to npm#2, it's normal to see some irregularities show up when you run npm -g ls, and since some packages are distributed as self-contained installs via the use of bundledDependencies, they may come out of the package in a state that is inconsistent with npm#2's rules.
While this won't always work, most of the time the easiest way to fix these issues is simply to uninstall and reinstall the affected package. For packages that ship with bundledDependencies, if you really want to get everything cleaned up, you can cd into the node_modules folder containing the version of the package with the noisy prerelease dependency version and just run npm install problemDependency, and it will use the newest version of that dependency that matches the semver range for that particular package.
Re: your second question, semver range checking is done semantically, not lexically, so 1.0.31 should match with npm#2:
% semver -r '~1.0.2' 1.0.26 1.0.27-1 1.0.31
1.0.26
1.0.31
I suspect that the behavior you're seeing is due to a bundledDependency included in the package tarball.
All of this is documented, so I'm going to close this issue. I hope this clears things up for you!

npm installs dependencies with complete readme in a package.json -- invalid json results

Today I upgraded npm and node. I'm at 1.4.9 and 0.10.28, respectively. (OSX 10.9.2.)
Since then, it seems that npm install is writing "bad" package.json files for all of my dependencies.
Specifically, it is putting sevaral fields into the files that do not seem to be present in the source repo's package.json.
Like this example. I have about 40 dev dependencies and they all have this junk (not to pick on gulp, I just happened to grab it for this example):
"readme": "<p align=\"center\">\n <a href=\"http...",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/gulpjs/gulp/issues"
},
"_id": "gulp#3.6.2",
"_shasum": "ea6b33d768db4a22294fa6339afb61842f5e6fb5",
"_from": "gulp#~3.6.2",
"_resolved": "https://registry.npmjs.org/gulp/-/gulp-3.6.2.tgz"
These are on the root of the package.json object. Note, I've abbreviated the readme -- it's an entire html-ized version of the readme, and in many of the files it's not properly escaped and thus makes package.json invalid and unusable.
Obviously this leaves me dead in the water. My questions are "what did I do"? And how do I undo it? Did I wind up with a version of NPM that I shouldn't have? Could there be something else about my project, my node install, or the rest of my environment that might cause this? I do have nave and a version of node in the 0.11 family, but that's not active and hasn't been in recent history -- could npm update -g npm have discovered that I have 0.11 in a different directory and jumped me into territory to which I should not have gone? If so, how to I go backward? I've tried npm installing npm back down into earlier versions but npm still reports the higher version number as if my install didn't happen, and I can't quite figure out what version I'm supposed to have, anyway.
What I've tried so far -- reinstalling node and npm, wiping out my node_modules for the project, and npm cache clean. Nothing seems to have any effect. I'd be happy to answer any questions that I can about my environment that might help me resolve this.
TIA!
I just poked my way somewhat blindly into a solution.
(although I suspect it didn't matter, I upgraded to the master branch code of npm)
I believe that I fixed this by experimenting with setting long = false in my .npmrc file. No more readmes in package.json files! :)
Aside: the package.json content that I see is quite foreign to me in its arrangement, but I guess that may be a function of being on a newer version.
At the very least, the package.json is now valid json and life is better again. I'm not going to accept this, my own answer, just yet because I hope someone might be able to tell me why I needed to do this. This is an override in my .npmrc file as far as I understand it, so it seems bizarre that out of the blue I needed to add this override by hand based on no documentation....
I'll accept an answer that points me to an explanation of what happened or of what might have happened, if there is such an answer! If none are forthcoming, I'll just accept my own answer so that the SO question loop is closed. Thanks!

Resources