2

My question is similar to this question. I've installed node via nvm. (executable-find "node") returns .nvm/versions/node/v15.11.0/bin/node.

Entering node on eshell drops me into a node shell. But when I enter npm in an eshell, I'm fed

/usr/bin/env: ‘node’: No such file or directory

Similarly, the command nvm returns nvm: command not found.

On a zsh terminal, the above commands work as expected. I suspect this has to do with the following line in my .zshrc:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm

I can use (setenv "NVM_DIR" "~/.nvm") to set the env var, I'm at a loss per the second line.

including the line (setq exec-path (append exec-path '("~/.nvm/versions/node/v15.11.0/bin"))) does not solve my problem.

3 Answers 3

1

The problem is that nvm is actually a set of bash functions and doesn't work outside of bash. The following blog post has a detailed account of the issue and a work around using nvm-exec solution: https://jloubert.com/blog/eshell-nvm/

The author purposes adding an .nvmrc file to your projects that has the required nvm version number in it.

They then purpose adding an eshell alias that calls npm-exec and you prefix any node commands with that alias. The eshell alias code looks like where "foo" is the alias keyword

(defvar my/nvm-folder "/my/path/to/.nvm")
(add-hook
 'eshell-mode-hook
 (lambda ()
   (eshell/alias
    "foo"
    (concat my/nvm-folder
            "/nvm-exec foo-server run"))))
1

Since you didn't necessarily clarify what you're using node/npm for, this is if you're a Python, etc. dev who might need npm/node in emacs for LSPs (as was my use case when I found this answer, and nvm was easiest AUR installation). If that is the case, you could theoretically just do something as simple as creating a script such as:

https://gist.github.com/MeLlamoPablo/0abcc150c10911047fd9e5041b105c34

sudo rm -f /usr/bin/node
sudo rm -f /usr/bin/npm
sudo ln -s $(which node) /usr/bin/
sudo ln -s $(which npm) /usr/bin/

symlinking your default node/npm, allowing emacs to pick it up and rerunning the script on the off chance you switch defaults.

0

Have you tried using exec-path-from-shell package? It loads the environment variables that are used in your shell.

If you are using use-package then this should suffice:

(use-package exec-path-from-shell
   :config (exec-path-from-shell-initialize))
1
  • exec-path-from-shell only copies over environmental path values and does not handle the shell script execution of the 2nd line that op pointed out.
    – kevzettler
    Apr 19, 2022 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.