Skip to content

Instantly share code, notes, and snippets.

@fl0w fl0w/lazynvm.sh
Last active Jul 3, 2020

Embed
What would you like to do?
# 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 $@
}
@christophemarois

This comment has been minimized.

Copy link

christophemarois commented Jul 17, 2018

In zsh, I have a different setup in my ~/.zshrc that not only lazyloads nvm and node, but also any globally-installed package

# Add every binary that requires nvm, npm or node to run to an array of node globals
NODE_GLOBALS=(`find ~/.nvm/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 call
load_nvm () {
  export NVM_DIR=~/.nvm
  [ -s "$(brew --prefix nvm)/nvm.sh" ] && . "$(brew --prefix nvm)/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
@fl0w

This comment has been minimized.

Copy link
Owner Author

fl0w commented Oct 23, 2018

updated for CLI npx and bash completion

@nicholasmakhija

This comment has been minimized.

Copy link

nicholasmakhija commented Dec 5, 2019

Thanks @christophemarois, I've been hunting for a solution like this one!

@plopezlpz

This comment has been minimized.

Copy link

plopezlpz commented Apr 24, 2020

@christophemarois this is gold, thanks

@VincentN

This comment has been minimized.

Copy link

VincentN commented Apr 29, 2020

Updated @christophemarois's script with npx, removed brew paths for nvm, added bash completion and updated the unset -f function call:

# Add every binary that requires nvm, npm or node to run to an array of node globals
NODE_GLOBALS=(`find ~/.nvm/versions/node -maxdepth 3 -type l -wholename '*/bin/*' | xargs -n1 basename | sort | uniq`)
NODE_GLOBALS+=("node")
NODE_GLOBALS+=("nvm")
NODE_GLOBALS+=("npx")

# Lazy-loading nvm + npm on node globals call
load_nvm () {
  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
}

# Making node global trigger the lazy loading
for cmd in "${NODE_GLOBALS[@]}"; do
  eval "${cmd}(){ unset -f ${cmd} >/dev/null 2>&1; load_nvm; ${cmd} \$@; }"
done

Thanks for sharing!

@adriaanvanrossum

This comment has been minimized.

Copy link

adriaanvanrossum commented May 7, 2020

I got this error with @christophemarois and @VincentN script:

bash: eval: line xx: syntax error: unexpected end of file

I changed

eval "${cmd}(){ unset -f ${NODE_GLOBALS} >/dev/null 2>&1; load_nvm; ${cmd} \$@ }"

to

eval "${cmd}(){ unset -f ${cmd} >/dev/null 2>&1; load_nvm; ${cmd} \$@; }"

Note the change of NODE_GLOBALS and the ; at the end.

@VincentN

This comment has been minimized.

Copy link

VincentN commented May 15, 2020

@adriaanvanrossum, oops. Updated the script!

@laur89

This comment has been minimized.

Copy link

laur89 commented Jun 26, 2020

Unsetting NODE_GLOBALS still makes sense. My take (tested only in bash):

export NVM_DIR="$HOME/.nvm"
mapfile -t NODE_GLOBALS < <(find "$NVM_DIR/versions/node/"*/bin/ -maxdepth 1 -mindepth 1 -type l -print0 | xargs --null -n1 basename | sort | uniq)
NODE_GLOBALS+=(node nvm)  # no need to add npx, that's picked up by find command above

# instead of using --no-use flag, load nvm lazily:
_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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.