npm - What does updating dependencies mean? - node.js

I see --save mentioned most of the time when installing packages. What does it mean in English? What do I lose if I don't use --save? Is it ok to just apply this option every time?
docs.npmjs.com/cli/install merely describes it as:
-S, --save: Package will appear in your dependencies
--Afternote:
I read the other question suggested as a duplicate, and I think that OP and myself were actually asking about what updating dependencies mean and not what what --save mean. It quite clear that --save means to save something, but for what purpose is the more important question. The documentation does not mention any reason. The answer given here by #nicovank helped me and I learned that it is for the purpose of duplicating the project in future, if I have not understood wrongly.

Using the save flag specifies to npm that this depedency will be saved in the package.json file, under dependencies.
You can use --save-dev to save under the devDependencies.
By using either one of those, the version saved will be for example ^1.0.0, meaning 1.0.0 or above. If you want to save the exact version you are using, use the --save-exact flag. This can be useful if you want to prevent changes in the library making your application unable to run.
Once all your dependencies are saved, you can later reinstall them all using npm install.
Is it ok to just apply this option every time?
Yes, and you should, to keep track of the dependencies of your project.
More documentation on install flags here.

Related

npm install package in absolute path (Locally and package.json)

First of all, huge apology for naive question and if this sounds duplicate.
I wish to install a package, for example material-ui, as an external dependency under a different path like ./node_module/my-material-ui. The problem is I don't seem to find any option to tell npm to do this other than --prefix option which actually doesn't help because it installs the package under ./node_module/my-material-ui/node_modules/material-ui. Infact, this makes sense since it prefixes the installation path. I searched around but didn't immediately find a solution.
Now as a following question, instead of individually (and locally) installing the aforementioned package using npm install ..., you wish to specify where the package has to be installed in package.json. In other words, how one can achieve the above goal by specifying that inside package.json.
Thanks in advance for your help and recommendations!
The migration guide covers this scenario.
yarn add material-ui#latest
yarn add material-ui-next#npm:material-ui#next
then
import FlatButton from 'material-ui/FlatButton'; // v0.x
import Button from 'material-ui-next/Button'; // v1.x

npm update unlinks linked packages

I have a project, which consists of one root node package containing subpackages linked together by npm link - these subpackages depend on each other (listed in package.json dependencies) and the structure basically looks like this:
-rootpackage
--subpackageA
--subpackageB
Lets say subpackageA has dependency on subpackageB, so I link them to avoid publishing/reinstalling subpackageB in subpackageA after every change in the source of subpackageB.
The link works just fine until I run npm update in subpackageA, which causes the subpackageB to be unlinked.
Now, I see two options:
I can theoretically run the npm link operation after each npm install or npm update to ensure the links are always present. This works with postinstall in case of installation, but in case of an update the postinstall is not called. I don't know any postupdate command for npm, which is to be called after update.
Maybe there is a way to do this more cleverly, perhaps with yarn, which I am also using, in a way, that it kind of prevents unlinking or excludes the update for my subpackages, so I don't lose the links between my subpackages, but right now I am not aware of such a way.
Is there any way to make one of those options work or any other way to solve this problem ? I need to keep this and other links so we don't have to run npm link after every installation/update. I can't really find information about this issue anywhere. Btw I am using Node 6.4.0 and NPM 3.10.3.
So the solution is to use Yarn Workspaces or maybe project like Lerna.
Yarn Workspaces is a utility that expects a structure similar to what was described in the question and which maintains the linking subpackages and root automatically. It is very easy to set up (just 2 lines in root package.json and executing yarn for the first time) and after it you don't have to worry about upgrade or install at all, the links stay in place unless you delete them manually.
Lerna expands on that and provides you with additional tooling for managing multipackage projects. It can use Yarn Workspaces internally for the linking if you use yarn but it is not a requirement and works fine with npm. Just make sure to have Git because last time I checked Lerna didn't work with SVN or other VCSs.

Use latest major version

