Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VSCode pre-commit: npx: not found #668

Open
NayamAmarshe opened this issue Feb 13, 2022 · 27 comments
Open

VSCode pre-commit: npx: not found #668

NayamAmarshe opened this issue Feb 13, 2022 · 27 comments

Comments

@NayamAmarshe
Copy link

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

@Schniz
Copy link
Owner

Schniz commented Feb 15, 2022

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?

@NayamAmarshe
Copy link
Author

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)"

@Schniz
Copy link
Owner

Schniz commented Feb 16, 2022

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.

@devmattrick
Copy link

devmattrick commented Jun 14, 2022

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 😄

@NayamAmarshe
Copy link
Author

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/

@devmattrick
Copy link

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.

@NayamAmarshe
Copy link
Author

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.

@Schniz
Copy link
Owner

Schniz commented Jun 14, 2022

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 🙏

@Schniz
Copy link
Owner

Schniz commented Jun 14, 2022

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!)

@devmattrick
Copy link

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?

@cloydlau
Copy link

Ran into a same issue when using Github Desktop.

cloydlau added a commit to cloydlau/json-editor-vue that referenced this issue Oct 14, 2022
@nathanpovo
Copy link

Ran into this issue when using VSCode on Windows.

Seems like it is an issue with VSCode: microsoft/vscode#90178, microsoft/vscode-python#10165

@nathanpovo
Copy link

nathanpovo commented Mar 25, 2023

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.

@Schniz
Copy link
Owner

Schniz commented Mar 27, 2023

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
Copy link
Owner

Schniz commented Mar 27, 2023

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.

@AdeCaspeer
Copy link

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

@feugy
Copy link

feugy commented Aug 13, 2023

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

@SinBirb
Copy link

SinBirb commented Nov 6, 2023

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.

@coderwyd
Copy link

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

@NayamAmarshe
Copy link
Author

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

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

@coderwyd
Copy link

coderwyd commented Feb 2, 2024

@Schniz Will this problem be fixed?

@Schniz
Copy link
Owner

Schniz commented Feb 2, 2024

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
Copy link
Owner

Schniz commented Feb 2, 2024

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 :)

@coderwyd
Copy link

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!

@nemchik
Copy link

nemchik commented Jul 17, 2024

I found another workaround/solution. husky doesn't execute git hooks using bash it does it using sh so it never loads .bashrc.

Add eval "$(fnm env --use-on-cd --version-file-strategy=recursive)" (or whatever flags you prefer) to ~/.config/husky/init.sh

ref: https://typicode.github.io/husky/how-to.html#node-version-managers-and-guis (may be worth mentioning this in the readme given how many issues are opened here on this topic)

@nemchik
Copy link

nemchik commented Jul 17, 2024

Based on my above comment and some additional research, when husky runs sh in the git bash environment on windows it DOES see the windows PATH environment variable (and all other windows environment variables as well). The issue is that the fnm environment variables are not present in the windows environment until fnm env is run and evaluated, and this never happens with husky unless you add it to ~/.config/husky/init.sh. Additionally, since the path output by fnm env are dynamic, there is no one permanent path that would cover all the bases.

I haven't looked at #609 to see if it's trying to resolve this by having a permanent non-dynamic path in the windows environment that uses shims for the various executabled that would be needed (like node, npm, npx, and potentially all the required variants for yarn, pnpm, etc) or if there's a more clever way to do it, but based on how husky is using sh instead of bash I think having a permanent non-dynamic path in the windows environment would solve the issue (and maybe work out nicely in other ways, or cause a ton of other problems 😆).

@mrienstra
Copy link

Thanks @nemchik. In my case, because I installed fnm with brew (macOS), I used the following in ~/.config/husky/init.sh:

eval "$(/opt/homebrew/bin/brew shellenv)"
eval "$(fnm env --use-on-cd)"

(first line was sourced from ~./zprofile, second from ~/.zshrc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests