Best way to find the matching dependencies? - node.js

Is there any way to find the best match with the dependencies, for example I am using Angular v5.2.0, with some other dependencies I find some issues, now I want to find the dependencies that work with v5.2.0, for that I have search but no success.
Is there any website or source where we can easily get this?

i would run npm ls which lists all the installed packages with their dependencies (and also their versions) in a tree-structure (dependency tree). There you can see which version of a dependency X is needed/used by Angular v5.2.0.
If you have used a newer version of X in your package.json where you had some issues with, you can downgrade this version to the version which is actually used by Angular v5.2.0.

Related

Configuring package-lock.json to be source of dependency truth

I had the exact same question as Do I need both package-lock.json and package.json? (tldr; "what's the difference between package.json and package-lock.json?") and found some really great answers in there. However it leaves me with a few other very similar-related questions that I don't see answered elsewhere.
For instance, what if package.json and package-lock.json conflict with one another? Say package.json says to use some-lib-2.* (any 2.x version of some-lib) but package-lock.json is configured to use some-lib-1.18.4? Is there an error? Is preference given to either file as the "source of dependency truth"?
I like the idea of one file to manage my specific dependencies, and so I feel like I'm leaning towards:
Not specifying libraries or version in package.json at all; and
Using package-lock.json to specify the exact versions of each module/library my project uses
Is this possible to do? If so are there any special configurations that I need to make? Do I track both files in version control, or is there ever any reasons why I would not want to track these in git/VCS?
You use the the command line (npm install [optional args]) to update both files
NPM -- and your command line invocation -- decide what the acceptable ranges of dependency versions there are for module and define those ranges in package.json. It then picks a version within that range -- uses it for buildtime/runtime -- and writes that exact version in package-lock.json
So you want to place both files in version control so you have repeatable builds and any developers checking out your project will immediately be able to build the project with the same versions of the same dependencies
And the only time you edit package.json directly is if you don't want to allow a range of versions for a particular dependency and want to cherry pick the exact version to use. You make the edit, you save, you run npm install [options] and package-lock.json will be updated to use that version as well
For what it's worth, this is terribly confusing and advocates the anti-pattern of not managing your dependencies. It allows developers to think its OK to just pull in the latest version of a given dependency, even if that version changes from build to build. That leads to bug creep in your application, non-repeatable builds and all sorts of headaches.
I would strongly advocate for always specifying the exact version you want for all your direct dependencies: no more ranges or wildcards please.

How to disable package deduplication for a single dependency?

My Node/Electron project has a dependency graph sort of like this:
My Project
aaa#^4.0
bbb#^5.6
ccc#^1.0.0
ddd#^0.8
ccc#^1.0.1
eee#^4.4
eee#^4.3
npm install resolves this to the following node_modules:
aaa#4.0
bbb#5.6
ccc#1.0.1
ddd#0.8
eee#4.4
It figures that ccc#1.0.0 and 1.0.1 are compatible and deduplicates them, as it should. However, runtime errors indicate that they are, in fact, not compatible at all. That is, bbb#5.6 does not work with ccc#1.0.1 and requires 1.0.0.
Now, I could use --legacy-bundling so both versions would be installed, as nested modules in those that depend on them, but I don't want to do that for all dependencies. Specifically, there must be only one copy of eee at runtime.
How can I disable the deduplication for either aaa and all its dependencies or just for bbb? Preferably in NPM, but I'm willing to switch to Yarn or another tool if needed.
Edit: the question originally used ccc versions 1.0 and 2.0, but I was wrong, npm did in fact view those as not compatible and already installed them the way I wanted. My problem was with Webpack after all. So I've updated the question to the current version, which is still a possible scenario.
I've found that it can be achieved by
editing package-lock.json
and changing .["packages"]["node_modules/bbb"]["dependencies"]["bbb"]
from "^1.0.0"
to "1.0.0",
then running npm ci.
I have no idea if this is the proper way to do it, but at least running npm i doesn't overwrite the change.
Now I'm running into the problem that Webpack doesn't resolve bbb's import to the nested ccc, but that's outside of the scope of this question...

Can npm symlink node modules to a master directory instead of redownloading?

With npm, when a package requires other packages it creates a tree structure of dependencies. Sometimes a lot of these dependencies depend on the same packages from other packages.
I was wondering, would it be possible to make npm so all packages are stores in the global node_modules and any dependency is just symlinked back to the top of the global node_modules. I understand the version issue, and that can just be handled by storing the package with the version name appended, then symlinking to the proper version.
I feel this would speed up installs and reduce disk usage for duplicate files.
(Is this what npm3 is supposed to do?)
Yes, what you propose would be possible (at least on Linux the symlinks are resolved as expected).
npm (in none of its versions) however does not benefit from symlinks. To gain some of the benefits you proposed, newer versions of npm work as follows: if some package is needed multiple times, npm installs the package as high as possible in the dependency tree. This enables using the same dependency by multiple packages.
For example, no matter how many (sub-)dependencies depend on somedep v. ^1.x.x you got only one copy of somedep. This will probably be placed directly in the root node_modules, so that any sub-dependency can require it.
Older versions of npm do not do this automatically, however, you can invoke the similar effect by running 'npm dedupe'.
Note however, that this approach is weaker than proposed in the question: If 3 of your dependencies depend on somedep v. ^1.x.x and 3 other dependencies depend on somedep v. ^2.x.x, npm obviously cannot put both of these somedeps to the parent node_modules.
Also, check out ied project: https://github.com/alexanderGugel/ied . It does something similar to what you propose, but sadly, it installs only one version of each dependency, which is quite limiting.

