NodeJS 如何编写自动更改节点版本的.nvmrc文件

35g0bw71  于 2023-04-11  发布在  Node.js
关注(0)|答案(5)|浏览(313)

嗨,我有两个项目,一个在angularjs 4.4.7中,另一个在angular 6版本中。我需要在节点版本之间切换。我尝试使用NVM手动工作。如何处理angularjs程序中的版本更改,以便在自动加载最新的angular页面时更改节点版本。是否有类似的可能方法。我也通过#avn,但如何创建。节点版本文件。有人可以帮助任何链接或正确的示例步骤

igsr9ssn

igsr9ssn1#

正如@Aditya-M-P已经提到的,你可以在你的项目根目录下运行以下命令来生成.nvmrc,为你的项目设置一个所需的NodeJS版本来正常工作:

node -v > .nvmrc

它将在.nvmrc文件中生成如下内容:

v10.16.2

使用10.16.2而不使用v字母也可以正常工作。
然而,在.nvmrc部分的官方文档中,它从来没有提到一旦你创建了这个文件,指定的节点版本将自动加载。所以这还不够,你需要运行下面的命令,以便nvm可以查找.nvmrc文件来加载指定的版本:

nvm use

下面是一个用于演示的gif:

自动加载指定节点版本:

您需要根据使用的bashzsh向shell配置添加其他内容
要获得它们的确切配置,请按照相应的shell配置部分中的说明进行操作。
在我的例子中,我使用的是zsh,所以我需要在.zshrc文件的末尾添加这个,这里是确认它像魅力一样工作的图像:

# 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

我希望它能对任何面临同样问题的人有用!😎

h4cxqtbf

h4cxqtbf2#

查看GitHub上nvm的repo中的README。那里已经给出了解决方案。

shell 集成

对于bash,在你的$HOME/.bashrc后面加上以下内容,shell会根据目录下的.nvmrc文件修改节点版本。

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)

        declare locally_resolved_nvm_version
        # `nvm ls` will check all locally-available versions
        # If there are multiple matching versions, take the latest one
        # Remove the `->` and `*` characters and spaces
        # `locally_resolved_nvm_version` will be `N/A` if no local versions are found
        locally_resolved_nvm_version=$(nvm ls --no-colors "$nvm_version" | tail -1 | tr -d '\->*' | tr -d '[:space:]')

        # If it is not already installed, install it
        # `nvm install` will implicitly use the newly-installed version
        if [[ "$locally_resolved_nvm_version" == "N/A" ]]; then
            nvm install "$nvm_version";
        elif [[ $(nvm current) != "$locally_resolved_nvm_version" ]]; then
            nvm use "$nvm_version";
        fi
    fi
}
alias cd='cdnvm'

因为Bash中没有钩子支持,所以上面的解决方案很难看。
对于zsh,将其放入$HOME/.zshrc

# 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

更好的解决方案

更好的解决方案是使用nodenv。我不是在开玩笑,nodenv与nvm非常不同,而n。
nodenvrbenv家族的一员。这些版本管理器比其他版本管理器有很大的优势。
1.由于使用了shim可执行文件,无需每次修改环境变量PATH即可更改节点版本,因此内置支持自动切换节点版本

  1. nodenv中的自动版本切换不必挂接到chpwd上来定期检查目录更改。版本选择延迟到执行node命令时。
  2. nodenv中的命令是在脚本中实现的。而nvm中的命令是在函数中实现的,这意味着所有4000多行代码都必须在shell启动时解析,这大大增加了shell初始化时间。nodenv初始化速度要快得多。
    参考文献
xa9qqrwz

xa9qqrwz3#

正如在nvm存储库上与此相关的GitHub问题线程中所指出的,您可以在每个Angular项目文件夹中运行以下命令:

$ node -v > .nvmrc

请注意,在运行上面的命令之前,您需要首先在每个项目中切换到正确的node版本。

命令中发生了什么

  • node -v将把当前版本的node输出到stdout
  • 然后,>符号将redirecting输出到一个名为.nvmrc的文件(如果已经存在具有相同文件名的文件,它将覆盖)。
  • 在bash手册页的 REDIRECTION 部分阅读更多bash重定向:https://linux.die.net/man/1/bash

当你把cd文件夹放到你的目标目录时,nvm会首先读取文件,然后自动切换到正确的版本。

vh0rcniy

vh0rcniy4#

在项目的根目录下创建.nvmrc文件并使用该项目中所需的节点版本之后,可以使用类似

v12.20.0

你应该可以cd到项目文件夹并运行nvm use。这将打印如下内容:

Found '/Users/you/myproject/.nvmrc' with version <v12.20.0>
Now using node v12.20.0 (npm v6.14.8)

除了通过创建一个bash脚本来为您实现这一点外,NVM还没有提供自动化的AFAIK方法,NVM文档在这里详细介绍了该方法

o7jaxewo

o7jaxewo5#

对于一些比shell钩子更简单的东西,你可以在package.json中添加preinstallprebuild脚本,这样每次你尝试安装或构建项目时,都会使用在.nvmrc文件中定义的正确版本。
.nvmrc文件示例:

18.10.0

package.json文件中的示例脚本:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "preinstall": "nvm use",
  "prebuild": "nvm use",
  "build": "tsc"
},

我还没有测试过这个,但我计划很快将它添加到我自己的项目中。
注意:只有在执行npm install时才会调用preinstall钩子,而不是在安装特定模块时。

相关问题