esegui "nvm use" automaticamente ogni volta che c'è un file .nvmrc nella directory


88

Come configurare la mia shell in modo che nvm usevenga eseguita automaticamente ogni volta che c'è un file .nvmrc nella directory e utilizzare l'ultima versione o una configurazione globale quando non c'è un file .nvmrc?


2
Questo caso d'uso è ora documentato nella documentazione ufficiale di NVM in Deep Shell Integration . Puoi anche vedere la mia risposta per la bashshell.
d4nyll

Risposte:


89

Se usi zsh (z shell):

Chiamare automaticamente "nvm use" in una directory con un file .nvmrc

Mettilo nella tua $ HOME / .zshrc per chiamare nvm use automaticamente ogni volta che entri in una directory che contiene un file .nvmrc con una stringa che dice a nvm quale nodo usare:

# place this after nvm initialization!
autoload -U add-zsh-hook
load-nvmrc() {
  local node_version="$(nvm version)"
  local nvmrc_path="$(nvm_find_nvmrc)"

  if [ -n "$nvmrc_path" ]; then
    local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")

    if [ "$nvmrc_node_version" = "N/A" ]; then
      nvm install
    elif [ "$nvmrc_node_version" != "$node_version" ]; then
      nvm use
    fi
  elif [ "$node_version" != "$(nvm version default)" ]; then
    echo "Reverting to nvm default version"
    nvm use default
  fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc

Maggiori informazioni: https://github.com/creationix/nvm#zsh


6
Questo ha funzionato molto bene per me, ma ha causato un calo delle prestazioni cd, poiché viene eseguito ogni volta che cambi directory. Ho aggiunto [[ -a .nvmrc ]] || returnalla prima riga load-nvmrc (), e questo ne ha migliorato significativamente le prestazioni
Belgabad,

1
@Belgabad È più performante, perché con la tua riga lo script non controllerà .nvmrcnelle directory principali e inoltre non tornerà alla nodeversione predefinita quando cdesci dalla directory del progetto.
Rotareti

50

Se usi bash puoi aggiungerlo al tuo ~/.bashrcfile:

enter_directory() {
  if [[ $PWD == $PREV_PWD ]]; then
    return
  fi

  PREV_PWD=$PWD
  [[ -f ".nvmrc" ]] && nvm use
}

export PROMPT_COMMAND=enter_directory

33

Ottima risposta da @devius .

L'ho appena esteso in modo che possa tornare alla versione predefinita quando si lascia una directory con .nvmrcun'altra senza di essa.

~/.bashrc:

#
# Run 'nvm use' automatically every time there's 
# a .nvmrc file in the directory. Also, revert to default 
# version when entering a directory without .nvmrc
#
enter_directory() {
if [[ $PWD == $PREV_PWD ]]; then
    return
fi

PREV_PWD=$PWD
if [[ -f ".nvmrc" ]]; then
    nvm use
    NVM_DIRTY=true
elif [[ $NVM_DIRTY = true ]]; then
    nvm use default
    NVM_DIRTY=false
fi
}

export PROMPT_COMMAND=enter_directory

Usando bash su Windows, questo restituisce node v.0.0 (64-bit) is not installed.anche se il file .nvmrc ha 9.3.
hofnarwillie

2
Risolto utilizzandoVERSION=$(cat .nvmrc); nvm use $VERSION
hofnarwillie

Dovrei anche dire che sta usando nvm-for-windows che è una bestia completamente diversa. Ma con lo script sopra + la modifica funziona a meraviglia. +1
hofnarwillie

26

Ho appena scoperto il cambio di versione automatico per Node.js https://github.com/wbyoung/avn , puoi usarlo.

Puoi anche seguire questo thread https://github.com/creationix/nvm/issues/110


32
Questo è deprimente .. non c'è limite alla profondità della pila di utensili? node → npm → nvm → avn ed eseguire il backup. sospiro giocherò a palla, ma la mia passione diminuisce a ogni hack. (e grazie per il collegamento, ovviamente, gabo.)
hraban

Nessuno dei commenti nel thread menzionato ha funzionato con bash per me. Forse sono tutti per MacOS. Per qualcosa che funziona in Ubuntu controlla la mia risposta di seguito.
devius

15

Questa risposta è presa dalla documentazione ufficiale di nvm .

Metti quanto segue alla fine del tuo $HOME/.bashrc:

find-up () {
    path=$(pwd)
    while [[ "$path" != "" && ! -e "$path/$1" ]]; do
        path=${path%/*}
    done
    echo "$path"
}

cdnvm(){
    cd "$@";
    nvm_path=$(find-up .nvmrc | tr -d '[:space:]')

    # If there are no .nvmrc file, use the default nvm version
    if [[ ! $nvm_path = *[^[:space:]]* ]]; then

        declare default_version;
        default_version=$(nvm version default);

        # If there is no default version, set it to `node`
        # This will use the latest version on your machine
        if [[ $default_version == "N/A" ]]; then
            nvm alias default node;
            default_version=$(nvm version default);
        fi

        # If the current version is not the default version, set it to use the default version
        if [[ $(nvm current) != "$default_version" ]]; then
            nvm use default;
        fi

        elif [[ -s $nvm_path/.nvmrc && -r $nvm_path/.nvmrc ]]; then
        declare nvm_version
        nvm_version=$(<"$nvm_path"/.nvmrc)

        # Add the `v` suffix if it does not exists in the .nvmrc file
        if [[ $nvm_version != v* ]]; then
            nvm_version="v""$nvm_version"
        fi

        # If it is not already installed, install it
        if [[ $(nvm ls "$nvm_version" | tr -d '[:space:]') == "N/A" ]]; then
            nvm install "$nvm_version";
        fi

        if [[ $(nvm current) != "$nvm_version" ]]; then
            nvm use "$nvm_version";
        fi
    fi
}
alias cd='cdnvm'

Questo è un miglioramento rispetto a:

Questo alias cercherà "su" dalla directory corrente per rilevare un file .nvmrc file. Se lo trova, passerà a quella versione; in caso contrario, utilizzerà la versione predefinita.


Sembra un po 'lento ma mi piace molto questa opzione
BossmanT

@ BossmanT Con "sembra un po 'lento", intendi dire che potresti indovinare che è lento guardando quello che fa, o in realtà l'hai trovato lento a funzionare?
callum

@callum solo osservandolo in esecuzione nel mio ambiente bash, tuttavia non sono state eseguite prove a tempo, è circa una frazione di secondo più lento, ovviamente niente di significativo
BossmanT

Non sono riuscito a rilevare alcun ritardo. La corsa cdnon è qualcosa che potresti mai fare in grandi lotti, quindi non penso sia importante a meno che il ritardo non sia evidente a un essere umano.
callum

3

Ho provato molte soluzioni per questo e niente ha funzionato come volevo, quindi ho scritto il mio:

Funzione ZSH per passare automaticamente alla versione corretta del nodo

Per quanto ne so, questo è l'unico che soddisfa tutti i seguenti criteri:

  • ti garantisce di essere sempre sulla versione giusta cercando nell'albero delle directory per trovare quella più vicina .nvmrc(proprio come nvm use);
  • può gestire qualsiasi .nvmrcformato valido ;
  • ti avverte chiaramente se nessuna versione installata soddisfa il .nvmrc,
  • presume che tu voglia defaultse non c'è nessun .nvmrcpunto sull'albero;
  • è completamente silenzioso e veloce se sei già sulla versione corretta di Node.

1

Ancora un'altra soluzione usando direnv . Direnv viene fornito con OS X e molte distribuzioni, quindi non è necessaria alcuna installazione.

Aggiungi queste due righe al tuo .zshenv o .bash_profile a seconda della shell che usi:


export NVM_DIR="$HOME/.nvm" # You probably have this line already
export NODE_VERSIONS="${NVM_DIR}/versions/node"
export NODE_VERSION_PREFIX="v"

Aggiungi un file .envrc alla radice del progetto con il contenuto

set -e
use node

Infine cd nella tua directory. (Non dimenticare di fonte .zshenv)

direnv ti chiederà di consentire il caricamento della configurazione. generedirenv allow e voilà!

Nota che direnv non supporta costrutti fantasiosi come lts/*in .nvrmc. Sul lato positivo, direnv supporta un sacco di runtime come node, php, go, pyhton, ruby ​​ecc. Permettendoci di utilizzare un unico strumento per risolvere i problemi di percorso.


0

Estendendo la risposta di @Adriano P , proporrei questa versione che è meno generale (funziona solo se .nvmrcè impostata su una radice del repository git ), ma funziona nei casi in cui si naviga altrove nel progetto rispetto alla sua radice:

_enter_dir() {
    local git_root
    git_root=$(git rev-parse --show-toplevel 2>/dev/null)

    if [[ "$git_root" == "$PREV_PWD" ]]; then
        return
    elif [[ -n "$git_root" && -f "$git_root/.nvmrc" ]]; then
        nvm use
        NVM_DIRTY=1
    elif [[ "$NVM_DIRTY" == 1 ]]; then
        nvm use default
        NVM_DIRTY=0
    fi
    PREV_PWD="$git_root"
}

export PROMPT_COMMAND=_enter_dir
#export PROMPT_COMMAND="$PROMPT_COMMAND;_enter_dir"  # use this if PROMPT_COMMAND already defined

0

Uso questo framework di configurazione zsh chiamato Oh My Zsh. È un repository molto attivo con aggiornamenti regolari. Provalo e sono sicuro che lo adorerai. Oh, e ha la funzione automatica .nvmrc integrata, quindi è semplice come installare il pacchetto tramite npm!

https://github.com/robbyrussell/oh-my-zsh


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.