How to install multiple versions of the same node.js module? - node.js

Can I install multiple versions of the same node module globally with npm?

I don't think there is a (good) way to do this.
However, I'm guessing that your use case is this: You have two projects, which require different versions of a globally installed package.
For cases like this, I usually avoid installing packages globally altogether, and install them locally instead (without -g). For example, if you wanted to install a specific older version of the "mocha" package for a given project, you'd do
cd ~/src/myproject
npm install --save-dev mocha#^1.0.0
(Note that we're not using -g here.) Then call it like so:
./node_modules/.bin/mocha

While it is possible, it's probably going to be difficult to maintain without writing your own scripts to manage it. For this, I'm going to assume that you are using MacOS or Linux, and you have node installed in /usr/local/bin
When you install a global module, npm places the module and its dependencies in the same location that node is installed. Usually /usr/local/lib/node_modules, then creates a symbolic link for that module's in /usr/local/bin.
For example, you want to install nodemon, so you run npm install -g nodemon. npm installs nodemon to /usr/local/lib/node_modules/nodemon and creates a symlink at /usr/local/bin/nodemon that points to /usr/local/lib/node_modules/nodemon/bin/nodemon.js
Lets assume that you just installed nodemon#1.8.1, but for some reason you also need nodemon#1.7.3.
To have them both installed at once, but not conflict, you may be able to:
rename the directory for your existing copy of nodemon from nodemon to nodemon18
create a new nodemon18 symlink using ln -s /usr/local/bin/nodemon18 /usr/local/lib/node_modules/nodemon/bin/nodemon.js (don't forget to make it executable)
install nodemon#1.7.3 via npm install -g nodemon#1.7.3
Now, running nodemon from your terminal will run nodemon#1.7.3 and running nodemon18 will run nodemon#1.8.1.
YMMV. I really don't recommend doing this.

Not currently.
(Related: You can install multiple versions of node using with NVM (Node Version Manager): https://github.com/creationix/nvm)

Related

one dedicated directory for node_modules

I am quite new to npm but I have a question about npm node modules. I have the node modules now installed in several directories. One for Gulp, one for nodeJS etc. I was wondering how I could have one dedicated node modules directory and let the other packages point to that directory, instead of having node modules all over the place.
What is best practise?
Cheers,
Lino
Yes, you can have global node_modules directory accessible to multiple application.
A package is available globally if it is installed with -g option. For instance if body-parser is required globally it should be installed with the following npm command:
npm install body-parser -g
Following are the paths are usage of modules:
Local install (default): puts stuff in ./node_modules of the current
package root.
Global install (with -g): puts stuff in /usr/local or wherever
node is installed.
Install it locally if you're going to require() it.
Install it globally if you're going to run it on the command line.
If you need both, then install it in both places, or use
npm link.

Doesn't npm install check for a global version first?

I just setup a test, and tried to npm install express even though express already exists globally on my system. To my surprise, instead of using the global version, it ended up re-installing a version locally!? Isn't it supposed to use the global version... Or am I suppose to use -g every time, even when I only want to use the existing global version. Otherwise, what's the point of installing anything locally!?
The answer is "NO". It isn't supposed to use your global version.
If you want to use your global version, then you doesn't need to execute npm install at all because it is already installed.
If you do it then, obviously, you are saying "I want to install it locally to my project". And more than that: "I want to install its latest version unless it is declared in my package.json with other explicitly specified version".
In fact, the actual question is: Why in the hell would you want to not install a dependency of your project locally? To have more version mismatch issues?
As #anshuman_singh says, best practice is to always do an npm install --save.
You are able to use globally installed packages, of course. It could be handy for fast testing code that you will drop just after a few hours or so.
But, anyway: If you doesn't have really hard disk or network bandwidth issues, installing all dependencies locally will avoid you too much trouble in the future.
On the other hand, uploading that modules to your code repository is also a bad idea (maybe that is what you were trying to avoid) because, with different versions of node, most native modules won't work if not rebuild. But most VCS support ignoring files and or directories that must not be uploaded.
For example, in git (.gitignore file):
**/node_modules
In summary:
npm init (if you didn't already it).
npm install --save for all your project dependencies.
npm install --save-dev for dependencies not needed in production (testing stuff).
Don't upload node_modules to your VCS.
After new checkout: npm install or npm install --production (to not install dev-dependencies).
npm install -g only for tools you will use in console.
This way, you are sure that you will have in production (or other dev environments) the exact same version of each package.
And, finally, if you ever want to upgrade some package to its latest version, simply run:
npm install --save <pagkage_name>#latest.
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 first option is the best in my opinion. Simple, clear, explicit. The second is really handy if you are going to re-use the same library in a bunch of different projects
Install locally-
npm install moduleName
install locally and save in package.json-
npm install moduleName --save
install globally-
npm install moduleName -g

What does the -g option for npm install and npm list do?

The Node.js npm (Node Package Manager) has a -g command line argument, which I often see referenced. For example, the documentation for the Microsoft Azure x-plat (cross-platform) CLI tool says to install it by using npm install -g azure-cli.
Question: What does the -g option do?
What options do I have to install node modules?
After writing this I quickly found and old but still applicable post by Isaac (yes, the npm #isaacs). But I still think the below post is informational.
You can install npm modules globally or locally - you already know that, but why?
Globally: npm install -g some-module-a: This module is intended to be used as an executable (i.e. CLI, file watcher, code minifier, logger, etc.).
Locally: npm install some-module-b: To be imported and used in your app via import, var someModule = require('some-module)
global modules are one of the best ideas of npm. We can easily create executables using node/javascript. If your node app is meant to be run as an executable, then you will want others to install it globally. If it's a utility, helper, application, etc. then you usually don't want it installed globally. So, unless the module explicitly states that you should install it with -g, then don't.
One more time: if you are wanting to use some module called some-module in your node app - var someModule = require('some-module'), then npm install some-module from the root of your node app to pull it into your local node_modules directory. If you've installed some-module globally and not locally, it will usually not load and will show you an error about not finding the module (even though it can be made to load the global module - hint: just don't!)
So what exactly happens when you install globally?
npm install -g [some module] installs the specified node module in a directory higher up in your file system (i.e. usually /usr/local/lib/node_modules in unix systems). The biggest use case for global modules is for CLIs written using node (think npm, bower, gulp, grunt, et. al.).
Let's look at what happens when you install bower globally:
*follow these steps in your command line/terminal
step: npm install -g bower
explanation: the module - all of it's files and dependencies - are saved in your global directory (e.g. /usr/local/lib/node_modules/bower).
Something else happened here. Somehow you can now run bower in your command line. Awesome!
step: bower -v --> results in the installed bower version (i.e. 1.6.5)
explanation: It's now a fully executable node app using bower as the keyword. Inside bower's package.json file you'll find a bin property:
"bin": {
"bower": "bin/bower"
}
So how did that all work?
npm will create a symlink from where most executables live, /usr/local/bin/bower over to /usr/local/lib/node_modules/bower/bin/bower, where the module lives. That symlink makes it so when the executable runs, it can reference other files in the original module, including it's local node_modules. Pretty cool, huh?
*Note on executables: If you create a file called awesomeness in /usr/local/bin/ and chmod u+x (user + executable) it. Then write some scripting in it (in this case javascript using #!/usr/bin/env node at the top). Then you can run it anywhere in your command line/terminal just by typing awesomeness.
Hope that helped. I know doing a deeper dive into it helped me early on.
Node.js packages can be installed one of two ways:
Globally
Locally
The -g option instructs npm to install the package globally. You would install a Node.js package globally, if you want to be able to call the command directly from the terminal.
From the documentation:
There are two ways to install npm packages: locally or globally. You choose which kind of installation to use based on how you want to use the package.
If you want to use it as a command line tool, something like the grunt CLI, then you can 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.
To download packages globally, you simply use the command npm install -g , e.g.:

Node Version Manager (NVM) npm installing modules to common folder

I've installed NVM for node.js using the instructions from this post:
http://www.backdrifter.com/2011/02/18/using-nvm-and-npm-to-manage-node-js/
When I switch between node versions and then use npm to install a module, all the modules are placed in the same 'node_modules' folder (~/node_modules/) instead of in the 'node_modules' directory specific to that version of node?
Any idea on how to remedy this?
Based on the comments from https://github.com/creationix/nvm/pull/97:
When installing packages with npm using the global switch -g the
package ends up in the proper directory (i.e.
.nvm/$VERSION/lib/node_modules), however node is unable to require it
since it somehow isn't searching on it's prefix.
So using npm install -g xxxxx will put the modules in the correct location for NVM but if you try to require one of them node can't find the module. I am still playing around with this and will update if I find a solution.
Update
Where does NPM put node_modules? (see https://docs.npmjs.com/files/folders)
Local install (default): puts stuff in ./node_modules of the current package root.
Global install (with -g): puts stuff in /usr/local or wherever node is installed.
Install it locally if you're going to require() it.
Install it globally if you're going to run it on the command line.
If you need both, then install it in both places, or use npm link.
So what I did was run npm init (see http://npmjs.org/doc/init.html) in my projects root dir which generated package.json. Now when I run npm install xxxxx it creates a node_modules dir in my project folder (which I add to my .gitignore). This works for modules that I require in my code.
For commands such as CoffeeScript I install with npm install -g coffee-script which puts it in the correct directory (.nvm/$VERSION/lib/node_modules). While I can't require these modules (npm link should solve this problem) I can run the commands - i.e. coffee.
I just installed express globally (-g) and was having problem when require("express"). Just like Jesse Vogt said I just reinstalled express but this time without the -g just like this: "sudo npm install express" and now is working perfectly!
For latest nvm window version 1.1.7.
Package was installed and placed into the respective nodejs version.
nvm use 16.8.0
npm install truffle
nvm use 16.7.0
npm install mysql

How to include the coffee-script module in node using Cygwin on Windows

I'm trying to get the functionality of CoffeeScript.compile in node.js.
I've installed node on Cygwin in Windows, and installed coffee script with npm.
I can use the coffee command fine but if I try to
require("coffee-script");
I get "Cannot find module 'coffee-script'" in node.
Am I going about this the wrong way?
It sounds like require isn't looking in npm's global install path. Run
require.paths
from the Node REPL to see which paths are being looked in. On the command line, run
npm ls -g
to see the directory that npm is installing global libraries in (it's /usr/local/lib on my Mac). Add /node_modules to that, and add it to require.paths. You can do this on a one-time basis by running
require.paths.shift('/usr/local/lib/node_modules');
(Update: Modifying require.paths is no longer allowed as of Node 0.5+.)
or you can do it permanently by adding the line
export NODE_PATH=/usr/local/lib/node_modules
to your ~/.bashrc file.
Are you using from a different directory? If so, install it globally with the -g flag.
(npm install coffee-script -g).

Resources