1'use strict'; 2const path = require('path'); 3const os = require('os'); 4const fs = require('fs'); 5const ini = require('ini'); 6 7const readRc = fp => { 8 try { 9 return ini.parse(fs.readFileSync(fp, 'utf8')).prefix; 10 } catch (err) {} 11}; 12 13const defaultNpmPrefix = (() => { 14 if (process.env.PREFIX) { 15 return process.env.PREFIX; 16 } 17 18 if (process.platform === 'win32') { 19 // `c:\node\node.exe` → `prefix=c:\node\` 20 return path.dirname(process.execPath); 21 } 22 23 // `/usr/local/bin/node` → `prefix=/usr/local` 24 return path.dirname(path.dirname(process.execPath)); 25})(); 26 27const getNpmPrefix = () => { 28 if (process.env.PREFIX) { 29 return process.env.PREFIX; 30 } 31 32 const homePrefix = readRc(path.join(os.homedir(), '.npmrc')); 33 if (homePrefix) { 34 return homePrefix; 35 } 36 37 const globalConfigPrefix = readRc(path.resolve(defaultNpmPrefix, 'etc', 'npmrc')); 38 if (globalConfigPrefix) { 39 return globalConfigPrefix; 40 } 41 42 if (process.platform === 'win32' && process.env.APPDATA) { 43 // Hardcoded contents of `c:\Program Files\nodejs\node_modules\npm\.npmrc` 44 const prefix = path.join(process.env.APPDATA, 'npm'); 45 if (fs.existsSync(prefix)) { 46 return prefix; 47 } 48 } 49 50 return defaultNpmPrefix; 51}; 52 53const npmPrefix = path.resolve(getNpmPrefix()); 54 55const getYarnPrefix = () => { 56 if (process.env.PREFIX) { 57 return process.env.PREFIX; 58 } 59 60 if (process.platform === 'win32' && process.env.LOCALAPPDATA) { 61 const prefix = path.join(process.env.LOCALAPPDATA, 'Yarn'); 62 if (fs.existsSync(prefix)) { 63 return prefix; 64 } 65 } 66 67 const configPrefix = path.join(os.homedir(), '.config/yarn'); 68 if (fs.existsSync(configPrefix)) { 69 return configPrefix; 70 } 71 72 const homePrefix = path.join(os.homedir(), '.yarn-config'); 73 if (fs.existsSync(homePrefix)) { 74 return homePrefix; 75 } 76 77 // Yarn supports the npm conventions but the inverse is not true 78 return npmPrefix; 79}; 80 81exports.npm = {}; 82exports.npm.prefix = npmPrefix; 83exports.npm.packages = path.join(npmPrefix, process.platform === 'win32' ? 'node_modules' : 'lib/node_modules'); 84exports.npm.binaries = process.platform === 'win32' ? npmPrefix : path.join(npmPrefix, 'bin'); 85 86const yarnPrefix = path.resolve(getYarnPrefix()); 87exports.yarn = {}; 88exports.yarn.prefix = yarnPrefix; 89exports.yarn.packages = path.join(yarnPrefix, process.platform === 'win32' ? 'config/global/node_modules' : 'global/node_modules'); 90exports.yarn.binaries = path.join(exports.yarn.packages, '.bin'); 91