jonschlinkert / global-modules

Returns the directory used by NPM for globally installed NPM packages.
https://github.com/jonschlinkert
MIT License
35 stars 7 forks source link

npm root -g should be the correct global node_module path? #7

Open lcxfs1991 opened 7 years ago

lcxfs1991 commented 7 years ago

Hi, I found that the result from npm root -g should be the correct path. However sometimes global-modules will find the wrong one when we use nvm to manage our node versions.

Do you have any ideas?

doowb commented 7 years ago

Hi @lcxfs1991, I'm also using nvm and I get the same path when I do npm root -g and console.log(require('global-modules')).

Do you have any code examples that show you are getting an error or different results? Also, if you could provide details about the OS, node version, and npm version, it'll help us determine if there is a bug or not.

axnsan12 commented 6 years ago

Hello,

I have the same issue when using https://github.com/ekalinin/nodeenv on Windows 10.

> node --version
v8.9.4

> npm --version
5.6.0

> npm root -g
C:\test-project\.env\Scripts\node_modules

> where nodejs
C:\test-project\.env\Scripts\nodejs.exe

> where npm
C:\test-project\.env\Scripts\npm.cmd

> nodejs
> require('global-modules');
'C:\\Users\\<MYUSER>\\AppData\\Roaming\\npm\\node_modules'
doowb commented 6 years ago

@axnsan12 I don't know anything about nodeenv but this module uses global-prefix which will fall back to using which to find the npm path. which will use the environment variable $PATH to search for npm. If nodeenv isn't setting $PATH correctly, then which won't be able to find npm and global-prefix will fallback to the path you see.

axnsan12 commented 6 years ago

@doowb which doesn't exist on Windows (without cygwin at least). You should be using where. I coincidentally also have cygwin installed, but you're right, nodeenv on Windows does not set the cygwin $PATH, only the windows %PATH%.

Is there any reason you're not just running npm root -g?

EDIT: I see now that you linked to the node module which, not the system binary. Still, the windows %PATH% is set properly when using nodeenv, as you can see from my where output.

doowb commented 6 years ago

@axnsan12 will you run the following:

> nodejs
> console.log(process.env.PATH);
axnsan12 commented 6 years ago

Sure, here it is:

C:\test-project\.env\Scripts;C:\Program Files\Far Manager\ConEmu\Scripts;C:\Program Files\Far Manager;C:\Program Files\Far Manager\ConEmu;C:\Program Files\Docker\Docker\Resources\bin;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64\compiler;C:\ProgramData\Oracle\Java\javapath;C:\Python36\Scripts\;C:\Python36\;C:\Python27\Scripts;C:\Python27;C:\bin\imagemagick;C:\Program Files\MongoDB\Server\3.4\bin;C:\cygwin64\bin;C:\Program Files (x86)\PuTTY\;C:\Program Files\Git\cmd;C:\bin;C:\Android\sdk\platform-tools;C:\Android\sdk\tools;C:\Users\axnsan\Application Data\npm;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\ProgramData\chocolatey\bin;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\OpenVPN\bin;C:\Program Files\dotnet\;C:\Program Files (x86)\IDA 6.8;C:\Program Files\Calibre2\;C:\Windows\System32;C:\Program Files (x86)\Skype\Phone\;C:\Go\bin;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\nodejs\;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\;C:\Ruby24-x64\bin;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Program Files\OpenVPN\bin;C:\Program Files (x86)\PuTTY\;C:\Program Files\Git\cmd;C:\Python27\Scripts;C:\Python27;C:\bin;C:\Android\sdk\platform-tools;C:\Android\sdk\tools;C:\Program Files\nodejs\;C:\Users\axnsan\Application Data\npm;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Users\axnsan\AppData\Local\Microsoft\WindowsApps;C:\texlive\2016\bin\win32;C:\Program Files (x86)\Diffuse;C:\Users\axnsan\AppData\Roaming\npm;C:\Users\axnsan\AppData\Local\GitHubDesktop\bin

Bonus:

> which.sync('npm')
'C:\\test-project\\.env\\Scripts\\npm.CMD'
> which.sync('nodejs')
'C:\\test-project\\.env\\Scripts\\nodejs.EXE'
> require('global-modules');
'C:\\Users\\axnsan\\AppData\\Roaming\\npm\\node_modules'

(the expected path would be C:\\test-project\\.env\\Scripts\\node_modules)

doowb commented 6 years ago

Thanks, I don't have access to an environment setup like yours and that's why I'm asking for this information.

I might have to look into this more, but the main logic is in global-prefix. The npm path is only used to check for builtin or global config files that may contain the prefix property. If that's not found, then it falls back to windows logic that looks to see if process.env.APPDATA is set and uses that (this must be the case in your situation). This was added in this PR to address when npm is installed using npm i -g npm.

Maybe the correct way is to check if the prefix exists after building the APPDATA version and using process.execPath if that path doesn't exist. I think this will still be faster than executing npm root -g (add still work when npm is in APPDATA).

If you could go to global-prefix and open an issue or do a PR with changes for handling this situation so we can discuss it more there, I'd appreciate it.

kachkaev commented 5 years ago

Seems like there is a similar issue for macOS users who follow these official instructions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally#manually-change-npms-default-directory. They are essential for people who do not have admin rights on their machine, which is very prevalent, say, in education environment.

Running npm root -g gives /Users/myUsername/.npm-global/lib/node_modules, which does not match the result of global-modules. Feels like the package needs fixing.

clembu commented 4 years ago
$ echo $PWD
/data/bs
$ npm root -g
/home/me/.npm-global/lib/node_modules
$ node
> require("global-modules")
/data/bs/~/.npm-global/lib/node_modules

Seriously? It appends a path begining with ~ to the current directory? How do you guys manage to not expand ~?