How do I import global modules in Node? I get "Error: Cannot find module <module>"?
Asked Answered
S

10

188

I am trying to setup Node on Mac OSX Lion. It all seems to work ok, but I can't seem to import anything modules from my global modules folder. I get the error,

Error: Cannot find module <module>

If I run this: node -e require.paths, the response I get is:

[ '/usr/local/lib/node_modules',
  '/Users/Me/.node_modules',
  '/Users/Me/.node_libraries',
  '/usr/local/Cellar/node/0.4.12/lib/node' ]

Which is correct, my modules are indeed installed in /usr/local/lib/node_modules. When I try and run a script, however, I am getting this:

Error: Cannot find module 'socket.io'
    at Function._resolveFilename (module.js:326:11)
    at Function._load (module.js:271:25)
    at require (module.js:355:19)
    at Object.<anonymous> (/Users/Me/node/server.js:2:10)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.<anonymous> (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)

My .bash_profile looks like this:

export PATH=/usr/local/mysql/bin:$PATH
export NODE_PATH=/usr/local/lib/node_modules
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/mysql/lib/"

Would really appreciate some help, I have no idea why I can't import any libraries.

Sheridansherie answered 1/11, 2011 at 18:8 Comment(11)
You know that this is not exactly the preferred way to do things, right?Intellectualize
Could you elaborate? Do you mean I shouldn't be installing libraries to my global folder?Sheridansherie
what happens if you ls into your project directory and type "npm list"Kuhlman
@Hanpan: The preferred way is to install modules you want to use via require() locally.Intellectualize
Similar question: #15636867Herta
require has no idea where your global installs are, but you can use npm link to generate symbolic links to global packages. Check out my answer below.Mayne
A better and more updated answer (that does not rely on npm link) can be found here: https://mcmap.net/q/56116/-nodejs-require-a-global-module-packageKnobby
"You know that this is not exactly the preferred way to do things, right?".Obscure
I'm old school and used to installing libraries in global locations. I've never seen any convincing reason for a heavy use of local library installs. The mongodb class i'm taking will end up with somewhere near a hundred small projects by the time we're finished, each one containing a mostly duplicate set of libraries - mongodb, express, consolidate, etc. The move to interactive languages leaves deposits of local libraries all over the place. I must have thousands of Scala libs in the local Scala repositories. Ditto Meteor, groovy and ruby.Obscure
Possible duplicate of NodeJS require a global module/packageJournalism
I am working for an open-source dev environment that targets React hosted in a Docker image. It uses global installed NPM packages. But it is considered as a development environment for several reasons: 1. yarn build or npm run build to bundle a React app for production. It does not require npm packages installed in production environment separately. You can achieve this by using webpack 2. It is easier to maintain our dev environment at same place for different React app projects. Only one time you have to link the deps into your React app by using "npm link". If you like to contribute or benAngkor
D
152

If you're using npm >=1.0, you can use npm link <global-package> to create a local link to a package already installed globally. (Caveat: The OS must support symlinks.)

However, this doesn't come without its problems.

npm link is a development tool. It's awesome for managing packages on your local development box. But deploying with npm link is basically asking for problems, since it makes it super easy to update things without realizing it.

As an alternative, you can install the packages locally as well as globally.

For additional information, see

Diaphaneity answered 1/11, 2011 at 18:56 Comment(12)
I am reading this and can not believe my eyes. So if I install, say express, and then have 20 projects to build on top of express, I need to install it 20 times, for each of them, in every project folder, over and over? I don't have much experience with package managers but this kinda sucks...Clemons
That's correct, and if you think about it, it makes sense. Managing your dependencies locally makes keeps everything self-contained and allows you to specify a specific version of a dependency for any given project (e.g. project foo requires express 2.x, while project bar can use the express 3 beta).Pye
I struggled to understand the logic of this for a while as well, but after watching my Ruby friends struggle with global package updates, argue about gemsets and often simply never upgrade, I have conceded that installing dependencies locally is absolutely the only sane way to do package management.Tenderhearted
I'd like to draw a parallel between this situation and that of static-linking vs. dynamic-linking libraries as it pertains to the distribution of software. Consider that almost all Apps distributed on the iOS App Store must statically link dependencies not provided by the iOS SDK. Why is this done? Global dependency hell is a very real thing.Elytron
It is also my understanding that npm's cache (which lives in ~/.npm) will make expedient the reinstallation process performed in your different locations.Elytron
@StevenLu's analogy for iOS apps is flawed. Yes, I have to link them statically. But I don't have to copy the source to every single project. I can tell Xcode "hey, go use that source". One piece of source code in one place. No duplication.Radack
that doesn't make my analogy flawed, i wasnt referring to the source code, I was referring to the generation of machine code (which doesn't get shared)Elytron
Please include the relevant info in the answer itself :) ThanksDetain
this shouldn't be accepted at all, tricks are for kids, and nm link is one of them.Tangential
Nodejs also looks for /node_modules, so you could also create a symlink from root to your global node_modules, for example: sudo ln -s /usr/local/lib/node_modules /.Sansom
@StevenLu Distribution of dynamically linked code can be solved. It does require cooperation among package developers, however; there's no infrastructure-only solution, per my knowledge. The biggest problem is how to manage versioning of independent packages so that any valid combination can be installed simultaneously without conflict, and any invalid combination is disallowed.Journalism
@Tenderhearted No it is not, unless robust and fully automated deduplication (requiring zero attention from package/module authors) is built into the package manager as a first-class fundamental level-0 feature, rather than everyone and their cousin writing mutually incompatible deduplicating wrappers, as is the case with pnpm, yarn and others.Shutz
S
178

