Node 版本管理器

目录
- 简介
- 关于
- 安装与更新
- 用法
- 运行测试
- 环境变量
- Bash 补全
- 兼容性问题
- 在 Alpine Linux 上安装 nvm
- 卸载 / 移除
- 开发环境 Docker
- 常见问题
- macOS 故障排除
- WSL 故障排除
- 维护者
- 项目支持
- 企业支持
- 许可证
- 版权声明
简介
nvm 让你可以通过命令行快速安装和使用不同版本的 node。
示例:
$ nvm install 24
Now using node v24.14.0 (npm v11.9.0)
$ node -v
v24.14.0
$ nvm use 22
Now using node v22.22.1 (npm v10.9.4)
$ node -v
v22.22.1
$ nvm use 20
Now using node v20.20.1 (npm v10.8.2)
$ node -v
v20.20.1
就这么简单!
关于
nvm 是一个 node.js 的版本管理器,设计为按用户安装、按 Shell 调用。nvm 可以在任何符合 POSIX 标准的 Shell 上工作(sh、dash、ksh、zsh、bash),特别是在这些平台上:Unix、macOS 和 Windows WSL。
安装与更新
安装 & 更新脚本
要安装或更新 nvm,你应该运行安装脚本。你可以手动下载并运行脚本,或者使用以下 cURL 或 Wget 命令:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
运行以上任一命令会下载脚本并执行。脚本会将 nvm 仓库克隆到 ~/.nvm,并尝试将下面的配置片段添加到正确的配置文件(~/.bashrc、~/.bash_profile、~/.zshrc 或 ~/.profile)中。如果你发现安装脚本更新了错误的配置文件,请将 $PROFILE 环境变量设置为配置文件的路径,然后重新运行安装脚本。
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 这会加载 nvm
附加说明
-
如果环境变量
$XDG_CONFIG_HOME存在,nvm 会将文件放在那里。 -
你可以在上述脚本末尾添加
--no-use参数,推迟使用nvm,直到你手动use它:
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use # 这会加载 nvm,但不自动使用默认版本
-
你可以使用
NVM_SOURCE、NVM_DIR、PROFILE和NODE_VERSION变量自定义安装源、目录、配置文件和版本。例如:curl ... | NVM_DIR="path/to/nvm"。请确保NVM_DIR末尾不要有斜杠。 -
安装程序可以使用
git、curl或wget来下载nvm,看哪个可用。 -
你可以让安装程序不编辑你的 Shell 配置文件(例如如果你已经通过 zsh nvm 插件 获得了补全功能),方法是在运行
install.sh脚本之前设置PROFILE=/dev/null。一行命令示例:PROFILE=/dev/null bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash'
在 Docker 中安装
当以非交互方式调用 bash 时(比如在 Docker 容器中),常规的配置文件都不会被加载。为了像平常一样使用 nvm、node 和 npm,你可以指定特殊的 BASH_ENV 变量,bash 在非交互调用时会加载它。
# 使用 bash 作为 Shell
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# 创建一个被交互和非交互 bash Shell 共同加载的脚本文件
ENV BASH_ENV "${HOME}/.bash_env"
RUN touch "${BASH_ENV}"
RUN echo '. "${BASH_ENV}"' >> ~/.bashrc
# 下载并安装 nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | PROFILE="${BASH_ENV}" bash
RUN echo node > .nvmrc
RUN nvm install
在 Docker 中安装用于 CICD 任务
更健壮,适用于 CI/CD 任务。可以在交互和非交互容器中运行。 参见 https://github.com/nvm-sh/nvm/issues/3531。
FROM ubuntu:latest
ARG NODE_VERSION=20
# 安装 curl
RUN apt update && apt install curl -y
# 安装 nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
# 设置环境变量
ENV NVM_DIR=/root/.nvm
# 安装 node
RUN bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION"
# 设置 ENTRYPOINT 以重新加载 nvm 环境
ENTRYPOINT ["bash", "-c", "source $NVM_DIR/nvm.sh && exec \"$@\"", "--"]
# 设置 cmd 为 bash
CMD ["/bin/bash"]
此示例默认安装 nodejs v20.x.y。你可以通过 docker build 参数轻松覆盖版本,例如:
docker build -t nvmimage --build-arg NODE_VERSION=19 .
镜像创建完成后,你可以交互式启动容器并运行命令,例如:
docker run --rm -it nvmimage
root@0a6b5a237c14:/# nvm -v
0.40.8
非交互示例:
user@host:/tmp/test $ docker run --rm -it nvmimage node -v
v19.9.0
user@host:/tmp/test $ docker run --rm -it nvmimage npm -v
9.6.3
Linux 故障排除
在 Linux 上,运行安装脚本后,如果你遇到 nvm: command not found 或者输入 command -v nvm 后终端没有任何输出,只需关闭当前终端,打开一个新终端,然后重新验证即可。
或者,你可以在命令行上为不同的 Shell 运行以下命令:
bash: source ~/.bashrc
zsh: source ~/.zshrc
ksh: . ~/.profile
这些命令应该就能加载 nvm 命令。
macOS 故障排除
自 OS X 10.9 起,/usr/bin/git 已由 Xcode 命令行工具预置,这意味着我们无法正确检测 Git 是否已安装。你需要在运行安装脚本之前手动安装 Xcode 命令行工具,否则安装会失败。(参见 #1782)
如果你在运行安装脚本后遇到 nvm: command not found,可能的原因之一:
-
自 macOS 10.15 起,默认 Shell 是
zsh,nvm 会查找.zshrc来更新,但默认没有安装。请使用touch ~/.zshrc创建一个,然后重新运行安装脚本。 -
如果你使用 bash(以前的默认 Shell),你的系统可能没有
.bash_profile或.bashrc文件来设置命令。请使用touch ~/.bash_profile或touch ~/.bashrc创建其中一个,然后重新运行安装脚本。然后运行. ~/.bash_profile或. ~/.bashrc来加载nvm命令。 -
你以前使用过
bash,但现在安装了zsh。你需要手动将这些行添加到~/.zshrc,然后运行. ~/.zshrc。 -
你可能需要重启终端实例或运行
. ~/.nvm/nvm.sh。重启终端/打开新标签页/新窗口,或者运行 source 命令都会加载命令和新配置。 -
如果以上方法都无效,你可能需要重启终端实例。尝试在终端中打开新标签页/新窗口再试。
如果以上方法不能解决问题,你可以尝试以下操作:
-
如果你使用 bash,可能是你的
.bash_profile(或~/.profile)没有正确加载~/.bashrc。你可以通过添加source ~/<your_profile_file>来修复,或者按照下面的下一步操作。 -
尝试将安装部分的代码片段添加到你常用的配置文件中(
~/.bash_profile、~/.zshrc、~/.profile或~/.bashrc),它会找到正确的 nvm 目录并加载 nvm。 -
有关此问题的更多信息和可能的解决方法,请参考这里
注意 对于搭载 Apple Silicon 芯片的 Mac,node 从 v16.0.0 开始提供 arm64 架构的 Darwin 安装包,从 v14.17.0 开始提供实验性的 arm64 源码编译支持。如果你在使用 nvm 安装 node 时遇到问题,你可能需要更新到这些版本或更高版本。
Ansible
你可以使用一个任务:
- name: Install nvm
ansible.builtin.shell: >
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
args:
creates: "{{ ansible_env.HOME }}/.nvm/nvm.sh"
验证安装
要验证 nvm 是否已安装,请执行:
command -v nvm
如果安装成功,应该输出 nvm。请注意 which nvm 不会起作用,因为 nvm 是一个 source 进来的 Shell 函数,而不是可执行二进制文件。
注意: 在 Linux 上,运行安装脚本后,如果你遇到 nvm: command not found 或者输入 command -v nvm 后终端没有任何输出,只需关闭当前终端,打开一个新终端,然后重新验证即可。
重要说明
如果你运行的系统没有预编译的二进制包可用,这意味着你需要从源代码安装 node 或 io.js,你需要确保你的系统有 C++ 编译器。对于 OS X,Xcode 就可以;对于 Debian/Ubuntu 等基于 GNU/Linux 的系统,build-essential 和 libssl-dev 包即可。
注意: nvm 在某些情况下也支持 Windows。它应该可以通过 WSL(Windows Subsystem for Linux)工作,具体取决于 WSL 的版本。它也应该可以在 Git Bash(MSYS)或 Cygwin 上工作。除此之外,对于 Windows,存在一些替代方案,但它们不由我们支持或开发:
注意: nvm 也不支持 Fish(参见 #303)。存在一些替代方案,但它们不由我们支持或开发:
- bass 允许你在 fish shell 中使用为 Bash 编写的工具
- fast-nvm-fish 只适用于版本号(不适用于别名),但不会显著拖慢 Shell 启动速度
- plugin-nvm 是 Oh My Fish 的插件,让 nvm 及其补全在 fish shell 中可用
- nvm.fish - 你会爱上的 Node.js 版本管理器,专为 Fish 打造
- fish-nvm - nvm 的 fish 封装,延迟加载 nvm,直到真正使用时才加载。
注意: 我们在 FreeBSD 上仍然存在一些问题,因为没有 FreeBSD 的官方预编译二进制包,从源代码编译可能需要补丁;参见 issue 工单:
注意: 在 OS X 上,如果你没有安装 Xcode 并且不想下载约 4.3GB 的文件,你可以安装 Command Line Tools。你可以查看这篇博客了解如何操作:
注意: 在 OS X 上,如果你有/曾经有"系统"node 安装,并且想全局安装模块,请注意:
- 使用
nvm时,你不需要sudo就可以用npm -g全局安装模块,所以不要用sudo npm install -g grunt,而是用npm install -g grunt - 如果你有
~/.npmrc文件,请确保其中不包含任何prefix设置(这与nvm不兼容) - 你可以(但不应该?)保留之前的"系统"node 安装,但
nvm只对你的用户账户可用(安装 nvm 时使用的那个)。这可能导致版本不匹配,因为其他用户将使用/usr/local/lib/node_modules/*,而你的用户账户使用~/.nvm/versions/node/vX.X.X/lib/node_modules/*
不支持通过 Homebrew 安装。如果你在使用 homebrew 安装的 nvm 时遇到问题,请先 brew uninstall 它,然后按照下面的说明安装,再提交 issue。
注意: 如果你使用 zsh,你可以轻松地将 nvm 安装为 zsh 插件。安装 zsh-nvm 并运行 nvm upgrade 来升级(你可以设置 NVM_AUTO_USE=true 来自动检测和使用 .nvmrc 文件)。
注意: v1.7 之前的 Git 版本可能会遇到通过 https 协议从 GitHub 克隆 nvm 源码的问题,而且 v1.6 之前的 git 行为也不同,v1.17.10 之前的 git 无法克隆标签,所以最低要求的 git 版本是 v1.7.10。如果你对我们提到的问题感兴趣,请参考 GitHub 的 HTTPS 克隆错误文章。
Git 安装
如果你已经安装了 git(需要 git v1.7.10+):
- 在你的用户主目录下克隆此仓库
- 在任意位置执行
cd ~/,然后执行git clone https://github.com/nvm-sh/nvm.git .nvm
- 在任意位置执行
cd ~/.nvm并使用git checkout v0.40.8切换到最新版本- 通过 source 加载
nvm:. ./nvm.sh
现在将以下行添加到你的 ~/.bashrc、~/.profile 或 ~/.zshrc 文件中,以便在登录时自动加载:
(你可能需要添加到以上多个文件中)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 这会加载 nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # 这会加载 nvm bash 补全
手动安装
要进行完全手动安装,请执行以下命令,首先将 nvm 仓库克隆到 $HOME/.nvm,然后加载 nvm:
export NVM_DIR="$HOME/.nvm" && (
git clone https://github.com/nvm-sh/nvm.git "$NVM_DIR"
cd "$NVM_DIR"
git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"
现在将以下行添加到你的 ~/.bashrc、~/.profile 或 ~/.zshrc 文件中,以便在登录时自动加载:
(你可能需要添加到以上多个文件中)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 这会加载 nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # 这会加载 nvm bash 补全
手动升级
使用 git 手动升级(需要 git v1.7.10+):
- 切换到
$NVM_DIR - 拉取最新更改
- 切换到最新版本
- 激活新版本
(
cd "$NVM_DIR"
git fetch --tags origin
git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"
用法
要下载、编译并安装最新版本的 node,请执行:
nvm install node # "node" 是最新版本的别名
要安装特定版本的 node:
nvm install 14.7.0 # 或 16.3.0、12.22.1 等
设置别名:
nvm alias my_alias v14.4.0
请确保你的别名不包含任何空格或斜杠。
第一个安装的版本会成为默认版本。新的 Shell 将从默认版本的 node 开始(例如 nvm alias default)。
你可以使用 ls-remote 列出可用版本:
nvm ls-remote
然后在任何新的 Shell 中直接使用已安装的版本:
nvm use node
或者你可以直接运行它:
nvm run node --version
或者,你可以在子 Shell 中使用指定版本的 node 运行任意命令:
nvm exec 4.2 node --version
你还可以获取安装路径下可执行文件的路径:
nvm which 12.22
你可以使用以下特殊的默认别名代替版本号(如 "14.7"、"16.3" 或 "12.22.1"),用于 nvm install、nvm use、nvm run、nvm exec、nvm which 等命令:
node:这会安装最新版本的nodeiojs:这会安装最新版本的io.jsstable:此别名已弃用,仅真正适用于nodev0.12及更早版本。目前,它是node的别名。unstable:此别名指向nodev0.11- 最后一个"不稳定"的 node 版本,因为 1.0 之后所有 node 版本都是稳定的。(在 SemVer 中,版本号传达的是破坏性变更,而不是稳定性)。current:当前 Shell 中活动的版本(即node通过$PATH解析到的版本)。它不受.nvmrc影响。当你想明确引用活动版本时很有用——例如nvm which current总是输出活动node的路径,无论是否存在.nvmrc文件。
长期支持版本
Node 有一个长期支持(LTS)计划。你可以在别名和 .nvmrc 文件中使用 lts/* 表示最新 LTS 版本,使用 lts/argon 表示 "argon" 系列的 LTS 版本。此外,以下命令支持 LTS 参数:
nvm install --lts/nvm install --lts=argon/nvm install 'lts/*'/nvm install lts/argonnvm uninstall --lts/nvm uninstall --lts=argon/nvm uninstall 'lts/*'/nvm uninstall lts/argonnvm use --lts/nvm use --lts=argon/nvm use 'lts/*'/nvm use lts/argonnvm exec --lts/nvm exec --lts=argon/nvm exec 'lts/*'/nvm exec lts/argonnvm run --lts/nvm run --lts=argon/nvm run 'lts/*'/nvm run lts/argonnvm ls-remote --lts/nvm ls-remote --lts=argonnvm ls-remote 'lts/*'/nvm ls-remote lts/argonnvm version-remote --lts/nvm version-remote --lts=argon/nvm version-remote 'lts/*'/nvm version-remote lts/argon
每当你的本地 nvm 副本连接到 https://nodejs.org 时,它都会为所有可用的 LTS 系列重新创建相应的本地别名。这些别名(存储在 $NVM_DIR/alias/lts 下)由 nvm 管理,你不应该修改、删除或创建这些文件——你的更改会被撤销,而且随意修改这些文件可能会导致 bug,我们可能不会提供支持。
要获取最新的 LTS 版本的 node 并迁移你已安装的包,请使用:
nvm install --reinstall-packages-from=current 'lts/*'
安装时迁移全局包
如果你想安装新版本的 Node.js 并从之前的版本迁移 npm 包:
nvm install --reinstall-packages-from=node node
这会首先使用 "nvm version node" 来确定你要迁移包的当前版本。然后它从远程服务器解析要安装的新版本并安装它。最后,它运行 "nvm reinstall-packages" 来将之前 Node 版本的 npm 包重新安装到新版本中。
你还可以像这样安装并迁移特定 Node 版本的 npm 包:
nvm install --reinstall-packages-from=5 6
nvm install --reinstall-packages-from=iojs v4.2
请注意,重新安装包明确不会更新 npm 版本——这是为了确保 npm 不会意外升级到与新 node 版本不兼容的损坏版本。
要同时更新 npm,请添加 --latest-npm 参数,像这样:
nvm install --reinstall-packages-from=default --latest-npm 'lts/*'
或者,你可以随时运行以下命令来获取当前 node 版本支持的最新 npm 版本:
nvm install-latest-npm
如果你已经遇到了 "npm does not support Node.js" 之类的错误,你需要 (1) 回退到之前的 node 版本(nvm ls 和 nvm use <你从 ls 中看到的最新可用版本>),(2) 删除新创建的 node 版本(nvm uninstall <你从 ls 中看到的损坏版本>),然后 (3) 使用 --latest-npm 参数重新运行 nvm install。
在已安装版本间迁移全局包
--reinstall-packages-from 是与 nvm install 绑定的。要在你已经安装的版本之间迁移全局 npm 包,而不需要(重新)安装任何东西,请 nvm use 目标版本,然后运行 nvm reinstall-packages 作为独立命令,指向你要从哪个版本复制:
nvm use 22.22.2
nvm reinstall-packages 22.20.0
这会将 22.20.0 中的所有全局包重新安装到当前活动版本(22.22.2)中。与 --reinstall-packages-from 一样,npm 版本本身不会改变。
离线安装
你可以离线安装 node,方法是将安装包下载到 $NVM_DIR 的相应目录中。
例如,如果你在 macOS 上运行,并且想要安装 v18.0.0,你可以下载 https://nodejs.org/dist/v18.0.0/node-v18.0.0-darwin-x64.tar.gz 并将其放入 $NVM_DIR(即 ~/.nvm)。
然后运行 nvm install 18.0.0,nvm 会使用你下载的 tar 包进行安装,而不会尝试下载它。
安装时从文件设置默认全局包
你可以在 $NVM_DIR/default-packages 中放置一个包列表,每行一个包,这样在安装新版本时就会自动安装这些包。这些包会通过 npm install 全局安装。
$ cat ~/.nvm/default-packages
grunt-cli
bower
pm2
这在 CI 环境中特别有用。
io.js
如果你想安装 io.js 而不是 Node.js,你可以使用 nvm install iojs 来安装最新版本。
你也可以指定特定版本:nvm install iojs-v1.0.1。
所有其他命令都以相同的方式工作,只是使用 iojs 代替 node。
系统版本的 Node
如果你想使用系统安装的 node,你可以运行 nvm use system。
此外,当运行 nvm run、nvm exec 或 nvm which 时,你可以使用 system 代替版本号。
列出版本
要列出已安装的版本:
nvm ls
要列出远程可用的版本:
nvm ls-remote
设置自定义颜色
nvm 有几个文本颜色配置。你可以通过设置以下环境变量来自定义它们:
NVM_COLORS_CYAN用于nvm ls和nvm ls-remote中的活动版本NVM_COLORS_GREEN用于nvm ls和nvm ls-remote中的默认版本
例如,要使用青色表示活动版本,黄色表示默认版本:
export NVM_COLORS_CYAN=36
export NVM_COLORS_GREEN=33
颜色代码与 ANSI 转义序列一致。
持久化自定义颜色
要持久化这些设置,请将 export 命令添加到你的 Shell 配置文件(~/.bashrc、~/.zshrc 等)中。
禁用彩色输出
要完全禁用 nvm 输出中的颜色,请设置:
export NVM_COLORS_NONE=1
恢复 PATH
如果你在安装和使用 nvm 后需要临时恢复到系统 node 的 PATH,你可以运行:
nvm deactivate
这会从当前 Shell 的 PATH 中移除 nvm 相关的路径前缀。
设置默认 node 版本
你可以设置一个默认版本,新的 Shell 将自动使用它:
nvm alias default 18.0.0
这也适用于任何已安装的版本或别名。
如果你想让每个新 Shell 都使用最新安装的版本,你可以:
nvm alias default node
使用 node 二进制镜像
你可以通过设置环境变量 NVM_NODEJS_ORG_MIRROR 来使用 node 二进制的镜像:
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node
如果你想在单个命令中使用镜像:
NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node nvm install 18
向镜像传递 Authorization 头
如果你需要向镜像传递 Authorization 头(例如私有镜像仓库),你可以设置:
export NVM_NODEJS_ORG_MIRROR="https://your-mirror.com/dist"
export NVM_NODEJS_ORG_AUTH="Bearer your-token"
没有官方二进制的平台
如果你的平台没有官方预编译的二进制包,nvm 会自动从源代码编译。你也可以强制从源代码编译:
nvm install -s 18.0.0
编译可能需要一些时间。
.nvmrc
.nvmrc 文件包含项目要使用的 node 版本。它应该包含一个版本号(如 18.0.0)或一个标签(如 lts/argon)。
当你在包含 .nvmrc 文件的目录中时,你可以运行 nvm use(不带参数)来自动切换到 .nvmrc 文件中指定的版本。如果该版本尚未安装,nvm 会提示你先安装它。
.nvmrc 文件还支持 node、iojs、stable、unstable 等别名,以及 lts/* 和 lts/argon 等 LTS 别名。
深度 Shell 集成
在包含 .nvmrc 文件的目录中自动调用 nvm use
你可以将 nvm 集成到你的 Shell 中,以便在进入包含 .nvmrc 文件的目录时自动切换 node 版本。
bash
将以下代码添加到你的 ~/.bashrc 文件中:
# 放在 nvm 初始化之后!
load-nvmrc() {
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" != "$(nvm version)" ]; then
nvm use
fi
elif [ -n "$(PWD=$OLDPWD nvm_find_nvmrc)" ] && [ "$(nvm version)" != "$(nvm version default)" ]; then
echo "Reverting to nvm default version"
nvm use default
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc
保存文件后,运行 source ~/.bashrc 来重新加载配置。
zsh
将以下代码添加到你的 ~/.zshrc 文件中:
# 放在 nvm 初始化之后!
autoload -U add-zsh-hook
load-nvmrc() {
local nvmrc_path
nvmrc_path="$(nvm_find_nvmrc)"
if [ -n "$nvmrc_path" ]; then
local nvmrc_node_version
nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
if [ "$nvmrc_node_version" = "N/A" ]; then
nvm install
elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then
nvm use
fi
elif [ -n "$(PWD=$OLDPWD nvm_find_nvmrc)" ] && [ "$(nvm version)" != "$(nvm version default)" ]; then
echo "Reverting to nvm default version"
nvm use default
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc
保存文件后,运行 source ~/.zshrc 来重新加载配置。
fish
这需要你安装了 bass。
# ~/.config/fish/functions/nvm.fish
function nvm
bass source ~/.nvm/nvm.sh --no-use ';' nvm $argv
end
# ~/.config/fish/functions/nvm_find_nvmrc.fish
function nvm_find_nvmrc
bass source ~/.nvm/nvm.sh --no-use ';' nvm_find_nvmrc
end
# ~/.config/fish/functions/load_nvm.fish
function load_nvm --on-variable="PWD"
set -l default_node_version (nvm version default)
set -l node_version (nvm version)
set -l nvmrc_path (nvm_find_nvmrc)
if test -n "$nvmrc_path"
set -l nvmrc_node_version (nvm version (cat $nvmrc_path))
if test "$nvmrc_node_version" = "N/A"
nvm install (cat $nvmrc_path)
else if test "$nvmrc_node_version" != "$node_version"
nvm use $nvmrc_node_version
end
else if test "$node_version" != "$default_node_version"
echo "Reverting to default Node version"
nvm use default
end
end
# ~/.config/fish/config.fish
# 你必须在初始化时调用它,否则监听目录切换将不起作用
load_nvm > /dev/stderr
运行测试
测试使用 Urchin 编写。像这样安装 Urchin(和其他依赖):
npm install
测试分为慢速测试和快速测试。慢速测试会执行诸如安装 node 并检查是否使用了正确版本之类的操作。快速测试通过模拟这些操作来测试别名和卸载等功能。在 nvm git 仓库的根目录下,像这样运行快速测试:
npm run test/fast
像这样运行慢速测试:
npm run test/slow
像这样运行所有测试:
npm test
注意:测试运行时避免运行 nvm。
环境变量
nvm 暴露以下环境变量:
NVM_DIR- nvm 的安装目录。NVM_BIN- 当前活动版本的 node、npm 和全局包的安装位置。NVM_INC- node 的头文件目录(用于构建 node 的 C/C++ 插件时很有用)。NVM_CD_FLAGS- 用于保持与 zsh 的兼容性。NVM_RC_VERSION- 如果使用了 .nvmrc 文件,则为其中的版本。
此外,nvm 在切换版本时会修改 PATH,以及 MANPATH(如果存在 manpath 命令的话)和 NODE_PATH(如果存在的话)。
可以设置以下环境变量来配置 nvm install:
NVM_NO_SOURCE_FALLBACK- 当设为1时,二进制下载失败将中止,而不是静默回退到(慢得多的)从源码编译;等同于-b参数,与-s互斥。NVM_INSTALL_LOCK_TIMEOUT- 等待同一版本的并发安装完成的秒数,超时后放弃(默认600)。超时后,nvm 会打印锁文件路径,以便删除被终止的安装留下的锁。NVM_INSTALL_LOCK_STALE- 安装锁被认为已过期并自动窃取的分钟数;0(默认)表示永不窃取。
nvm install <version> 会对每个版本获取一个 advisory 锁(位于 $NVM_DIR/.cache/locks 下的目录),因此两个同时安装同一版本的 Shell 不会损坏其版本目录;安装不同版本永远不会互相阻塞。
Bash 补全
要激活补全,你需要 source bash_completion:
[[ -r $NVM_DIR/bash_completion ]] && \. $NVM_DIR/bash_completion
将以上 source 行放在你的配置文件(.bashrc、.bash_profile)中 nvm 的 source 行的正下方。
用法
nvm:
$ nvmTab
alias deactivate install list-remote reinstall-packages uninstall version
cache exec install-latest-npm ls run unload version-remote
current help list ls-remote unalias use which
nvm alias:
$ nvm aliasTab
default iojs lts/* lts/argon lts/boron lts/carbon lts/dubnium lts/erbium node stable unstable
$ nvm alias my_aliasTab
v10.22.0 v12.18.3 v14.8.0
nvm use:
$ nvm useTab
my_alias default v10.22.0 v12.18.3 v14.8.0
nvm uninstall:
$ nvm uninstallTab
my_alias default v10.22.0 v12.18.3 v14.8.0
兼容性问题
如果你设置了一些非默认配置,nvm 可能会遇到一些问题。(参见 #606)
以下是已知会导致问题的配置:
在 ~/.npmrc 中:
prefix='some/path'
环境变量:
$NPM_CONFIG_PREFIX
$PREFIX
Shell 设置:
set -e
在 Alpine Linux 上安装 nvm
为了提供最佳性能(和其他优化),当你运行 nvm install X 时,nvm 会下载并安装预编译的 Node(和 npm)二进制包。Node 项目为主流/传统 Linux 发行版(如 Debian、Ubuntu、CentOS、RedHat 等)编译、测试并提供这些预编译二进制包。
Alpine Linux 与主流/传统 Linux 发行版不同,它基于 BusyBox,一个非常紧凑(约 5MB)的 Linux 发行版。BusyBox(以及 Alpine Linux)使用与大多数主流/传统 Linux 发行版不同的 C/C++ 工具链——musl。这使得为这些主流/传统发行版构建的二进制程序与 Alpine Linux 不兼容,因此在 x64 和 arm64 上,nvm 会请求 musl 构建版本。nodejs.org 仅为部分较新的 x64 版本发布这些构建版本,因此对于其他版本,下载会返回 404,nvm install X 会回退到从源码编译,除非你指向一个有这些构建版本的镜像(参见没有官方二进制的平台)。
nvm install 有一个 -s 参数,用于请求 nvm 下载 Node 源码并在本地编译。
如果你确实想在 Alpine Linux 上安装 nvm,你应该能够根据你使用的版本,在 Alpine Linux Shell 中运行以下命令来实现:
Alpine Linux 3.13+
apk add -U curl bash ca-certificates openssl ncurses coreutils python3 make gcc g++ libgcc linux-headers grep util-linux binutils findutils
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
Alpine Linux 3.5 - 3.12
apk add -U curl bash ca-certificates openssl ncurses coreutils python2 make gcc g++ libgcc linux-headers grep util-linux binutils findutils
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
注意:Alpine 3.5 最多只能安装 NodeJS v6.9.5,Alpine 3.6 最多只能安装 v6.10.3,Alpine 3.7 最多安装 v8.9.3,Alpine 3.8 最多安装 v8.14.0,Alpine 3.9 最多安装 v10.19.0,Alpine 3.10 最多安装 v10.24.1,Alpine 3.11 最多安装 v12.22.6,Alpine 3.12 最多安装 v12.22.12,Alpine 3.13 和 3.14 最多安装 v14.20.0,Alpine 3.15 和 3.16 最多安装 v16.16.0(这些都是主分支上的版本)。Alpine 3.5 - 3.12 需要 python2 包来构建 NodeJS,因为它们是较旧的版本。Alpine 3.13+ 需要 python3 来成功构建较新的 NodeJS 版本,但如果你需要构建 Alpine 3.5 - 3.15 支持的 node 版本,你也可以在 Alpine 3.13+ 上使用 python2,你只需要在安装脚本中指定要安装的 NodeJS 版本即可。
Node 项目现在为部分较新的版本(v24.20.0+ 和 v26.8.0+;没有 v25 版本提供)发布了官方的 linux-x64-musl 二进制包。没有官方的 arm64 musl 二进制包。
作为一个潜在的替代方案,@mhart(一位 Node 贡献者)提供了一些预装了 Node 和可选 npm 的 Alpine Linux Docker 镜像。
卸载 / 移除
手动卸载
要手动移除 nvm,执行以下操作:
首先,使用 nvm unload 从你的终端会话中移除 nvm 命令,并删除安装目录:
$ nvm_dir="${NVM_DIR:-~/.nvm}"
$ nvm unload
$ rm -rf "$nvm_dir"
编辑 ~/.bashrc(或其他 Shell 资源配置文件)并删除以下行:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 这会加载 nvm
[[ -r $NVM_DIR/bash_completion ]] && \. $NVM_DIR/bash_completion
开发环境 Docker
为了让开发和测试工作更轻松,我们提供了一个用于开发的 Dockerfile。它基于 Ubuntu 基础镜像,预装了 nvm 开发所需的基本和实用工具。要构建开发环境的 Docker 镜像,请在 nvm 仓库根目录下执行 Docker 构建:
$ docker build -t nvm-dev .
这会将你当前的 nvm 工作副本和我们预定义的开发环境打包成一个名为 nvm-dev 的 Docker 镜像。构建完成后,你应该能在镜像列表中看到它:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nvm-dev latest 9ca4c57a97d8 7 days ago 650 MB
要基于此镜像启动并进入容器:
$ docker run -h nvm-dev -it nvm-dev
nvm@nvm-dev:~/.nvm$
构建镜像需要几分钟时间,镜像大小约为 650MB,因此不适合用于生产环境。
有关 Docker 的更多信息和文档,请参考其官方网站和文档:
常见问题
-
如果你尝试安装 node 版本但安装失败,请务必运行
nvm cache clear来删除缓存的 node 下载文件,否则你可能会遇到如下错误:curl: (33) HTTP server doesn't seem to support byte ranges. Cannot resume.
-
我的
sudo node在哪里?参见 #43 -
在 node v0.8.6 版本发布后,nvm 尝试从二进制包安装。但在某些系统上,由于共享库不兼容,官方二进制包无法正常工作。在这种情况下,使用
-s参数强制从源码安装:
nvm install -s 0.8.6
- 如果设置
default别名后在新 Shell 中没有生效(即nvm current显示system),请确保系统 node 的PATH在你的 Shell 配置文件中的nvm.shsource 行之前设置(参见 #658)
macOS 故障排除
nvm node 版本在 vim Shell 中找不到
如果你将 node 版本设置为系统 node 以外的版本 nvm use 6.2.1,然后打开 vim 并运行 :!node -v,你应该看到 v6.2.1。如果你看到的是系统版本 v0.12.7,你需要运行:
sudo chmod ugo-x /usr/libexec/path_helper
更多关于此问题的信息请参见 dotphiles/dotzsh。
nvm 与 npm 配置的 "prefix" 选项不兼容
有关此问题的一些解决方案请参见这里
还有一个导致此问题的边缘情况,那就是 $HOME 路径与用户主目录实际名称之间的大小写不匹配。
你必须确保 $HOME 中的用户目录名称与你运行 ls /Users/ 看到的用户目录名称大小写一致(参见此 issue)。
要更改用户目录和/或账户名称,请按照这里的说明操作
Homebrew 导致 zsh 目录不安全
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]? y
Homebrew 会导致诸如 /usr/local/share/zsh/site-functions 和 /usr/local/share/zsh 之类的目录不安全。这不是 nvm 的问题——这是 homebrew 的问题。有关此问题的一些解决方案,请参考这里。
搭载 Apple Silicon 芯片的 Mac
Apple Silicon 芯片架构的实验性支持在 node.js v15.3 中加入,完整支持在 v16.0 中加入。 因此,如果你像往常一样尝试安装较旧版本的 node,你可能会在安装 node 时遇到编译错误,或者在运行代码时遇到内存不足错误。
所以,如果你想在 Apple Silicon Mac 上运行 v16.0 之前的版本,最好编译面向 x86_64 Intel 架构的 node,这样 Rosetta 2 就可以将 x86_64 处理器指令翻译为基于 ARM 的 Apple Silicon 指令。
你需要做以下操作:
-
安装 Rosetta(如果你还没有安装)
$ softwareupdate --install-rosetta你可能会想:"我的 Apple Silicon Mac 怎么知道要为 Intel 芯片编译的 node 版本使用 Rosetta?"。 如果一个可执行文件只包含 Intel 指令,macOS 会自动使用 Rosetta 来翻译这些指令。
-
打开一个使用 Rosetta 运行的 Shell
$ arch -x86_64 zsh注意:你也可以在 Finder 中找到 Terminal 或 iTerm 应用,右键点击,选择"显示简介",然后勾选"使用 Rosetta 打开"复选框来实现同样的效果。
注意:此终端会话现在运行在
zsh中。 如果zsh不是你通常使用的 Shell,nvm可能不会像你平常 Shell 那样通过 dotfiles 自动 source。 如果是这种情况,请务必 sourcenvm。$ source "${NVM_DIR}/nvm.sh" -
安装你感兴趣的任何旧版本的 node。我们以 12.22.1 为例。 这会下载 node 源代码并编译,需要几分钟时间。
$ nvm install v12.22.1 --shared-zlib注意:你可能会好奇为什么要加上
--shared-zlib。 Apple 系统的clang编译器近期版本中存在一个 bug。 如果你的系统安装了这些有问题的版本,即使你不加上--shared-zlib参数,上述步骤也可能成功。 但是,之后当你尝试使用旧版本的 node.js 运行npm install安装某些东西时,你会看到incorrect data check错误。 如果你想避免处理这个问题的麻烦,请加上这个参数。 更多详情请参见此 issue和此评论 -
退出并回到你的原生 Shell。
$ exit $ arch arm64注意:如果你在第二步中选择了"使用 Rosetta 打开"复选框而不是运行 CLI 命令,你会在这里看到
i386。 除非你有其他理由要保持勾选,否则现在可以取消勾选。 -
检查架构是否正确。
x64是x86_64的缩写,这是你想看到的。$ node -p process.arch x64
现在你应该可以像往常一样使用 node 了。
WSL 故障排除
如果你在 WSL-2 上遇到此错误:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:09 --:--:-- 0curl: (6) Could not resolve host: raw.githubusercontent.com
这可能是由于你的杀毒软件、VPN 或其他原因导致的。
即你可以 ping 8.8.8.8 但不能 ping google.com
这可以通过在你的根目录下运行以下命令来解决:
sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
sudo chattr +i /etc/resolv.conf
这会删除你运行 WSL 时自动生成的 resolv.conf 文件,创建一个新文件并写入 nameserver 8.8.8.8,然后创建一个 wsl.conf 文件并添加 [network] 和 generateResolveConf = false 以防止自动生成该文件。
你可以通过运行以下命令来检查文件内容:
cat /etc/resolv.conf
维护者
目前唯一的维护者是 @ljharb——非常欢迎更多维护者加入,我们希望随着时间的推移能有更多人加入团队。治理方式将随着项目的发展而重新评估。
项目支持
仅支持最新版本(目前为 v0.40.8)。
企业支持
如果你无法更新到最新版本的 nvm,我们的合作伙伴为所有不受支持的版本提供商业安全修复:
许可证
参见 LICENSE.md。
版权声明
版权所有 OpenJS Foundation 及 nvm 贡献者。保留所有权利。OpenJS Foundation 拥有并使用商标。有关 OpenJS Foundation 的商标列表,请参见我们的商标政策和商标列表。未在OpenJS Foundation 商标列表中标明的商标和徽标是其各自所有者的商标™或注册商标®。使用它们并不意味着与它们有关联或获得它们的认可。
OpenJS Foundation | 使用条款 | 隐私政策 | 章程 | 行为准则 | 商标政策 | 商标列表 | Cookie 政策