jscheid / prettier.el

Prettier code formatting for Emacs.
GNU General Public License v3.0
168 stars 12 forks source link

Cannot find prettier when using nvm. #70

Closed abbreviatedman closed 3 years ago

abbreviatedman commented 3 years ago

Describe the bug

Similar to https://github.com/jscheid/prettier.el/issues/33, but occurs with nvm.

Does not happen when using asdf to manage node instead.

Link to M-x prettier-info output

https://gist.github.com/abbreviatedman/31153e74384b8d729dcfbaa547504594

To Reproduce

Entered this file and saved (global-prettier-mode enabled):

https://github.com/abbreviatedman/chartner/blob/master/dummy-data.js

Expected behavior does not occur.

Instead, we get the dreaded Error: Cannot find prettier anywhere, check troubleshooting instructions.

Expected behavior A clear and concise description of what you expected to happen.

The file is formatted according to prettier rules.

Additional context

(getenv "NODE_PATH") ;; --> /home/abbreviatedman/.nvm/versions/node/v15.7.0/bin/node $ command -v prettier # --> /home/abbreviatedman/.nvm/versions/node/v15.7.0/bin/prettier (getenv "PATH") ;; --> includes "/home/abbreviatedman/.nvm/versions/node/v15.7.0/bin/"

jscheid commented 3 years ago

NODE_PATH should not be the path to the node executable, instead it should contain a list of directories where to look for globally installed packages. Could this be the problem?

I see snap mentioned in your prettier-info output, did you see this?

jscheid commented 3 years ago

Also, can you confirm that prettier can be found when using nvm? Something like:

$ cd /the/directory/where/you/were/testing/prettier.el
$ nvm use
$ node -e 'require("prettier")'

If that would output something like Error: Cannot find module 'prettier' then that's what you'd need to debug first.

abbreviatedman commented 3 years ago

Thanks for the prompt reply! Took me a bit myself to try to narrow things down with your suggestions.

snap

I'm afraid that snap is not the issue; I don't use it. Confirmed by running snap list to make sure I didn't have any sneakily installed snaps. I do not.

not having prettier available to node

It's installed globally, but I ran the command to attempt to require it. prettier was like, "That's... not how you use me.", but it ran.

node path is the path to the node MODULES, not the location of node itself

This helped... I think? I had switched from nvm to asdf, and using the correct "NODE_PATH" got prettier integration working (and so might just switch to using asdf!), but I switched back to nvm to check and now... have a different error?

I think what I've learned is that you really aren't meant to switch version managers...

So here's the error I'm getting now: Could not sync Prettier config, consider setting 'prettier-mode-sync-config-flag' to nil: (error "Node sub-process died")

Followed shortly by: prettier-process (local) quit unexpectedly: exited abnormally with code 1

If I set prettier-mode-sync-config-flag to nil, I get:

prettier-process (local) quit unexpectedly: exited abnormally with code 1

Followed by:

Error: (error "Process prettier is not active")

So... if you have some suggestions, I'll try them out. I may just have borked nvm somehow. (Although... it certainly works outside of emacs.)

abbreviatedman commented 3 years ago

