tự động chạy `nvm use` mỗi khi có tệp .nvmrc trên thư mục


87

Làm cách nào để định cấu hình trình bao của tôi để nvm usechạy tự động mỗi khi có tệp .nvmrc trên thư mục và sử dụng phiên bản mới nhất hoặc cấu hình chung khi không có tệp .nvmrc?


2
Trường hợp sử dụng này hiện đã được ghi lại trong tài liệu nvm chính thức trong Tích hợp vỏ sâu . Bạn cũng có thể xem câu trả lời của tôi cho bashshell.
d4nyll

Câu trả lời:


86

Nếu bạn sử dụng zsh (z shell):

Tự động gọi 'nvm use' trong thư mục có tệp .nvmrc

Đặt cái này vào $ HOME / .zshrc của bạn để gọi nvm sử dụng tự động bất cứ khi nào bạn nhập thư mục chứa tệp .nvmrc với một chuỗi cho nvm biết nút nào sẽ sử dụng:

# 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

Thông tin thêm: https://github.com/creationix/nvm#zsh


5
Điều này thực sự hiệu quả đối với tôi, nhưng gây ra ảnh hưởng đến hiệu suất cd, vì nó chạy mỗi khi bạn thay đổi thư mục. Tôi đã thêm [[ -a .nvmrc ]] || returnvào dòng đầu tiên của tải nvmrc (), và cải thiện đáng kể hiệu suất của nó
Belgabad

@Belgabad Nó hoạt động hiệu quả hơn, bởi vì với dòng của bạn, tập lệnh sẽ không kiểm tra .nvmrctrong thư mục mẹ và nó cũng sẽ không quay lại nodephiên bản mặc định khi bạn cdra khỏi dự án.
Rotareti

49

Nếu bạn sử dụng bash, bạn có thể thêm cái này vào ~/.bashrctệp của mình :

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

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

export PROMPT_COMMAND=enter_directory

30

Câu trả lời tuyệt vời từ @devius .

Tôi vừa mở rộng nó để nó có thể trở lại phiên bản mặc định khi rời một thư mục với một thư .nvmrcmục khác mà không có nó.

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

Sử dụng bash trên windows, nó trả về node v.0.0 (64-bit) is not installed.mặc dù tệp .nvmrc có 9.3.
hofnarwillie

2
Cố định bằng cách sử dụngVERSION=$(cat .nvmrc); nvm use $VERSION
hofnarwillie

Tôi cũng nên nói rằng việc sử dụng nvm-for-windows là một con thú hoàn toàn khác. Nhưng với script + sửa đổi ở trên, nó hoạt động tốt. +1
hofnarwillie

26

Tôi vừa tìm hiểu về Chuyển đổi phiên bản tự động cho Node.js https://github.com/wbyoung/avn , bạn có thể sử dụng điều đó.

Bạn cũng có thể theo dõi chủ đề này https://github.com/creationix/nvm/issues/110


29
Điều này thật đáng buồn .. không có giới hạn cho chiều sâu ngăn xếp công cụ? nút → npm → nvm → avn, và sao lưu. thở dài Tôi sẽ chơi bóng, nhưng niềm đam mê của tôi đang suy yếu sau mỗi lần hack. (và cảm ơn vì liên kết, tất nhiên, gabo.)
hraban

Không có nhận xét nào tại chủ đề được đề cập hoạt động với bash cho tôi. Có thể tất cả chúng đều dành cho MacOS. Đối với một cái gì đó hoạt động trong Ubuntu, hãy kiểm tra câu trả lời của tôi bên dưới.
lệch

12

Câu trả lời này được lấy từ tài liệu nvm chính thức .

Đặt phần sau vào cuối của bạn $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'

Đây là một cải tiến so với:

  • Câu trả lời của @Gabo Esquivel - bởi vì bạn sẽ không phải chuyển sang một công cụ khác ( avn)
  • Câu trả lời của @ defus@Adriano P - không giải quyết các tình huống mà bạn đang ở trong một dự án

