Führen Sie `nvm use` jedes Mal automatisch aus, wenn sich eine .nvmrc-Datei im Verzeichnis befindet

87

Wie konfiguriere ich meine Shell so, dass nvm usesie jedes Mal automatisch ausgeführt wird, wenn sich eine .nvmrc-Datei im Verzeichnis befindet, und verwende die neueste Version oder eine globale Konfiguration, wenn keine .nvmrc-Datei vorhanden ist?

Gabo Esquivel
quelle
2
Dieser Anwendungsfall ist jetzt in der offiziellen NVM-Dokumentation unter Deep Shell Integration dokumentiert . Sie können auch meine Antwort für die bashShell sehen.
d4nyll

Antworten:

86

Wenn Sie zsh (z-Shell) verwenden:

Automatisches Aufrufen von 'nvm use' in einem Verzeichnis mit einer .nvmrc-Datei

Fügen Sie dies in Ihr $ HOME / .zshrc ein, um nvm use automatisch aufzurufen, wenn Sie ein Verzeichnis eingeben, das eine .nvmrc-Datei mit einer Zeichenfolge enthält, die nvm mitteilt, welcher Knoten verwendet werden soll:

# 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

Weitere Informationen: https://github.com/creationix/nvm#zsh

Rotareti
quelle
5
Dies hat bei mir sehr gut funktioniert, aber zu einem Leistungseinbruch geführt cd, da es jedes Mal ausgeführt wird, wenn Sie die Verzeichnisse wechseln. Ich [[ -a .nvmrc ]] || returnhabe die erste Zeile von load-nvmrc () hinzugefügt , und das hat die Leistung erheblich verbessert
Belgabad
@Belgabad Es ist leistungsfähiger, da das Skript mit Ihrer Zeile nicht .nvmrcin übergeordneten Verzeichnissen sucht und auch nicht zur Standardversion zurückkehrt, nodewenn Sie cddas Projektverzeichnis verlassen.
Rotareti
49

Wenn Sie bash verwenden , können Sie dies zu Ihrer ~/.bashrcDatei hinzufügen :

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

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

export PROMPT_COMMAND=enter_directory
Devius
quelle
30

Hervorragende Antwort von @devius .

Ich habe es gerade erweitert, damit es auf die Standardversion zurückgesetzt werden kann, wenn ein Verzeichnis mit .nvmrceinem anderen ohne es verlassen wird.

~/.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.
quelle
Wenn Sie bash unter Windows verwenden, wird dies zurückgegeben node v.0.0 (64-bit) is not installed., obwohl die .nvmrc-Datei vorhanden ist 9.3.
Hofnarwillie
2
VERSION=$(cat .nvmrc); nvm use $VERSION
Behoben
Ich sollte auch sagen, dass dies nvm-for-windows verwendet, was ein ganz anderes Biest ist. Aber mit dem obigen Skript + Modifikation funktioniert es ein Vergnügen. +1
Hofnarwillie
26

Ich habe gerade von Automatic Version Switching für Node.js https://github.com/wbyoung/avn erfahren , das können Sie verwenden.

Sie können diesem Thread auch folgen: https://github.com/creationix/nvm/issues/110

Gabo Esquivel
quelle
28
Dies ist deprimierend. Gibt es keine Begrenzung für die Tiefe des Werkzeugstapels? Knoten → npm → nvm → avn und sichern. Seufz Ich werde Ball spielen, aber meine Leidenschaft schwindet mit jedem Hack. (und danke für den Link natürlich gabo.)
hraban
Keiner der Kommentare im erwähnten Thread hat für mich mit bash funktioniert. Vielleicht sind sie alle für MacOS. Für etwas, das in Ubuntu funktioniert, überprüfen Sie meine Antwort unten.
Devius
12

Diese Antwort stammt aus der offiziellen NVM-Dokumentation .

Fügen Sie Folgendes am Ende Ihres ein $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'

Dies ist eine Verbesserung gegenüber:

  • @Gabo Esquivels Antwort - weil Sie nicht zu einem anderen Tool wechseln müssen ( avn)
  • Die Antworten von @ devius und @Adriano P - die sich nicht mit Situationen befassen, in denen Sie sich in einem Projekt befinden

