fnm
fnm copied to clipboard
Add shims for Volta-like binaries
This PR introduces --with-shims
to the fnm env
command.
These shims (currently only node
, but maybe npm
will need it too) will be used instead of the $FNM_MULTISHELL_PATH
, and although they will introduce some runtime penalty (~8-16ms on my machine), it will be much easier to integrate with other tools and make people understand how fnm works.
This should also fix some rehash
ing issues some users have on newer Zsh versions.
This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.
🔍 Inspect: https://vercel.com/schniz/fnm/CkggR7pGuDDtUcAG2qtKPoM8JYHL
✅ Preview: https://fnm-git-add-with-shims-schniz.vercel.app
d1f7b9d is because I thought I would be able to change the symlink generation process from random to using the parent process' pid, and therefore making it reproducible, and making fnm env
not mandatory at all (unless one wants fancy features).
Unfortunately, every shell script has its own pid so we need to find a common denominator somehow. Shells are obviously not the common denominator (the shims are a shell script), so we need to know whether it's an interactive shell--or a graphical IDE (like #475 and other issues).
If someone has an idea how to pull this off, let me know 😃
Shells are obviously not the common denominator (the shims are a shell script)
CLI (pid1) -> node shim (pid2) -> fnm (pid3)
fnm tries to take pid2, instead of pid1. The same can be applied in VSCode or XCode or whatever:
VSCode (pid1) -> some 3rd party script (pid2) -> another 3rd party (pid3) -> fnm (pid4)
and now we're trying to use pid3, which can be a one-off thing. So pids are probably not what we want. I also thought about implementing a table of pids to versions but this is just insanity and composes very very badly (how up the tree we need to update version when we switch?) 😁
The premise of reproducible "multishell" paths is good, because it simplifies the installation of fnm, which can be awesome.
Shims are a fundamentally different model than PATH hijacking, and they come with an entirely distinct set of problems; I’ll be very curious to see how fnm deals with both at once.
I've read some linked issues and it seems that people want fnm to install node globally (or behave like it's installed globally). Am I correct?
What about this shim?
#!/bin/sh
cwd=$PWD
while [ -n "$cwd" ]; do
if [ -f "$cwd/.node-version" ]; then
# echo "Found $cwd/.node-version"
exec fnm exec --using "$cwd/.node-version" -- node "$@"
fi
if [ -f "$cwd/.nvmrc" ]; then
# echo "Found $cwd/.nvmrc"
exec fnm exec --using "$cwd/.nvmrc" -- node "$@"
fi
cwd=${cwd%/*}
done
exec fnm exec --using default -- node "$@"
We can have fnm exec --fallback-to-default
but I am not sure this is enough.. what if someone wants to change a node version?
I just wonder if there's a better option we haven't though of, that will make fnm env
optional
what if someone wants to change a node version?
You meant beside changing default version?
⚠️ No Changeset found
Latest commit: 2299a02196d754b0ece072c3d9f2776ce63f721a
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
main problem I see with it right now, that it will make all global node module installations fail, as they install binaries in $NODE_INSTALL_DIR/bin
, and we're not linking it to $PATH
gotta dig deeper