lancez `nvm use` automatiquement chaque fois qu'il y a un fichier .nvmrc dans le répertoire

87

Comment configurer mon shell pour qu'il nvm uses'exécute automatiquement à chaque fois qu'il y a un fichier .nvmrc dans le répertoire et utiliser la dernière version ou une configuration globale lorsqu'il n'y a pas de fichier .nvmrc?

Gabo Esquivel
la source
2
Ce cas d'utilisation est maintenant documenté dans la documentation officielle nvm sous Deep Shell Integration . Vous pouvez également voir ma réponse pour le bashshell.
d4nyll

Réponses:

86

Si vous utilisez zsh (z shell):

Appel automatique de 'nvm use' dans un répertoire avec un fichier .nvmrc

Mettez ceci dans votre $ HOME / .zshrc pour appeler nvm use automatiquement chaque fois que vous entrez dans un répertoire contenant un fichier .nvmrc avec une chaîne indiquant à nvm quel nœud utiliser:

# 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

Plus d'infos: https://github.com/creationix/nvm#zsh

Rotareti
la source
5
Cela a très bien fonctionné pour moi, mais a entraîné une baisse des performances cd, car il s'exécute chaque fois que vous changez de répertoire. J'ai ajouté [[ -a .nvmrc ]] || returnà la première ligne de load-nvmrc (), et cela a considérablement amélioré les performances de celui
Belgabad
@Belgabad C'est plus performant, car avec votre ligne, le script ne sera pas vérifié .nvmrcdans les répertoires parents et il ne retournera pas non plus à la nodeversion par défaut lorsque vous cdsortez du répertoire du projet.
Rotareti
49

Si vous utilisez bash, vous pouvez ajouter ceci à votre ~/.bashrcfichier:

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

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

export PROMPT_COMMAND=enter_directory
devius
la source
30

Excellente réponse de @devius .

Je viens de l'étendre pour qu'il puisse revenir à la version par défaut en laissant un répertoire avec .nvmrcun autre sans lui.

~/.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
Adriano P
la source
En utilisant bash sur Windows, cela revient node v.0.0 (64-bit) is not installed.même si le fichier .nvmrc a 9.3.
hofnarwillie
2
Correction en utilisantVERSION=$(cat .nvmrc); nvm use $VERSION
hofnarwillie
Je devrais aussi dire que cela utilise nvm-for-windows qui est une bête complètement différente. Mais avec le script ci-dessus + modification, cela fonctionne un régal. +1
hofnarwillie
26

Je viens de découvrir le changement automatique de version pour Node.js https://github.com/wbyoung/avn , vous pouvez l'utiliser.

Vous pouvez également suivre ce fil https://github.com/creationix/nvm/issues/110

Gabo Esquivel
la source
28
C'est déprimant .. n'y a-t-il pas de limite à la profondeur de la pile d'outils? node → npm → nvm → avn, et sauvegarder. soupir je joue au ballon, mais ma passion diminue à chaque piratage. (et merci pour le lien, bien sûr, gabo.)
hraban
Aucun des commentaires sur le fil mentionné n'a fonctionné avec bash pour moi. Peut-être qu'ils sont tous pour MacOS. Pour quelque chose qui fonctionne dans Ubuntu, consultez ma réponse ci-dessous.
devius
12

Cette réponse est tirée de la documentation officielle nvm .

Mettez ce qui suit à la fin de votre $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'

Il s'agit d'une amélioration par rapport à:

Cet alias rechercherait «en haut» de votre répertoire actuel afin de détecter un .nvmrcfichier. S'il le trouve, il passera à cette version; sinon, il utilisera la version par défaut.

d4nyll
la source
Semble un peu lent mais j'aime vraiment cette option
BossmanT
@BossmanT Par «semble un peu lent», voulez-vous dire que vous devinez qu'il est lent à regarder ce qu'il fait, ou que vous l'avez trouvé lent à fonctionner?
callum le
@callum uniquement en l'observant en cours d'exécution dans mon environnement bash, aucun contre-la-montre n'a été couru pour lui cependant, c'est environ une fraction de seconde plus lent, rien de significatif bien sûr
BossmanT
Je n'ai détecté aucun décalage. Courir cdn'est pas quelque chose que vous êtes susceptible de faire en gros lots, donc je ne pense pas que cela compte à moins que le décalage ne soit perceptible par un humain.
callum le
2

J'ai essayé de nombreuses solutions pour cela et rien n'a fonctionné comme je le souhaitais, alors j'ai écrit la mienne:

Fonction ZSH pour passer automatiquement à la version correcte du nœud

Pour autant que je sache, c'est le seul qui répond à tous les critères suivants:

  • garantit que vous êtes toujours sur la bonne version en recherchant dans l'arborescence des répertoires pour trouver le plus proche .nvmrc(comme nvm use);
  • peut gérer n'importe quel .nvmrcformat valide ;
  • vous avertit clairement si aucune version installée ne satisfait le .nvmrc,
  • suppose que vous voulez defaults'il n'y a aucun .nvmrcendroit dans l'arbre;
  • est complètement silencieux et rapide si vous êtes déjà sur la bonne version de Node.
callum
la source
1

Encore une autre solution utilisant direnv . Direnv est fourni avec OS X et de nombreuses distributions, aucune installation n'est donc nécessaire.

Ajoutez ces deux lignes à votre .zshenv ou .bash_profile selon le shell que vous utilisez:


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

Ajouter un fichier .envrc à la racine du projet avec le contenu

set -e
use node

Enfin cd dans votre répertoire. (N'oubliez pas de vous procurer .zshenv)

direnv vous demandera d'autoriser la configuration de chargement. Tapez direnv allowet voilà!

Notez que direnv ne prend pas en charge les constructions sophistiquées comme lts/*dans .nvrmc. Du côté positif, direnv prend en charge un tas d'exécutables comme node, php, go, pyhton, ruby ​​etc. nous permettant d'utiliser un seul outil pour résoudre les problèmes de chemin.

R. Haluk Öngör
la source
0

En prolongeant la réponse @Adriano P , je proposerais cette version moins générale (ne fonctionne que si elle .nvmrcest définie sur une racine de référentiel git ), mais fonctionne dans les cas où nous naviguons ailleurs dans le projet que sa racine:

_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
laur
la source
0

J'utilise ce cadre de configuration zsh appelé Oh My Zsh. C'est un référentiel très actif avec des mises à jour régulières. Essayez-le et je suis sûr que vous allez l'adorer. Oh, et il a la fonction automatique .nvmrc intégrée, donc c'est aussi simple que d'installer le paquet via npm!

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

Satya Sampathirao
la source