-
-
Save fl0w/07ce79bd44788f647deab307c94d6922 to your computer and use it in GitHub Desktop.
# lazyload nvm | |
# all props goes to http://broken-by.me/lazy-load-nvm/ | |
# grabbed from reddit @ https://www.reddit.com/r/node/comments/4tg5jg/lazy_load_nvm_for_faster_shell_start/ | |
lazynvm() { | |
unset -f nvm node npm npx | |
export NVM_DIR=~/.nvm | |
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm | |
if [ -f "$NVM_DIR/bash_completion" ]; then | |
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion | |
fi | |
} | |
nvm() { | |
lazynvm | |
nvm $@ | |
} | |
node() { | |
lazynvm | |
node $@ | |
} | |
npm() { | |
lazynvm | |
npm $@ | |
} | |
npx() { | |
lazynvm | |
npx $@ | |
} |
@VincentN is this the approach I should take if I want it to be applied to nodemon
, for example?
Because with the original lazynvm.sh
when I try to run nodemon
inside a project I get a "command not found" error
@laur89 I ran into this error while using your code snippet
command not found: mapfile
also I am not able to use yarn globals using any of the above snippets @VincentN @christophemarois please any suggestion
command not found: mapfile
This suggests you're not using bash, as mapfile
is bash builtin. As I stated above, the snippet was only ever tested in bash.
@laur89 thanks for your snippet and reply. So I just used a combined script took some parts from yours and some from @christophemarois now this works with yarn globals and node version is same for projects using yarn as well.
export NVM_DIR="$HOME/.nvm"
#[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
#[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
NODE_GLOBALS=(`find ~/.nvm/versions/node -maxdepth 3 -type l -wholename '*/bin/*' | xargs -n1 basename | sort | uniq`)
NODE_GLOBALS+=(node nvm yarn)
_load_nvm() {
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
}
for cmd in "${NODE_GLOBALS[@]}"; do
eval "function ${cmd}(){ unset -f ${NODE_GLOBALS[*]}; _load_nvm; unset -f _load_nvm; ${cmd} \$@; }"
done
unset cmd NODE_GLOBALS
export PATH="$PATH:$HOME/.yarn/bin"```
~/.zshrc
export NVM_DIR="$HOME/.config/nvm"
# Lazy load
if [[ -s "$NVM_DIR/nvm.sh" ]]; then
NODE_GLOBALS=(`find $NVM_DIR/versions/node -maxdepth 3 -type l -wholename '*/bin/*' | xargs -n1 basename | sort | uniq`)
NODE_GLOBALS+=("node")
NODE_GLOBALS+=("nvm")
# Lazy-loading nvm + npm on node globals
load_nvm () {
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
}
# Making node global trigger the lazy loading
for cmd in "${NODE_GLOBALS[@]}"; do
eval "${cmd}(){ unset -f ${NODE_GLOBALS}; load_nvm; ${cmd} \$@ }"
done
fi
It works fine but vscode tasks does not works with lazy loading 👎
Any idea if this solution still has merit after nvm-sh/nvm#2317?
Edit, in my case with bash, it still beats the original/vanilla by ~0.4s
This does not work incase a script is run directly ./script.js
.
script.js looks like:
#!/usr/bin/env node
# everything else
because env tries to find node within current paths which is not updated by the nvm due to lazy load.
solution that I found works is to create individual shell script for each of the command in the path which would trigger lazynvm(). nvm will then initialize node path at the beginning of the $PATH
so that the next node call will run the node from the right path.
# lazynvm.sh
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
# node.sh
. $(dirname "$0")/lazynvm
node $@
and then add both to $PATH
in your .zshrc
:
export PATH="~/lazy-load:$PATH" # assuming both files are inside ~/lazy-load dir
Unsetting
NODE_GLOBALS
still makes sense. My take (tested only in bash):