And in a related one (probably related, but could open a separate issue if you'd prefer), I've switched back to asdf, only to find that I now have an error when I run (prettier-prettify) (or save a document with global-prettify-mode enabled):

SyntaxError: Invalid or unexpected token.

Have tried it on a file with only a console.log statement, ensuring that there isn't any unexpected token. prettier does not format the file, and I can confirm that both prettier and node are in all the path variables. prettier --write [filename] works just fine.

jscheid commented 3 years ago

No worries, we'll get to the bottom of this... a few thoughts:

First off, I shouldn't have pointed you at that troubleshooting guide, because unless snap is involved and/or when a version managers such as nvm is in play, you shouldn't have to set NODE_PATH explicitly at all. So first thing I would do, in order to eliminate a potentially confusing factor, is to remove that setting from everywhere and ensure it's unset, i.e. in Emacs (getenv "NODE_PATH") should return nil and for good measure, in your shell set | grep NODE_PATH should come back empty-handed.

Regarding Node sub-process died: this is strange and warrants investigation. When something like this happens, the *prettier (local)* buffer might contain useful information. If you can reproduce it, could you send over the contents of that buffer, if there's anything in it?

Also, what does (prettier--node-from-nvm) return, and what does (prettier--find-node 'local)?

Finally, a heads up that this package will try and figure out the node and prettier versions to used based on the directory containing the file you're editing. Different directories might lead to different package.jsons (which this packages may use to determine the Prettier version to use) and different .nvmrcs (used to determine node version.) So, to eliminate this as a factor, please make sure to always edit a file in the same directory for your tests.

jscheid commented 3 years ago

Another question, how did you install Prettier globally: with npm, yarn or some other package manager? And is it the latest version (2.2.1)?

abbreviatedman commented 3 years ago

I appear to have solved the problem, while using asdf at any rate. (May switch back to nvm to make sure it works using that version manger as well, though I'm guessing it will.)

Setting NODE_PATH to nil did NOT do that for the shell, so your "for good measure" was actually JUST the right amount of measure! It turns out that the zsh theme powerlevel10k was setting $NODE_PATH itself. There is likely a way to configure that from powerlevel10k (or just from my .zshrc?), but either way, switching themes did the trick.

Thanks for the suggestion! If anyone has similar problems in the future, perhaps checking their $NODE_PATH shell variable as a potential point of failure might be a good idea.

jscheid commented 3 years ago

Ah great, glad it's working now for you.

Odd though, we're using start-file-process, which -- at least for local execution -- is ultimately just a thin wrapper around make-process, which I thought invokes the command directly without going through a shell. That's why I said "for good measure", I didn't really expect it to have any bearing on the result. Might investigate this some more to see if there's anything we can do to make the process more robust.

I assume you start Emacs from inside zsh, not from a desktop environment?

jscheid commented 3 years ago

Nothing actionable here I'm afraid. I could go and try to reproduce with that zsh plugin, but I don't really have enough time to do so. If anyone else runs into a similar problem let me know and I might take a second look.

Sleepful commented 3 years ago

$ node -e 'require("prettier")'

This is giving me "module not found" while using nvm and globally-installed prettier. Any clue how to debug?

Sleepful commented 3 years ago

Ah, I was missing two things:

  1. in .zshrc
    export NODE_PATH=$NODE_PATH:`npm root -g`
  2. obviously
    npm install -g prettier
Sleepful commented 2 years ago

I have this issue again on a new OSX ... using nvm.

node -e 'require("prettier")' works fine.

But I get Error: Cannot find prettier anywhere, check troubleshooting instructions in Emacs.

Completely clueless...

Tide works fine with my current node installation, but I can't use prettier.

What.... what gives?

Sleepful commented 2 years ago

turns out I am using doom emacs and I just needed to run doom env, I am rock headed

dhdaines commented 3 months ago

This problem still exists for me. I have NO IDEA how to debug it. Emacs 29 on Debian 12, Node v20.14.0 installed via nvm, no fancy configuration. M-x prettier-info says:

(:emacs-version "GNU Emacs 29.3 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38, cairo version 1.16.0)\n of 2024-05-20, modified by Debian" :prettier-el-version "1.3.0" :buffer-file-name nil :remote-id nil :major-mode lisp-interaction-mode :exec-path
                ("/home/dhd/.local/bin" "/usr/local/bin" "/usr/bin" "/bin" "/usr/local/games" "/usr/games" "/usr/libexec/emacs/29.3/x86_64-linux-gnu")
                :env
                ("TERM=dumb" "GIO_LAUNCHED_DESKTOP_FILE_PID=88356" "DESKTOP_STARTUP_ID=gnome-shell/Emacs (GUI)/87015-0-minipc_TIME157280170" "GIO_LAUNCHED_DESKTOP_FILE=/usr/share/applications/emacs.desktop" "GJS_DEBUG_TOPICS=JS ERROR;JS LOG" "GJS_DEBUG_OUTPUT=stderr" "JOURNAL_STREAM=8:432780" "INVOCATION_ID=cccf0c6e0e6a49ee8cf2c4a31f4b4951" "MANAGERPID=35843" "XMODIFIERS=@im=ibus" "XDG_SESSION_TYPE=x11" "XDG_SESSION_DESKTOP=gnome-xorg" "XDG_SESSION_CLASS=user" "XDG_MENU_PREFIX=gnome-" "XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/" "XDG_CURRENT_DESKTOP=GNOME" "XAUTHORITY=/run/user/1000/gdm/Xauthority" "WINDOWPATH=2" "USERNAME=dhd" "SSH_AUTH_SOCK=/run/user/1000/keyring/ssh" "SSH_AGENT_PID=36103" "SESSION_MANAGER=local/minipc:@/tmp/.ICE-unix/86988,unix/minipc:/tmp/.ICE-unix/86988" "QT_IM_MODULE=ibus" "PWD=/home/dhd" "GTK_IM_MODULE=ibus" "GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1" "GNOME_DESKTOP_SESSION_ID=this-is-deprecated" "GDM_LANG=en_CA.UTF-8" "GDMSESSION=gnome-xorg" "DESKTOP_SESSION=gnome-xorg" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus" "QT_ACCESSIBILITY=1" "GTK_MODULES=gail:atk-bridge" "XDG_RUNTIME_DIR=/run/user/1000" "USER=dhd" "SYSTEMD_EXEC_PID=87015" "SHELL=/bin/bash" "PATH=/home/dhd/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" "LOGNAME=dhd" "LANGUAGE=en_CA:en" "LANG=en_CA.UTF-8" "HOME=/home/dhd")
                :prettier-options nil)

It looks to me like prettier.el is definitely finding node with nvm - evaluating in *scratch*:

nvm-dir
"/home/dhd/.nvm/"
prettier-nvm-node-command-cache
"/home/dhd/.nvm/versions/node/v20.14.0/bin/node"

Where does that "Cannot find prettier anywhere" error even come from in the source code? This is very opaque and infuriating. I can't for the life of me figure out how to set breakpoints or trace the execution of prettier.el.

dhdaines commented 3 months ago

Hmm. Perhaps node itself is to blame (not surprising since it is the worst software ever invented)? I have installed it correctly, run npm install -g prettier, but it is not actually able to load the prettier module:

$ node -e 'require("prettier")'
node:internal/modules/cjs/loader:1148
  throw err;
  ^

Error: Cannot find module 'prettier'
Require stack:
- /home/dhd/[eval]
    at Module._resolveFilename (node:internal/modules/cjs/loader:1145:15)
    at Module._load (node:internal/modules/cjs/loader:986:27)
    at Module.require (node:internal/modules/cjs/loader:1233:19)
    at require (node:internal/modules/helpers:179:18)
    at [eval]:1:1
    at runScriptInThisContext (node:internal/vm:209:10)
    at node:internal/process/execution:118:14
    at [eval]-wrapper:6:24
    at runScript (node:internal/process/execution:101:62)
    at evalScript (node:internal/process/execution:133:3) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/home/dhd/[eval]' ]
}
dhdaines commented 3 months ago

And apparently... one is never supposed to install prettier globally?!?!

https://github.com/prettier/prettier-vscode/issues/2038

jscheid commented 3 months ago

prettier-vscode is a different package that works differently so the comment you linked to won't help you.

Can you show the output of these two commands:

/home/dhd/.nvm/versions/node/v20.14.0/bin/npm root -g
ls -ld $(/home/dhd/.nvm/versions/node/v20.14.0/bin/npm root -g)/prettier

If the second command errors, try this, then try again with this package (after M-x prettier-restart):

/home/dhd/.nvm/versions/node/v20.14.0/bin/npm install -g prettier

I agree that this should be easier to debug. I'm working on something that will improve this.