Bí danh này sẽ tìm kiếm 'lên' từ thư mục hiện tại của bạn để phát hiện một .nvmrctệp. Nếu nó tìm thấy nó, nó sẽ chuyển sang phiên bản đó; nếu không, nó sẽ sử dụng phiên bản mặc định.


Xuất hiện hơi chậm nhưng tôi thực sự thích tùy chọn này
BossmanT

@BossmanT Bởi 'có vẻ hơi chậm', bạn có nghĩa là bạn sẽ đoán nó chạy chậm khi nhìn vào hoạt động của nó, hay bạn thực sự thấy nó chạy chậm?
callum 24/09/19

@callum chỉ từ quan sát nó chạy trong môi trường bash tôi, không có thời gian thử nghiệm là ran cho nó Tuy nhiên, khoảng một phần nhỏ của một giây chậm hơn, không bất cứ điều gì nó có ý nghĩa dĩ nhiên
BossmanT

Tôi không thể phát hiện bất kỳ độ trễ nào. Chạy cdkhông phải là điều bạn có thể làm trong một loạt lớn, vì vậy tôi không nghĩ nó quan trọng trừ khi độ trễ là đáng chú ý đối với con người.
callum

2

Tôi đã thử nhiều giải pháp cho điều này và không có gì hoạt động theo cách tôi muốn, vì vậy tôi đã viết của riêng mình:

Chức năng ZSH để tự động chuyển sang phiên bản Node chính xác

Theo như tôi biết, đây là chiếc duy nhất đáp ứng tất cả các tiêu chí sau:

  • đảm bảo bạn luôn sử dụng đúng phiên bản bằng cách tìm kiếm trên cây thư mục để tìm phiên bản gần nhất .nvmrc(giống như nvm use);
  • có thể xử lý bất kỳ .nvmrcđịnh dạng hợp lệ nào ;
  • cảnh báo rõ ràng cho bạn nếu không có phiên bản đã cài đặt nào đáp ứng .nvmrc,
  • giả sử bạn muốn defaultnếu không có .nvmrcbất cứ nơi nào trên cây;
  • hoàn toàn im lặng và nhanh chóng nếu bạn đã sử dụng đúng phiên bản Node.

1

Tuy nhiên, một giải pháp khác sử dụng direnv . Direnv đi kèm với OS X và nhiều bản phân phối nên không cần cài đặt.

Thêm hai dòng này vào .zshenv hoặc .bash_profile của bạn tùy thuộc vào trình bao bạn sử dụng:


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

Thêm tệp .envrc vào gốc dự án với nội dung

set -e
use node

Cuối cùng cd vào thư mục của bạn. (Đừng quên dẫn nguồn .zshenv)

direnv sẽ yêu cầu bạn cho phép tải cấu hình. Gõ direnv allowvà thì đấy!

Lưu ý rằng direnv không hỗ trợ các cấu trúc ưa thích như lts/*trong .nvrmc. Về mặt tích cực, direnv hỗ trợ một loạt các thời gian chạy như node, php, go, pyhton, ruby, v.v. cho phép chúng tôi sử dụng một công cụ duy nhất để giải quyết các vấn đề về đường dẫn.


0

Mở rộng trên câu trả lời @Adriano P , tôi muốn đề xuất phiên bản này ít tổng quát hơn (chỉ hoạt động nếu .nvmrcđược đặt trên gốc kho lưu trữ git ), nhưng hoạt động trong các trường hợp khi chúng tôi điều hướng đến nơi khác trong dự án chứ không phải gốc của nó:

_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

Tôi sử dụng khung cấu hình zsh này được gọi là Oh My Zsh. Đó là một kho lưu trữ rất tích cực với các bản cập nhật thường xuyên. Hãy thử nó và tôi chắc chắn bạn sẽ thích nó. Ồ, và nó có tính năng .nvmrc tự động được tích hợp sẵn nên việc cài đặt gói thông qua npm cũng đơn giản như vậy!

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


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.