|
|
|
|
var fs = require('fs')
|
|
|
|
|
var path = require('path')
|
|
|
|
|
var resolve = require('resolve').sync
|
|
|
|
|
var rc = require('rc')
|
|
|
|
|
var spawnSync = require('child_process').spawnSync
|
|
|
|
|
var isWin32 = process.platform === 'win32'
|
|
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
// resolvers
|
|
|
|
|
module.exports = [
|
|
|
|
|
nativeResolve,
|
|
|
|
|
nodePathResolve,
|
|
|
|
|
userHomeResolve,
|
|
|
|
|
nodeModulesResolve,
|
|
|
|
|
yarnModulesResolve,
|
|
|
|
|
prefixResolve,
|
|
|
|
|
execPathResolve
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
function resolveFn(module, basePath, dirname) {
|
|
|
|
|
try {
|
|
|
|
|
return resolve(module, {
|
|
|
|
|
basedir: path.join(basePath, dirname || '')
|
|
|
|
|
})
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// resolve using native require() function
|
|
|
|
|
// if NODE_PATH is defined, a global module should be natively resolved
|
|
|
|
|
function nativeResolve(module, dirname) {
|
|
|
|
|
try {
|
|
|
|
|
return require.resolve(module, dirname)
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// See: http://nodejs.org/docs/latest/api/modules.html#modules_loading_from_the_global_folders
|
|
|
|
|
// required?
|
|
|
|
|
function nodePathResolve(module, dirname) {
|
|
|
|
|
var i, l, modulePath
|
|
|
|
|
var nodePath = process.env.NODE_PATH
|
|
|
|
|
|
|
|
|
|
if (!nodePath) { return }
|
|
|
|
|
|
|
|
|
|
nodePath = nodePath.split(path.delimiter).map(function (nodepath) {
|
|
|
|
|
return path.normalize(nodepath)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
for (i = 0, l = nodePath.length; i < l; i += 1) {
|
|
|
|
|
if (modulePath = resolveFn(module, dirname || nodePath[i])) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return modulePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function userHomeResolve(module) {
|
|
|
|
|
var i, l, modulePath
|
|
|
|
|
var homePath = isWin32 ? process.env['USERPROFILE'] : process.env['HOME']
|
|
|
|
|
|
|
|
|
|
var paths = [
|
|
|
|
|
'node_modules',
|
|
|
|
|
'node_libraries',
|
|
|
|
|
'node_packages'
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
for (i = 0, l = paths.length; i < l; i += 1) {
|
|
|
|
|
if (modulePath = resolveFn(module, homePath, paths[i])) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return modulePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// See: https://npmjs.org/doc/files/npm-folders.html#prefix-Configuration
|
|
|
|
|
// it uses execPath to discover the default prefix on *nix and %APPDATA% on Windows
|
|
|
|
|
function prefixResolve(module) {
|
|
|
|
|
var modulePath, dirname
|
|
|
|
|
var prefix = rc('npm').prefix
|
|
|
|
|
|
|
|
|
|
if (isWin32) {
|
|
|
|
|
prefix = prefix || path.join(process.env.APPDATA, 'npm')
|
|
|
|
|
dirname = prefix
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
prefix = prefix || path.join(path.dirname(process.execPath), '..')
|
|
|
|
|
dirname = path.join(prefix, 'lib')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dirname = path.join(dirname, 'node_modules')
|
|
|
|
|
modulePath = resolveFn(module, dirname)
|
|
|
|
|
|
|
|
|
|
return modulePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolves packages using the node installation path
|
|
|
|
|
// Useful for resolving global packages such as npm when the prefix has been overriden by the user
|
|
|
|
|
function execPathResolve(module) {
|
|
|
|
|
var modulePath, dirname
|
|
|
|
|
var execPath = path.dirname(process.execPath)
|
|
|
|
|
|
|
|
|
|
if (isWin32) {
|
|
|
|
|
dirname = execPath
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
dirname = path.join(execPath, '..', 'lib')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dirname = path.join(dirname, 'node_modules')
|
|
|
|
|
modulePath = resolveFn(module, dirname)
|
|
|
|
|
|
|
|
|
|
return modulePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function nodeModulesResolve(module) {
|
|
|
|
|
var i, l, modulePath
|
|
|
|
|
var nodeModules = process.env['NODE_MODULES']
|
|
|
|
|
|
|
|
|
|
if (typeof nodeModules === 'string') {
|
|
|
|
|
nodeModules = nodeModules.split(path.delimiter)
|
|
|
|
|
for (i = 0, l = nodeModules.length; i < l; i += 1) {
|
|
|
|
|
if (modulePath = resolveFn(module, nodeModules[i])) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return modulePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function yarnModulesResolve(module) {
|
|
|
|
|
var i, modulePath;
|
|
|
|
|
|
|
|
|
|
// Retrieve yarn global path
|
|
|
|
|
var yarnCmd = isWin32 ? 'yarn.cmd' : 'yarn';
|
|
|
|
|
var result = spawnSync(yarnCmd, ['global', 'dir'], { encoding: 'utf8' });
|
|
|
|
|
|
|
|
|
|
if (!result.error && result.stdout) {
|
|
|
|
|
var yarnPath = result.stdout.replace(/[\r\n]+/g, '');
|
|
|
|
|
|
|
|
|
|
var nodeModulesStr = path.join(yarnPath, 'node_modules');
|
|
|
|
|
if (typeof nodeModulesStr === 'string') {
|
|
|
|
|
var nodeModules = nodeModulesStr.split(path.delimiter);
|
|
|
|
|
for (i = 0; i < nodeModules.length; i++) {
|
|
|
|
|
if (modulePath = resolveFn(module, nodeModules[i])) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return modulePath;
|
|
|
|
|
}
|