Dieser Alias ​​würde in Ihrem aktuellen Verzeichnis nach "up" suchen, um eine .nvmrcDatei zu erkennen . Wenn es es findet, wechselt es zu dieser Version; Wenn nicht, wird die Standardversion verwendet.

d4nyll
quelle
Erscheint etwas langsam, aber ich mag diese Option wirklich
BossmanT
@BossmanT Mit "erscheint ein wenig langsam" meinen Sie, Sie würden vermuten, dass es langsam ist, wenn Sie sich ansehen, was es tut, oder Sie fanden es tatsächlich langsam zu laufen?
Callum
@ Callum nur von der Beobachtung, dass es in meiner Bash-Umgebung läuft, wurden keine Zeitfahren dafür durchgeführt, es ist jedoch etwa einen Bruchteil einer Sekunde langsamer, natürlich nichts Bedeutendes
BossmanT
Ich konnte keine Verzögerung feststellen. Laufen cdist nichts, was Sie wahrscheinlich jemals in großen Mengen tun werden, daher denke ich nicht, dass es wichtig ist, es sei denn, die Verzögerung ist für einen Menschen spürbar.
Callum
2

Ich habe viele Lösungen dafür ausprobiert und nichts hat so funktioniert, wie ich es wollte, also habe ich meine eigenen geschrieben:

ZSH-Funktion zum automatischen Umschalten auf die korrekte Knotenversion

Soweit ich weiß, ist dies das einzige, das alle folgenden Kriterien erfüllt:

  • garantiert, dass Sie immer auf der richtigen Version sind, indem Sie den Verzeichnisbaum durchsuchen, um die nächstgelegene zu finden .nvmrc(genau wie nvm use);
  • kann mit jedem gültigen .nvmrcFormat umgehen ;
  • warnt Sie deutlich, wenn keine installierte Version die .nvmrc,
  • nimmt an, dass Sie wollen, defaultwenn es .nvmrcnirgendwo oben im Baum gibt;
  • ist völlig leise und schnell, wenn Sie bereits die richtige Node-Version verwenden.
Callum
quelle
1

Noch eine andere Lösung mit direnv . Direnv wird mit OS X und vielen Distributionen geliefert, sodass keine Installation erforderlich ist.

Fügen Sie diese beiden Zeilen zu Ihrem .zshenv- oder .bash_profile hinzu, je nachdem, welche Shell Sie verwenden:


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

Fügen Sie dem Projektstamm eine .envrc-Datei mit dem Inhalt hinzu

set -e
use node

Schließlich CD in Ihr Verzeichnis. (Vergessen Sie nicht, .zshenv zu beschaffen)

direnv fordert Sie auf, die Ladekonfiguration zuzulassen. Typ direnv allowund voila!

Beachten Sie, dass direnv keine ausgefallenen Konstrukte wie lts/*in .nvrmc unterstützt. Positiv zu vermerken ist, dass direnv eine Reihe von Laufzeiten wie Node, PHP, Go, Pyhton, Ruby usw. unterstützt, sodass wir ein einziges Tool zur Lösung von Pfadproblemen verwenden können.

R. Haluk Öngör
quelle
0

Ausgehend von der Antwort von @Adriano P würde ich diese Version vorschlagen, die weniger allgemein ist (funktioniert nur, wenn sie .nvmrcauf einem Git- Repository-Stammverzeichnis festgelegt ist), aber in Fällen funktioniert, in denen wir zu einer anderen Stelle im Projekt navigieren als zu ihrem Stammverzeichnis:

_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
quelle
0

Ich verwende dieses zsh-Konfigurationsframework namens Oh My Zsh. Es ist ein sehr aktives Repository mit regelmäßigen Updates. Probieren Sie es aus und ich bin sicher, Sie werden es lieben. Oh, und es hat die automatische .nvmrc-Funktion eingebaut, so dass es so einfach ist, das Paket bis npm zu installieren!

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

Satya Sampathirao
quelle