In my JavaScript applications I may be declaring a few dozen dependencies in my package.json file.
It would take a while to go through each one of those dependencies and see which version they are on.
I just want to say: use the latest major version, but not the bleeding edge.
As an example, with a tool like Git I don't usually care about taking changes at the patch-level but if a new major release comes out I will want it.
Is there a similar concept when specifying the version of a npm module?
NPM packages (theoretically) use SemVer.
In SemVer, packages get a version number of X.Y.Z.
Z indicates bug fixes. Y indicates new features without changing existing ones. X indicates a major version that breaks backwards-compatibility.
Doing npm install --save <package> will result in a version string in your package.json like ^2.3.9, which means "anything in the 2.* range greater than or equal to 2.3.9". This'll mean you get bug fixes and non-breaking new features, but you won't unexpectedly be updated to a version 3.0.0 that breaks your application.
Note: I say "theoretically" because not everyone sticks to SemVer's ideal. You may find a 2.3.9 -> 2.3.10 upgrade that breaks stuff at times. Tests are handy here.
Using npm i -S <pkg> should normally do the right thing.
A few caveats:
The above assumes if you are taking a runtime dependency on <pkg>. In installing a developer tool (like grunt) use -D or -G instead of -S.
Semantic versioning rule 9 says that publishers MAY identify pre-release versions using a suffix like -beta. Npm depends on it, so if package publisher FAILS to do it, you might take a dependency on a pre-release package without knowing it. Sophisticated npm publishers should know better, and sophisticated npm consumers should check the documentation.
A major version is '0' indicates the package is still in initial development, and the package SHOULD NOT be considered stable. (Semantic versioning rule 4.)
Consider using npm dist-tag ls <pkg> to see if there is some package-specific tag that identifies your intent better than latest. If so, use npm I -S <pkg>#<tag> to track that tag.
You can always use npm outdated to check if you dependend directly on a package with a new major release might want to consider upgrading to. It is by-design that major version upgrades do not happen automatically.
npm-installnpm-dist-tagsemantic-versioning

Programmatic way of checking if npm packages in package.json are used in project?

If I have a project written in node, with a package.json and a number of directories/sub-directories, is there any way of checking that all modules listed in package.json are actually being used in the project?
Take the scenario of multiple people committing to the project, adding npm packages here and there, adopting new ones as the project progresses, but never removing the old ones.
If your objective is to remove existing packages that are not listed in the dependency list you can use npm prune. See https://www.npmjs.org/doc/cli/npm-prune.html.
Sorry, I misunderstood your question. You can try using npm-check. See https://www.npmjs.org/package/npm-check.

How do I promote a bundled dependency to a global module?

The obvious way to promote a bundled dependency to a global module is by moving the directory from node_modules/foo/node_modules/baz to node_modules/baz but is that all I have to do? Is there a secret handshake, without which things will mysteriously go wrong?
(While I'm asking yes/no questions: I notice that npm drops the node_module under whatever directory I happen to be in at the moment. Is this intended behavior -- I can see how it would be useful for recursive installation of dependencies -- or did I, with no sense of irony, mess up the installation of npm?)
(And speaking of yes/no questions about messed-up installations, my install of node does not automatically look in its own node_modules directory, I had to add it to NODE_PATH. Is this expected behavior?)
My appraisal after two days of node.js: great product, I don't see why it isn't even more popular than it is -- I'm most the way through solving a problem that is absolutely unsolvable in the standard Apache/Tomcat systems I'm used to -- but it's harder to find answers to really simply question, like the above, than the big-picture ones ("how do I connect to MySQL?" "how do I load-balance?")
npm as of version 1.0 changed how it did it's installations in terms of Global vs Local.
The short answer is if you want to install a module globally you can use the -g flag.
npm install awesome-module -g
If you want it locally you drop the -g flag.
If you want your module to only be installed globally you can add
"preferGlobal": true
to your package.json
As far as your second question goes, yes it is the intended behavior to drop node_module in whatever directory you're in, that's part of the local installation.
Link to npm 1.0 release blog: http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/

Resources