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

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

Related

npm - What does updating dependencies mean?

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.

Should I be installing node modules globally?

I have gotten better at using the command line. I now use it regularly for foundation, gulp, ionic, etc. One thing I always struggle with is should I be installing modules globally?
I just got a new computer and I am starting fresh. When I do my first Foundation Project, or set up Gulp, when it prompts me to run 'npm install' should I be installing that gloabally? And if I do, will I need to run npm install the next time I set up a Foundation Project?
I think that NPMs documentation really sums it up quite nicely:
If you want to use it as a command line tool, something like the grunt CLI, then you want to install it globally. On the other hand, if you want to depend on the package from your own module using something like Node's require, then you want to install locally.
https://docs.npmjs.com/getting-started/installing-npm-packages-globally
In this case, you should install locally since they are dependencies of the application and not general command line utilities.
This doesn’t fit the Q&A format too well, but I would in general advise against that. Installing modules globally may lead to side effects in other projects that depend on the same packages.
I don’t know what a “Foundation Project” is (and Google does not yield a clear answer), so I think you’d have to add a link explaining what that is.

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.

Is there any advantage installing modules like socket.io/express globally?

And if so, I'm interested in knowing if there is any way to run them from /usr/local/lib folder instead of installing those modules in each project's folder I'm working on.
The node documentation says that installing global modules should be relegated to those that require command line access ( such as nodemon etc.. ).
https://nodejs.org/en/blog/npm/npm-1-0-global-vs-local-installation/
Which to choose
Just like how global variables are kind of gross, but also necessary
in some cases, global packages are important, but best avoided if not
needed.
In general, the rule of thumb is:
If you’re installing something that you want to use in your program,
using require('whatever'), then install it locally, at the root of
your project.
If you’re installing something that you want to use in
your shell, on the command line or something, install it globally, so
that its binaries end up in your PATH environment variable.
The only other related issue I can think of to your question is that you can install express generator globally as it allows you to create an instance of their web scaffolding.
npm install express-generator -g
But that is different and not the same thing as installing express itself globally.
So as far as I can tell the answer is no - their is no benefit to this.
Well, personally, no. I ended up messing up my repos trying to globally install express and other modules. I really can't see the benefit of sparing a few extra seconds when you know it can't mess up your system :D And just to add, don't try globally installing mongoDB, REALLY ended up badly.

Node.js - Are package.json dependencies necessary when installing modules locally?

I know that doing something like this in package.json :
....
...
"dependencies" : {
"some-node-module" : "*"
}
is a bad idea since you're basically telling node to always update this module to its latest version, even though your code might not be able to handle any other version other than the current one for this particular module.
So I should instead do something like this :
....
...
"dependencies" : {
"some-node-module" : "3.4.1"
}
Which basically tells node to always use the version of the module that my code was built around.
Question
I have an app which I've first tested locally. The app has now been built, and using the package.json dependencies, npm has installed all of the appropriate node modules locally under my app's root folder (as opposed to globally, in some obscure folder I don't have immediate access to and which is irrelevant to this app - I simply don't like global installations of node modules - I find them to.. "abstract").
Given that all of the node modules are now installed locally isn't the node modules dependencies part in my package.json now redundant ?
I mean, what if something happens and npm is not available or the specific version of a module can't be found?
Isn't it best to be independent of dynamic node module installations and just have everything installed locally the first time without having to use the package.json dependencies ?
npm install & update
"you're basically telling node to always update this module to its latest version"
Packages won't be automatically updated. The only time the "*" will be an issue is when you are installing the project for the first time via npm install or when you manually run an update via npm update.
I personally prefer to pick a specific version of a module rather than use any wildcards, but even then there are some gotchas...which is why npm shrinkwrap exists.
npm shrinkwrap
Next gotcha:
basically tells node to always use the version of the module that my
code was built around
Sorta true. Let's say you use version 1.2.3 of your favorite module and package.json reflects that, but in the module itself is a package.json dependency on another module and that uses "*"...so when you install, the new internal dependency and the wildcard can wind up breaking the module you thought was 'locked down'.
See the gotcha? Hard coding a version controls for the top level versions but does not enforce anything beneath that...and if a module author you depend upon (or a module they depend upon) uses wildcards, you can't be 100% sure things will be copacetic.
To strictly enforce a version, you'll want to use npm shrinkwrap. (The link there to the docs provides more background, which is good to understand if your project uses more than a few very simple modules.)
And now...your question.
You say:
I mean, what if something happens and npm is not available or the
specific version of a module can't be found?
Based on the first two parts of this answer, it should now be clear that it doesn't hurt to have the dependencies explicitly listed in the package.json because node isn't checking things every time the app runs. npm uses package.json when specific actions (install, update, etc) are called but even then, it is a manual trigger.
While situations vary, there are very few that I can imagine where omitting dependencies in package.json is a good idea. If you ever wind up having to rebuild the project, you'll be in trouble. If the project is so good you want to share it, you'll be in trouble. Heck, if this is something for work and you want to go on vacation and need to install it on another machine...you'll be in trouble.
So given the fact that after the initial install, dependencies have no negative impact...use --save or add the dependencies to your package.json. Your future self will thank you. :)

Resources