nvm vs nave vs n | packages processing comparsion

Node.js is sometimes confusing when it comes to version management...
I am trying to arrange various projects as i am doing with ruby projects. For example:
With ruby i can create file such as .rvmrc and fill with something like rvm --create use 1.9.3#my-app
This thing creates and uses all gems specifically to configured gemset. Which allows to have various options for any kind of project, and switch easily among them. So ruby does this in one place.
I want to achieve this for node.js projects.
Node works differently. I want to know the details about that, and especially of each node version management tool.
The point is to know which version management tool for which goal...
And why there are so many.
More accurately: i want npm install <package-name> to chosen node version. And after switching to other versions, this installed package to be missing, or have different version installed before (or certain one). Just like gemset is working.
I've been looking for clarification too:
Both allow switching & installing between node versions.
nvm will symlink the different versions to /usr/local/bin/node, and n will move your node installs to the path (/usr/local/bin/node).
n downloads and installs binary files, and nvm downloads, compiles, installs from the source.
I don't fully understand the latter part of your question, but in regards having control with node projects/apps, you can use npm install [package_name] --save-dev to save your npms within your 'project'.
These npm module versions (^semver) get detailed in your package.json file, for example "gulp": "^3.8.5" is different from "gulp": "3.8.5" (the later being specific to v3.8.5, and the ^3.8.5 means allowing any future version of 3, but not 4.0.0)
The differences between npm and gem is that npm installs the specified packages in the local node_modules folder (the current working directory using the --save-dev), so you have less worries with cross project module versions.
Important note: Running --save (instead of --save-dev) installs any missing dependencies.
I hope that helps a little :o)
Just tried to install nvm and it works for switching from one version to another. In header of nave.sh it says "# This program contains parts of narwhal's "sea" program, as well as bits borrowed from Tim Caswell's "nvm"", so you might try both and see the tiniest difference. Also check the "popularity" of each and contributors to get some insight). There is also a nodeenv which uses python, but I don't any reason why use python here. So, my answer would be no big difference.

NodeJS and NPM : problems following recommendation to check modules into git

I'm having problems following the 'official' recommendation to check in all external dependencies into git (article http://www.mikealrogers.com/posts/nodemodules-in-git.html linked fron FAQ)
How do you make sure that not only top-level dependencies are checked-in? Most npm modules do currently not follow the recommendation. They all have their node_modules in .gitignore . Just Deleting their .gitignore seems risky.
For compiled module the article recommends to check-in only the sources and run 'npm rebuild' and deploy time. Unfortunately 'npm rebuild' does not do a 'clean make' for all modules (despite bugfix https://github.com/isaacs/npm/issues/1872 being included in npm version 1.0.106 i'm using). This means that I have to prevent compile targets from being checked in (otherwise i would have object code compiled for the developer machine on the production machine without being overwritten by npm rebuild). But: how do i do this? Unfortunately the modules don't have a common compile output directory, so just git-ignoring "node_modules//build" and "/node_modules//out/" (as mentioned in this good article eng.yammer.com/blog/2012/1/4/managing-nodejs-dependencies-and-deployments-at-yammer.html won't help in every case.
Short version: how do you make sure that production servers use the exact same version of all dependent modules as you use during development?
UPDATE: there is now npm shrinkwrap which solves the problem of locking down exact dependency versions, even of dependencies' dependencies! More info here.
Checking in node_modules can be problematic, as the environment it's running on may differ from user to user - so what is compiled on some environment may not work on another. Plus it would fill up your changelogs and repositories with 3rd party code. Which I take it is the conslusion you've come to with your short version of the question, so let me address that.
Short version: how do you make sure that production servers use the exact same version of all dependent modules as you use during development?
Inside your package.json, there will be dependencies: {}, if it is not there, then add it. To accomplish what you want, add your dependencies as the key, and their exact versions as the value. E.g. dependencies: { docpad: '2.5.0', mocha: '1.1.0' }
However, generally (it depends on the author) upgrades to the revision number (the x.x.X number) are just bugfixes and safe. You can allow minor changes by doing dependencies: { docpad: '2.5.x', mocha: '1.1.x' } which saves you from having to update your package.json and do a release everytime there is a bugfix release. You can even do things like 2.x if you wish.
This is the solution I've come to use for all of my modules, as it ensures that even 6 months later or whatever the module will still work - whereas doing something like >= 2.0.0 means when v3 of a dependency comes out, your module will probably be unusable at that time. Ensuring you stick to specific versions "guarantees" stability over time.
For reference you can see how I've done it in my open-source node.js modules here
About the .gitignore of your dependencies (in "node_modules"), npm 1.1 ignores the .gitignore files, so that they are not installed;
npm 1.1 will exclude .gitignore files from the things it installs.
npm 1.0 did not have this feature, so you have to be careful about that.
Deleting them recursively is fine:
find node_modules -name .gitignore | xargs rm
But, in npm 1.1, you never have to do this, because it excludes them
from the install automatically.
That's coming from the chief himself (Isaac), and it's here and seems to cover pretty much everything. The "extraneous" problem I have must be something silly I've done, I'll try a clean setup.

Resources