Comments (6)
I really wanted yarn to play well with fnm, so I came up with the following:
EDIT: Simplest solution
While the original solution is still valid, I ran into some issues while running scripts from package.json
files (e.g. Unknown option: '--global-folder'
).
Turns out there is an astonishingly simple way to change the global folder, binary folder (and many other settings) based on the current shell:
export YARN_GLOBAL_FOLDER="$FNM_MULTISHELL_PATH/yarn-global"
export YARN_PREFIX="$FNM_MULTISHELL_PATH"
These environment variables do not seem to be documented on classic.yarnpkg.com but they work fine on version 1.22.10
nonetheless. (They are documented here for Yarn 2.) They're also mentioned in the changelogs once.
@Schniz maybe this solution is elegant enough to be included in fnm? Users can always override these variables in their dotfiles, after fnm is loaded.
1. Working Solution
# scope global yarn packages to current node version
yarn() {
# $@ is copied to $args (some positional parameters are filtered)
local args=()
# defaults for intercepted paramaters
local global_folder="$FNM_MULTISHELL_PATH/yarn-global"
local global_bin_folder="$FNM_MULTISHELL_PATH"
# intercept certain positional parameters
while test $# -gt 0; do
case "$1" in
--global-folder)
shift
global_folder=$1
shift;;
--prefix)
shift
global_bin_folder=$1
shift;;
*)
args+=$1
shift;;
esac
done
# run yarn (found in $PATH) and manually pass on intercepted parameters
command yarn $args --global-folder=$global_folder --prefix=$global_bin_folder
}
If this function is loaded in your terminal (e.g. because it is saved in .bashrc
), it will run every time yarn
is invoked. It filters out --global-folder <path>
and --prefix <path>
from the positional parameters. If those options were not provided (which is usually the case), it will provide default values based on $FNM_MULTISHELL_PATH
. The actual yarn command (the one that sits in your $PATH
) is then called with --global-folder
and --prefix
, as well as the remaining positional parameters.
--global-folder
tells yarn where to store the global node_modules
.
--prefix
tells yarn where to symlink binaries. Since fnm env
puts $FNM_MULTISHELL_PATH/bin
on the $PATH
, all commands that are installed with yarn global add
will be available in your terminal.
Note that I installed yarn using npm, such that the version of yarn that is used, is also scoped to the current node version.
2. Buggy Solution (for reference only, do not use)
FYI for my first attempt I added the following lines to .bashrc
or .zshrc
:
yarn config set global-folder "$FNM_MULTISHELL_PATH/yarn-global" > /dev/null
yarn config set prefix "$FNM_MULTISHELL_PATH" > /dev/null
This does not play well with --multi
however, because yarn config
changes $HOME/.yarnrc
by default. Each time a terminal window/tab is opened, above lines are run. This means that $HOME/.yarnrc
will always contain the paths that belong to the last opened shell. It is possible to pass --use-yarnrc <path>
(cf. working solution) and configure yarn via that file, but this is slower than the working solution because of file I/O and more complex overall.
from fnm.
I’d expect yarn to use whatever npm root -g
is; if it isn’t, yarn is broken - if it is, fnm is broken.
nvm and n and nave all “support” yarn afaik with no special handling.
from fnm.
Yes, but imo if you have to do that, it’s a yarn bug.
from fnm.
@ljharb this is what I get for the global bin paths:
$ npm -g bin
/home/redacted/.fnm/node-versions/v10.15.3/installation/bin
(not in PATH env variable)
$ yarn global bin
/home/redacted/.yarn/bin
Edit: could something like this work? yarn config set prefix $(npm prefix -g)
from fnm.
Yes, but imo if you have to do that, it’s a yarn bug.
Indeed. We can also support changing ~/.yarnrc
when we switch
, but this is very abusive and won't work across shells (with the --multi
).
I was thinking about having something like fnm promote-global-bin VERSION BINARY
. That could create a script in ~/.fnm/global-binaries
that calls the binary using the correct version every time, and fnm env
could add it to $PATH
too. But I'm not sure it will be used or a good idea 🤷♂️
from fnm.
closing for inactivity
from fnm.
Related Issues (20)
- Suggestion for Modifying PATH Export in install.sh to Enhance Compatibility and Safety
- `node_watchdog.cc` error when using the fnm install node, but not the same version of the Debian installed node HOT 1
- failed to fnm exec npm in git bash HOT 1
- [Idea] Include the name of the tool in the output?
- Usage in a monorepo HOT 2
- How to use in dockerfile ? HOT 1
- node.js HOT 1
- About the location of fnm (Linux) HOT 1
- 你好,我遇到了两个问题 HOT 2
- why dose the path is random ? how can i get a frozen path ? like nvm `/Users/xxx/.nvm/versions/node/v18.15.0/bin/node`
- Unable to download tar.xz file
- Is this library no longer updated?
- Please update the ring crate to 17.x
- Use `fnm env` to activate fnm not work in git-bash for windows HOT 3
- Modify the cd.cmd file, cd /d %1 can ensure switching between different drive letters
- Feature request: Port over nvm's "default global packages"
- Change directory not triggering use of default node version HOT 1
- How to correctly set PATHS for fish shell when both homebrew and fnm install node? HOT 1
- Programs installed in the active multishell are available when calling `fnm exec`
- Not able to import globally installed packages HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fnm.