Node.js uses the environmental variable NODE_PATH to allow for specifying additional directories to include in the module search path. You can use npm itself to tell you where global modules are stored with the npm root -g command. So putting those two together, you can make sure global modules are included in your search path with the following command (on Linux-ish)

export NODE_PATH=$(npm root --quiet -g)

Sift answered 19/4, 2017 at 19:40 Comment(8)
Thanks for the NODE_PATH environment variable hint. That helped a lot!Extractor
This should be the top commentSustentacular
I had to set NODE_PATH to the equivalent posix path to make npm work on MSYS2. Thank you.Quote
Works with Windows and Git bash too. Perfect. :-)Quadriceps
This makes your .node_modules folder searchable, but in order to import modules using require(), they should still be installed in your local project directory (or alternatively, linked using npm link). Global modules cannot be imported in projects, only binaries/scripts can be run from there.Demos
Works on Mac OSX. I am using a single JS file and using global modules. Much simpler to handle.Sanskrit
node --help shows all the environment variables (including NODE_PATH). (Verified with node v17.0.1.)Baziotes
If you are on windows cmd, you can do it via FOR /f "tokens=* delims=" %A in ('npm root --quiet -g') do set "NODE_PATH=%A" or FOR /f "tokens=* delims=" %%A in ('npm root --quiet -g') do set "NODE_PATH=%%A" in a batch file.Embus
D
152

If you're using npm >=1.0, you can use npm link <global-package> to create a local link to a package already installed globally. (Caveat: The OS must support symlinks.)

However, this doesn't come without its problems.

npm link is a development tool. It's awesome for managing packages on your local development box. But deploying with npm link is basically asking for problems, since it makes it super easy to update things without realizing it.

As an alternative, you can install the packages locally as well as globally.

For additional information, see

Diaphaneity answered 1/11, 2011 at 18:56 Comment(12)
I am reading this and can not believe my eyes. So if I install, say express, and then have 20 projects to build on top of express, I need to install it 20 times, for each of them, in every project folder, over and over? I don't have much experience with package managers but this kinda sucks...Clemons
That's correct, and if you think about it, it makes sense. Managing your dependencies locally makes keeps everything self-contained and allows you to specify a specific version of a dependency for any given project (e.g. project foo requires express 2.x, while project bar can use the express 3 beta).Pye
I struggled to understand the logic of this for a while as well, but after watching my Ruby friends struggle with global package updates, argue about gemsets and often simply never upgrade, I have conceded that installing dependencies locally is absolutely the only sane way to do package management.Tenderhearted
I'd like to draw a parallel between this situation and that of static-linking vs. dynamic-linking libraries as it pertains to the distribution of software. Consider that almost all Apps distributed on the iOS App Store must statically link dependencies not provided by the iOS SDK. Why is this done? Global dependency hell is a very real thing.Elytron
It is also my understanding that npm's cache (which lives in ~/.npm) will make expedient the reinstallation process performed in your different locations.Elytron
@StevenLu's analogy for iOS apps is flawed. Yes, I have to link them statically. But I don't have to copy the source to every single project. I can tell Xcode "hey, go use that source". One piece of source code in one place. No duplication.Radack
that doesn't make my analogy flawed, i wasnt referring to the source code, I was referring to the generation of machine code (which doesn't get shared)Elytron
Please include the relevant info in the answer itself :) ThanksDetain
this shouldn't be accepted at all, tricks are for kids, and nm link is one of them.Tangential
Nodejs also looks for /node_modules, so you could also create a symlink from root to your global node_modules, for example: sudo ln -s /usr/local/lib/node_modules /.Sansom
@StevenLu Distribution of dynamically linked code can be solved. It does require cooperation among package developers, however; there's no infrastructure-only solution, per my knowledge. The biggest problem is how to manage versioning of independent packages so that any valid combination can be installed simultaneously without conflict, and any invalid combination is disallowed.Journalism
@Tenderhearted No it is not, unless robust and fully automated deduplication (requiring zero attention from package/module authors) is built into the package manager as a first-class fundamental level-0 feature, rather than everyone and their cousin writing mutually incompatible deduplicating wrappers, as is the case with pnpm, yarn and others.Shutz
M
82

