Reputation: 15099
I'm trying to install globally and then use forever
and forever-monitor
like this:
npm install -g forever forever-monitor
I see the usual output and also the operations that copy the files to the global path, but then if I try to require("forever");
I get an error saying that the module wasn't found.
I'm using latest version of both node and npm and I already know about the change that npm made in global vs local install, but I really don't want to install localy on every project and I'm working on a platform that doesn't support link
so npm link
after a global install isn't possible for me.
My question is: why I can't require a globally installed package? Is that a feature or a bug? Or am I doing something wrong?
PS: Just to make it crystal clear: I don't want to install locally.
Upvotes: 235
Views: 126028
Reputation: 3
If you are a Windows user, you can quickly set the NODE_HOME
environment variable using the powershell command:
for machine (need Administrator)
[Environment]::SetEnvironmentVariable("NODE_PATH", $(npm root -g), "Machine")
for user:
[Environment]::SetEnvironmentVariable("NODE_PATH", $(npm root -g), "User")
Hope this helps Windows users.
Upvotes: 0
Reputation: 3246
In Node.js, require doesn't look in the folder where global modules are installed.
You can fix this by setting the NODE_PATH environment variable. In Linux this will be:
export NODE_PATH=/usr/lib/node_modules
Note that it depends on where your global modules are actually installed.
For a more sustainable solution, you can dynamically set your NODE PATH to:
export NODE_PATH=$(npm root -g)
See: Loading from the global folders.
Upvotes: 295
Reputation: 1
i tried following the other answers but what worked for me was
node_path = "C:\\Users\\{usename}\\AppData\\Roaming\\npm\\node_modules"
const *modulename* = require(node_path + "\\" +'*modulename*');
Upvotes: 0
Reputation: 6719
For CLI utilities that depend on big modules, like puppeteer
, I like to spawn a npm root -g
and use it to require the global module.
try {
const root = require('child_process').execSync('npm root -g').toString().trim()
var puppeteer = require(root + '/puppeteer')
} catch (err) {
console.error(`Install puppeteer globally first with: npm install -g puppeteer`)
process.exit(1)
}
Upvotes: 13
Reputation: 166349
As per documentation, Node.js will search in the following locations by default:
Path specified in the NODE_PATH
environment variable.
Note: NODE_PATH
environment variable is set to a colon-delimited list of absolute paths.
Current node_modules
folder. (local)
$HOME/.node_modules
(global)
Note: $HOME
is the user's home directory.
$HOME/.node_libraries
(global)$PREFIX/lib/node
(global)
Note: $PREFIX
is Node.js's configured node_prefix
.
To check the current value of node_prefix
, run:
node -p process.config.variables.node_prefix
Note: Prefix corresponds to --prefix
param during build and it's relative to process.execPath
. Not to confuse with value from the npm config get prefix
command.source
If the given module can't be found, that means it is not present in one of the above locations.
Location of global root folder where modules are installed can be printed by: npm root -g
(by default the path is computed at run-time unless overridden in npmrc
file).
You can try the following workarounds:
Specify your global module location in NODE_PATH
environment variable. E.g.
echo 'require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node
To test and print the value of NODE_PATH
, run:
echo 'console.log(process.env.NODE_PATH); require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node
For more permanent solution, link your $HOME/.node_modules
global user folder to point to the root folder, by running this command:
ln -vs "$(npm root -g)" "$HOME"/.node_modules
Then re-test it via: echo 'require("forever")' | node
command.
Temporary change the current folder to where the extension has been installed globally, before invoking the script. E.g.
npm install -g forever
cd "$(npm root -g)"
echo 'require("forever")' | node
cd -
Configure global installation destination in npm
userconfig file (see: npm help 5 npmrc
) or by userconfig
param (--prefix
).
To display the current config, run: npm config list
.
To edit the current config, run: npm config edit
.
Specify the full path of node modules location when calling require()
. E.g.
require("/path/to/sub/module")
Install the package to custom location, e.g.
npm install forever -g --prefix "$HOME"/.node_modules
However, the installation will go under ~/.node_modules/lib/node_modules/
, so the location still needs to be added.
Create a symlink in the current folder from the location of the global package. E.g.
npm link forever
Upvotes: 30
Reputation: 421
You can put this line in your .profile
file:
export NODE_PATH="$(npm config get prefix)/lib/node_modules"
This will make node
use the global path.
Upvotes: 6
Reputation: 1102
Apologies for the necromancy but I'm able to specify hard-coded paths to globally installed modules:
var pg = require("/usr/local/lib/node_modules/pg");
This isn't perfect but considering that Unity3d tries to "compile" all javascript that is included in the project directory I really can't install any packages.
Upvotes: 37
Reputation: 47993
After you install package globally you have to link the local project with global package
npm install express -g
cd ~/mynodeproject/
npm link express
See here
Upvotes: 127
Reputation: 1787
I know this is an old question, but I ran into this when trying to do some version checking using semver
in a preinstall
script in package.json
. Since I knew I can't depend on any local modules installed, I used this to require semver
from the global node_modules
folder (as npm
depends on it I know it's there):
function requireGlobal(packageName) {
var childProcess = require('child_process');
var path = require('path');
var fs = require('fs');
var globalNodeModules = childProcess.execSync('npm root -g').toString().trim();
var packageDir = path.join(globalNodeModules, packageName);
if (!fs.existsSync(packageDir))
packageDir = path.join(globalNodeModules, 'npm/node_modules', packageName); //find package required by old npm
if (!fs.existsSync(packageDir))
throw new Error('Cannot find global module \'' + packageName + '\'');
var packageMeta = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json')).toString());
var main = path.join(packageDir, packageMeta.main);
return require(main);
}
I like this approach because this doesn't require the install of any special modules in order to use.
I didn't go with a NODE_PATH
solution like others have suggested since I wanted to get this to work on anyone's machine, without having to require additional configuration/setup before running npm install
for my project.
The way this is coded, it is only guaranteed to find top-level modules (installed using npm install -g ...
) or modules required by npm
(listed as dependencies
here: https://github.com/npm/npm/blob/master/package.json). If you are using a newer version of NPM, it may find dependencies of other globally installed packages since there is a flatter structure for node_modules
folders now.
Hope this is useful to someone.
Upvotes: 23
Reputation: 39395
You can use the package requireg
to solve this problem:
var forever = require('requireg')('forever')
will do the trick.
Also, there's another module, global-npm
, while specific to just using the global npm
, you can look at the short code and see how the technique works.
Upvotes: 17