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.
~/.config/yarn/global
for yarn