You can use npm link to create a symbolic link to your global package in your projects folder.

Example:

$ npm install -g express
$ cd [local path]/project
$ npm link express

All it does is create a local node_modules folder and then create a symlink express -> [global directory]/node_modules/express which can then be resolved by require('express')

Mayne answered 27/4, 2014 at 0:14 Comment(2)
Is this cross-OS compatible?Themselves
Newer versions of Windows support it since this version: github.com/npm/npm/commit/… For older Windows versions try npmjs.com/package/npm-junctionNovobiocin
C
28

Install any package globally as below:

$ npm install -g replace  // replace is one of the node module.

As this replace module is installed globally so if you see your node modules folder you would not see replace module there and so you can not use this package using require('replace').

because with require you can use only local modules which are present in your node module folder.

Now to use global module you should link it with node module path using below command.

$ npm link replace

Now go back and see your node module folder you could now be able to see replace module there and can use it with require('replace') in your application as it is linked with your local node module.

Pls let me know if any further clarification is needed.

Colbycolbye answered 27/11, 2015 at 7:57 Comment(1)
I had a similar issue and this trick worked for me. Thanks Konrad KrakowiakWoolsack
N
21

You can use require with the path to the global module directory as an argument.

require('/path/to/global/node_modules/the_module');

On my mac, I use this:

require('/usr/local/lib/node_modules/the_module');

How to find where your global modules are? --> Where does npm install packages?

Narra answered 15/9, 2016 at 6:0 Comment(0)
F
9

Setting the environment variable NODE_PATH to point to your global node_modules folder.

In Windows 7 or higher the path is something like %AppData%\npm\node_modules while in UNIX could be something like /home/sg/.npm_global/lib/node_modules/ but it depends on user configuration.

The command npm config get prefix could help finding out which is the correct path.

In UNIX systems you can accomplish it with the following command:

export NODE_PATH=`npm config get prefix`/lib/node_modules/
Fudge answered 28/5, 2018 at 6:12 Comment(0)
N
3

Easy answer is to run node in npm global root directory.

cd $( npm root -g ) && node
Nicholson answered 20/4, 2021 at 19:9 Comment(0)
A
0

I am using Docker. I am trying to create a docker image that has all of my node dependencies installed, but can use my local app directory at container run time (without polluting it with a node_modules directory or link). This causes problems in this scenario. My workaround is to require from the exact path where the module, e.g. require('/usr/local/lib/node_modules/socket.io')

Adroit answered 28/1, 2016 at 16:2 Comment(0)
E
0

If you are on windows cmd, you can do it via FOR /f "tokens=* delims=" %A in ('npm root --quiet -g') do set "NODE_PATH=%A" or FOR /f "tokens=* delims=" %%A in ('npm root --quiet -g') do set "NODE_PATH=%%A" in a batch file.

Embus answered 23/3, 2022 at 2:33 Comment(0)
D
-2

require.paths is deprecated.

Go to your project folder and type

npm install socket.io

that should install it in the local ./node_modules folder where node will look for it.

I keep my things like this:

cd ~/Sites/
mkdir sweetnodeproject
cd sweetnodeproject
npm install socket.io

Create an app.js file

// app.js
var socket = require('socket.io')

now run my app

node app.js

Make sure you're using npm >= 1.0 and node >= 4.0.

Dubai answered 1/11, 2011 at 19:1 Comment(2)
He's asking about using globally installed npm packages.Themselves
@Jamund. You are showing how to use locally installed package, but original question was about global ones.Sidwel

© 2022 - 2024 — McMap. All rights reserved.