fnm icon indicating copy to clipboard operation
fnm copied to clipboard

VSCode pre-commit: npx: not found

Open NayamAmarshe opened this issue 2 years ago • 24 comments

I'm using fnm and VSCode can't seem to detect node. On committing through the Source Control Sidebar, it shows this error:

> git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -
.husky/pre-commit: 4: npx: not found
husky - pre-commit hook exited with code 127 (error)

Is there any fix for this? This wasn't a problem in nvm

NayamAmarshe avatar Feb 13 '22 02:02 NayamAmarshe

hmm I wonder how that's not an issue with nvm if it also requires being evaluated to add PATH. Maybe you also had global Node.js installed with Homebrew or similar tools?

Schniz avatar Feb 15 '22 09:02 Schniz

Maybe you also had global Node.js installed with Homebrew or similar tools?

I did but not anymore so I'm not sure why this happens. Here's what's in my zshrc:

export PATH="/home/yavin/bin:/home/yavin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/yavin/.npmbin"
export PATH="/home/yavin/bin:/home/yavin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin"
export PATH="/home/yavin/bin:/home/yavin/bin:/home/yavin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/yavin/.fnm:$PATH"
export PATH="/home/yavin/.fnm:$PATH"
export PATH="/home/yavin/bin:/run/user/1000/fnm_multishells/18470_1644474706526/bin:/home/yavin/.fnm:/home/yavin/.fnm:/home/yavin/bin:/home/yavin/bin:/home/yavin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/yavin/.fnm:/home/yavin/bin:/home/yavin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin"

# fnm
export PATH=/home/yavin/.fnm:$PATH
eval "`fnm env`"
eval "$(fnm env --use-on-cd)"

NayamAmarshe avatar Feb 16 '22 09:02 NayamAmarshe

The global Node.js installation makes sense as VSCode does not run in the context of the shell so it does not share the environment variables (I guess). Having a global installation might make sense for GUIs. This is still unsolved with fnm.

Schniz avatar Feb 16 '22 14:02 Schniz

Apologies for the ping, but I think I've thought of a potential solution. Could fnm "hijack" the "global" node command and essentially redirect that command to the matching node version based on any .nvmrc files in the pwd? If it doesn't find any it can then fallback to the default version.

If this seems like a workable solution I wouldn't mind trying to piece something together :smile:

devmattrick avatar Jun 14 '22 02:06 devmattrick

Could fnm "hijack" the "global" node command and essentially redirect that command

It was a huge problem for me, so I moved to Volta for the time being, it's faster and fixes the problem :) https://volta.sh/

NayamAmarshe avatar Jun 14 '22 03:06 NayamAmarshe

It was a huge problem for me, so I moved to Volta for the time being, it's faster and fixes the problem :) https://volta.sh/

Volta seems like a cool solution and I guess sorta proves the concept! My only gripe with it is that it doesn't seem to support any sort of "standardized" version pinning formats (e.g. package.json engines key, .nvmrc, .node-version, etc.) which makes it less ideal for projects that don't already use Volta.

devmattrick avatar Jun 14 '22 07:06 devmattrick

It was a huge problem for me, so I moved to Volta for the time being, it's faster and fixes the problem :) https://volta.sh/

Volta seems like a cool solution and I guess sorta proves the concept! My only gripe with it is that it doesn't seem to support any sort of "standardized" version pinning formats (e.g. package.json engines key, .nvmrc, .node-version, etc.) which makes it less ideal for projects that don't already use Volta.

Yeah, it uses package.json to pin node versions.

NayamAmarshe avatar Jun 14 '22 08:06 NayamAmarshe

I had an experiment with making Volta-like shims, but I am reaaaaally overwhelmed these days in my day job (and personal life, for a good causes though) so I'm kinda neglecting open source nowadays. I feel really bad about it :pray:

Schniz avatar Jun 14 '22 08:06 Schniz

Could fnm "hijack" the "global" node command and essentially redirect that command to the matching node version based on any .nvmrc files in the pwd?

