zkat / npx

execute npm package binaries (moved)
https://github.com/npm/npx
Other
2.63k stars 105 forks source link

npx fails to find npm on Windows 10 #58

Closed wavebeem closed 7 years ago

wavebeem commented 7 years ago
Windows 10: version 1703
Shell: PowerShell
node: 8.1.2
npm: 5.2.0
npx: 9.0.3

image

image

zkat commented 7 years ago

huh!

I don't understaaaaaand.

I think in this case, this is an npm bug, but I'm fine tracking it here. Basically, something's really weird with what https://github.com/npm/npm/blob/latest/bin/npx-cli.js#L6 is doing when executed through https://github.com/npm/npm/blob/latest/bin/npx.cmd, and I think I'm just misunderstanding how __dirname is going to work for that .cmd shim.

Does this work at all if you do npm i -g npx@latest and try again?

zkat commented 7 years ago

I'm curious whether you or @seriousManual can still repro this when using CMD.EXE instead of powershell. 🤔

warpdesign commented 7 years ago

@zkat For your information: I am getting the same error not found... with cmd.exe

I have opened an issue on npm but closed it when I saw npx was here: should I open it again?

seriousManual commented 7 years ago

hi @zkat i am using cmd.exe, not powershell

ocombe commented 7 years ago

Same problem here, using cmder (which uses ConEmu). Installed with npm i npm@latest, got npm 5.2.0 and npx 9.0.3. Running npx -v works fine, but running a command doesn't work:

npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32
not found: C:\Users\Olivier\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js

When I try to open "C:\Users\Olivier\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js" it works fine (the file exists)

Per your suggestion I tried:

npm i -g npx@latest
C:\Users\Olivier\AppData\Roaming\npm\npx -> C:\Users\Olivier\AppData\Roaming\npm\node_modules\npx\index.js
+ npx@9.0.7
added 507 packages in 12.131s

It still fails but with another error (same error as bug https://github.com/zkat/npx/issues/61):

npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32
npx: installed 1 in 4.432s
npx: command not found: 4bc19503fe9e9309e2bfaa2c58074d32
C:\Users\Olivier\AppData\Roaming\npm\node_modules\npx\node_modules\libnpx\index.js:139
    process.on('exit', () => rimraf.sync(prefix))
                                    ^

TypeError: rimraf.sync is not a function
    at process.on (C:\Users\Olivier\AppData\Roaming\npm\node_modules\npx\node_modules\libnpx\index.js:139:37)
    at emitOne (events.js:96:13)
    at process.emit (events.js:188:7)
warpdesign commented 7 years ago

The problems seems to be with the which package, called in getNpmCache:

function getNpmCache(opts) {
  return which(opts.npm).then(npmPath => {
     const args = ['config', 'get', 'cache', '--parseable']
    if (opts.userconfig) {
      args.push('--userconfig', child.escapeArg(opts.userconfig, true))
    }
    return child.exec(npmPath, args)
  }).then(cache => cache.trim())
}

In Linux it calls which('/usr/lib/node_modules/npm/bin/npm-cli.js') which works and simply returns the path we call it with: /usr/lib/node_modules/npm/bin/npm-cli.js.

Under Windows, it calls which('C:\Users\Nicolas\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js') which fails with:

Error: not found:  C:\Users\Nicolas\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js

The path is valid:

dir C:\Users\Nicolas\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js
 Volume in drive C has no label.
 Volume Serial Number is D6FC-769F

 Directory of C:\Users\Nicolas\AppData\Roaming\npm\node_modules\npm\bin

03/06/2017  01:42             2 749 npm-cli.js
katemihalikova commented 7 years ago

A sequel to my debugging in #60.

Error not found: C:\Users\katem\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js. It is only present in bundled npx and only when trying to run a package that is not already installed. @warpdesign located the problem to which package.

The root of the problem is that js files are never executable on Windows. cmd.exe can't read shebang.. which is trying to find an executable, but there is none, so it correctly fails. The solution is to run it through node executable instead:

  const args = buildArgs(specs, prefix, opts)
- return which(opts.npm).then(npmPath => {
-   return child.spawn(npmPath, args, {
+ return which('node').then(nodePath => {
+   args.unshift(opts.npm);
+   return child.spawn(nodePath, args, {
      stdio: [0, 'pipe', opts.q ? 'ignore' : 2]

opts.npm is used in getNpmCache and installPackages functions.
opts.npm is C:\Users\katem\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js on my box.

This solution moves me forward to the error in #61 😄

This problem is not present in npx package because it's using npm binary from node_modules/.bin folder where executable npm.cmd file exists, made by npm automatically.