запускати `nvm use` автоматично кожного разу, коли в каталозі є файл .nvmrc


87

Як налаштувати мою оболонку так, щоб вона nvm useзапускалася автоматично кожного разу, коли в каталозі є файл .nvmrc, і використовувати останню версію або глобальну конфігурацію, коли файлу .nvmrc немає?


2
Цей випадок використання зараз задокументовано в офіційній документації nvm під Deep Shell Integration . Ви також можете побачити мою відповідь на bashоболонку.
d4nyll

Відповіді:


86

Якщо ви використовуєте zsh (z shell):

Автоматичний виклик 'nvm use' у каталозі з файлом .nvmrc

Помістіть це у свій $ HOME / .zshrc, щоб автоматично викликати використання nvm кожного разу, коли ви вводите каталог, що містить файл .nvmrc із рядком, який повідомляє nvm, який вузол використовувати:

# 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

Більше інформації: https://github.com/creationix/nvm#zsh


5
Це дуже добре спрацювало для мене, але призвело до досягнення продуктивності cd, оскільки вона запускається щоразу, коли ви змінюєте каталоги. Я додав [[ -a .nvmrc ]] || returnдо першого рядка load-nvmrc (), і це суттєво покращило його продуктивність
Белгабад

@Belgabad Це ефективніше, оскільки у вашому рядку сценарій не перевірятиме наявність .nvmrcбатьківських каталогів, а також не повернеться до nodeверсії за замовчуванням, коли ви cdвийдете з папки проекту.
Ротареті,

49

Якщо ви використовуєте bash, ви можете додати це у свій ~/.bashrcфайл:

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

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

export PROMPT_COMMAND=enter_directory

30

Відмінна відповідь від @devius .

Я просто розширив його, щоб він міг повернутися до версії за замовчуванням, залишаючи каталог із .nvmrcіншим без нього.

~/.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

За допомогою bash у Windows це повертається, node v.0.0 (64-bit) is not installed.навіть якщо файл .nvmrc є 9.3.
hofnarwillie

2
Виправлено за допомогоюVERSION=$(cat .nvmrc); nvm use $VERSION
hofnarwillie

Слід також сказати, що за допомогою nvm-for-windows це зовсім інший звір. Але з наведеним вище сценарієм + модифікацією це працює. +1
hofnarwillie

26

Я щойно дізнався про автоматичне перемикання версій для Node.js https://github.com/wbyoung/avn , ви можете цим скористатися.

Ви також можете стежити за цією темою https://github.com/creationix/nvm/issues/110


29
Це гнітюче .. чи немає обмежень глибині стопки інструментів? вузол → npm → nvm → avn та резервне копіювання. зітхаю Я буду грати в м'яч, але моя пристрасть слабшає з кожним хаком. (і дякую за посилання, звичайно, габо.)
hraban

Жоден з коментарів у згаданому ланцюжку не працював із bash для мене. Можливо, вони всі для MacOS. Щось, що працює в Ubuntu, перевірте мою відповідь нижче.
devius

12

Ця відповідь взята з офіційної документації nvm .

Поставте в кінці вашого $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'

Це покращення порівняно з:

Цей псевдонім шукатиме "вгору" у вашому поточному каталозі, щоб виявити .nvmrcфайл. Якщо знайде, перейде на цю версію; якщо ні, то використовуватиметься версія за замовчуванням.



@BossmanT За словами "виглядає трохи повільно", ви маєте на увазі, що ви здогадуєтесь, що він повільний, не дивлячись на те, що він робить, або ви насправді виявили, що він працює повільно?
callum

@callum лише від спостереження, як він працює в моєму середовищі bash, для нього не проводились часові випробування, однак, це приблизно частка секунди повільніше, звичайно, нічого суттєвого
BossmanT

Я не міг виявити жодного відставання. Біг cd- це не те, що ти коли-небудь можеш робити великими партіями, тому я думаю, що це не має значення, якщо відставання не помітно для людини.
callum

2

Я спробував багато рішень для цього, і нічого не працювало так, як я хотів, тому я написав своє:

Функція ZSH для автоматичного перемикання на правильну версію вузла

Наскільки мені відомо, це єдиний, який відповідає усім наступним критеріям:

  • гарантує, що ви завжди у правильній версії, шукаючи дерево каталогів, щоб знайти найближче .nvmrc(так само, як nvm use);
  • може обробляти будь-який допустимий .nvmrcформат;
  • чітко попереджає вас, якщо жодна встановлена ​​версія не відповідає .nvmrc,
  • припускає, що ви хочете, defaultякщо .nvmrcніде на дереві ніде немає ;
  • є абсолютно безшумним і швидким, якщо ви вже використовуєте правильну версію Node.

1

Ще одне рішення з використанням direnv . Direnv поставляється з OS X та багатьма дистрибутивами, тому установка не потрібна.

Додайте ці два рядки до вашого .zshenv або .bash_profile залежно від того, яку оболонку ви використовуєте:


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

Додайте файл .envrc до кореня проекту із вмістом

set -e
use node

Нарешті компакт-диск до вашого каталогу. (Не забудьте джерело .zshenv)

direnv попросить вас дозволити завантаження конфігурації. Введіть direnv allowі вуаля!

Зверніть увагу, що direnv не підтримує вигадливі конструкції, як lts/*у .nvrmc. Позитивною стороною є те, що direnv підтримує купу таких середовищ виконання, як node, php, go, pyhton, ruby ​​тощо, що дозволяє нам використовувати єдиний інструмент для вирішення проблем із шляхами.


0

Розширюючи відповідь на @Adriano P , я запропонував би цю менш загальну версію (працює лише в тому випадку, якщо .nvmrcвстановлено в кореневому каталозі репозиторію git ), але працює у випадках, коли ми переходимо до іншого місця проекту, ніж його корінь:

_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

Я використовую цю структуру конфігурації zsh, яку називають Oh My Zsh. Це дуже активне сховище з регулярними оновленнями. Спробуйте, і я впевнений, вам сподобається. О, і в нього вбудована автоматична функція .nvmrc, тому це так само просто, як встановити пакет через npm!

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.