@devmattrick the PR I linked is just as you suggested, using fnm exec when you run node, npm etc--I need to figure out why the tests fail (IIRC, haven't touched the code in many moons!)

Schniz avatar Jun 14 '22 08:06 Schniz

I had an experiment with making Volta-like shims, but I am reaaaaally overwhelmed these days in my day job (and personal life, for a good causes though) so I'm kinda neglecting open source nowadays. I feel really bad about it pray

Don't feel bad about it, I totally get it! If I get some time this week I'll see if I can get it spruced up and maybe open a PR based on this one if you'd like?

devmattrick avatar Jun 15 '22 00:06 devmattrick

Ran into a same issue when using Github Desktop.

cloydlau avatar Oct 11 '22 11:10 cloydlau

Ran into this issue when using VSCode on Windows.

Seems like it is an issue with VSCode: https://github.com/microsoft/vscode/issues/90178, https://github.com/microsoft/vscode-python/issues/10165

nathanpovo avatar Mar 25 '23 19:03 nathanpovo

Managed to solve the issue (for hooks using husky) thanks to this comment. You can see the official documentation here.

Using git bash, create the file ~/.huskyrc (on a Windows machine, you can create the file manually at C:\Users\<CurrentUserName>\.huskyrc) and add the following:

eval "$(fnm env --use-on-cd)"

That is the command the documentation specifies when setting up the Bash shell for use with fnm.

Since this is not a fix that is specific to VSCode, it should also solve the issue in other GUIs (like Github Desktop) but I did not test it out.

It's technically a workaround since it does not solve the actual root cause but it lets you use husky git commits until the issue in VSCode is solved.

nathanpovo avatar Mar 25 '23 20:03 nathanpovo

I want to fix it and I have some ideas, they are not perfect tho. It would be nice to have some sort of a solution from someone who uses GUI-based tools to ponder a bit about this too because I'm using CLIs and Vim for everything (:muahahaha:) and therefore fnm wasn't optimized for this, but I believe we can optimize.

Like, fnm exec --or-default -- COMMAND should probably work too if it was implemented (like in #609)--it should use the current .node-version or .nvmrc to know which Node.js version to use for the current command, but that would require that cwd will be defined properly--which I assume it is for all GUI apps that execute stuff!

Schniz avatar Mar 27 '23 07:03 Schniz

This wasn't a problem in nvm

worth noting that as far as I know, this wasn't a problem in nvm because most tools have a special condition for nvm built in. nvm is a bash script which must be evaluated in the specific context prior to the script execution. fnm does not have this advantage nor I think it should: I believe that we can fix it without any special care.

Schniz avatar Mar 27 '23 07:03 Schniz

I also encountered the same problem, but I don’t know how to solve it!

AdeCaspeer avatar May 03 '23 03:05 AdeCaspeer

A bit late in the party: here is how I got it working:

~/.huskyrc
# makes sure fnm is included in the path
eval "$(~/.fnm/fnm env)"

This allowed me running husky pre-commit hook within VSCode. Husky's FAQ gives more explanation about why we need to configure huskyrc

feugy avatar Aug 13 '23 08:08 feugy

I'm having a bit of a similar issue, but because I have npm + yarn installed as a system package, I get the following error in VSCode's git output:

The engine "node" is incompatible with this module. Expected version "18.17". Got "18.18.0"
error Commands cannot run with an incompatible environment.

Somehow, my ~/.huskyrc file also is not loaded by VSCode, so I ended up setting the git.path in VScode:

"git.path": "/home/<user>/tools/git-zsh"

and only put this into /home/<user>/tools/git-zsh:

#!/bin/zsh
eval "$(fnm env --use-on-cd --shell zsh --version-file-strategy recursive --log-level quiet)"
/usr/bin/git ${@:1}

It's super hacky, but it works.

SinBirb avatar Nov 06 '23 14:11 SinBirb

Is there any way to solve this problem? now he blocks me

coderwyd avatar Jan 24 '24 03:01 coderwyd

Is there any way to solve this problem? now he blocks me

https://volta.sh is the best solution that I found.

NayamAmarshe avatar Jan 24 '24 03:01 NayamAmarshe

@Schniz Will this problem be fixed?

coderwyd avatar Feb 02 '24 03:02 coderwyd

Maybe. I have ideas. Not much free time. In the last 4 months I've been drafted as reserves to the ongoing war due to the Oct 7th massacre. In general, fnm works very well for me, and implementing solutions for other people setups is "nice to have" in these circumstances (I hope you understand). I do have ideas that need to be validated and coded though so I really hope I will have the time and drive to do that.

Schniz avatar Feb 02 '24 07:02 Schniz

The easiest way to fix it in userland is to call fnm exec npx instead of npx in your pre commit hook. This will ensure the correct version is set before running npx :)

Schniz avatar Feb 02 '24 07:02 Schniz

https://volta.sh is the best solution that I found.

The downside of volta is that you need to manually configure the node version in package.json instead of reading .nvmrc directly, but he did solve the problem that I couldn't commit with vscode anymore! Thanks!

coderwyd avatar Mar 14 '24 01:03 coderwyd