跳转到内容

NVM Node.js 版本管理完全指南 | 多版本切换与项目配置教程

NVM Node Version Manager

在 Node.js 开发中,不同项目可能需要不同版本的 Node.js。NVM(Node Version Manager) 是最流行的 Node.js 版本管理工具,让你能够在同一台机器上轻松安装、切换和管理多个 Node.js 版本。本文将详细介绍 NVM 的完整使用方法和最佳实践。

为什么需要 Node.js 版本管理?

常见痛点

问题影响解决方案
📦 版本冲突老项目不兼容新版 Node为每个项目指定版本
🔧 全局污染不同版本的 npm 包冲突隔离的全局包目录
测试需求需要测试多版本兼容性快速切换版本
🛠️ 权限问题系统级安装需要 sudo用户级安装无需权限
🔄 升级困难手动升级容易出错一键安装/卸载

NVM vs N 对比

nvm 与 n 的区别

node 版本管理工具还有一个是 TJ大神的 n 命令,n 命令是作为一个 node 的模块而存在,而 nvm 是一个独立于 node/npm 的外部 shell 脚本,因此 n 命令相比 nvm 更加局限。

由于 npm 安装的模块路径均为 /usr/local/lib/node_modules,当使用 n 切换不同的 node 版本时,实际上会共用全局的 node/npm 目录。 因此不能很好的满足『按不同 node 版本使用不同全局 node 模块』的需求。

详细对比表

特性NVMN
类型Shell 脚本Node 模块
安装方式独立安装通过 npm 安装
平台支持macOS/Linux/WindowsmacOS/Linux
版本隔离✅ 完全隔离❌ 共享全局目录
.nvmrc 支持✅ 原生支持❌ 不支持
默认版本设置✅ 支持✅ 支持
包迁移✅ 内置支持❌ 需手动处理
卸载清理✅ 干净彻底⚠️ 可能残留
学习曲线中等简单
推荐场景专业开发简单需求

结论:

  • 🟢 推荐使用 NVM:功能强大,生态完善
  • 🟡 N 适合简单场景:仅需快速切换版本

卸载全局安装的 node/npm

在官网下载的 node 安装包,运行后会自动安装在全局目录,使用过程中经常会遇到一些权限问题,所以推荐按照以下方法卸载全局安装的 node/npm。

首先,打开你 Finder,按 shift+command+G,打开前往文件夹的窗口,分别输入下列目录进去之后删除 node 和 node_modules 相关的文件和文件夹:

  • 打开 /usr/local/lib,删除 nodenode_modules 相关的文件和文件夹
  • 打开 /usr/local/include,删除 nodenode_modules 相关的文件和文件夹

如果你是使用的 brew install node 安装的 NodeJS,那么你还需要在终端中执行 brew uninstall node 命令来卸载

检查你的个人主文件夹下面的所有的 local、lib 以及 include 文件夹,并且删除所有与 node 和 node_modules 相关的文件以及文件夹

打开 /usr/local/bin 并删除 node 可执行文件

你可能还需要在你的终端中输入一些额外的指令:

bash
sudo rm /usr/local/bin/npm
sudo rm /usr/local/share/man/man1/node.1
sudo rm /usr/local/lib/dtrace/node.d
sudo rm -rf ~/.npm
sudo rm -rf ~/.node-gyp
sudo rm /opt/local/bin/node
sudo rm /opt/local/include/node
sudo rm -rf /opt/local/lib/node_modules

完整卸载流程详解

macOS 用户

步骤 1:备份重要数据

bash
# 备份全局 npm 包列表
npm list -g --depth=0 > ~/npm-global-packages.txt

# 备份自定义配置
cp ~/.npmrc ~/npmrc.backup 2>/dev/null || true

步骤 2:卸载 Homebrew 安装的 Node

bash
# 如果使用 Homebrew
brew uninstall node
brew cleanup

# 验证卸载
which node  # 应该返回空或系统路径

步骤 3:手动清理残留文件

bash
# 删除 Node.js 相关文件
sudo rm -rf /usr/local/lib/node_modules
sudo rm -rf /usr/local/include/node
sudo rm /usr/local/bin/node
sudo rm /usr/local/bin/npm
sudo rm /usr/local/bin/npx

# 删除配置文件
rm -rf ~/.npm
rm -rf ~/.node-gyp
rm ~/.npmrc

# 删除手册页
sudo rm -rf /usr/local/share/man/man1/node*
sudo rm -rf /usr/local/share/man/man1/npm*
sudo rm -rf /usr/local/share/man/man1/npx*
sudo rm -rf /usr/local/share/man/man7/npm*

# 删除 dtrace 文件
sudo rm -rf /usr/local/lib/dtrace/node.d

步骤 4:验证清理结果

bash
# 检查是否还有残留
which node
which npm
node --version 2>/dev/null || echo "Node.js 已卸载"

# 查找可能的残留文件
find /usr/local -name "*node*" 2>/dev/null
find ~ -name ".npm" -o -name ".node-gyp" 2>/dev/null

Linux 用户

bash
# Ubuntu/Debian
sudo apt-get remove --purge nodejs npm
sudo apt-get autoremove
sudo rm -rf /usr/local/lib/node_modules
sudo rm -rf /usr/local/include/node
rm -rf ~/.npm
rm -rf ~/.node-gyp

# CentOS/RHEL
sudo yum remove nodejs npm
sudo rm -rf /usr/local/lib/node_modules
rm -rf ~/.npm

Windows 用户

powershell
# 通过控制面板卸载
# 或使用 PowerShell
winget uninstall OpenJS.NodeJS

# 清理残留
Remove-Item -Recurse -Force "$env:APPDATA\npm" -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force "$env:APPDATA\npm-cache" -ErrorAction SilentlyContinue

安装 nvm

bash
brew install nvm

多平台安装方法

macOS(Homebrew)

bash
# 安装 NVM
brew install nvm

# 创建 NVM 目录
mkdir ~/.nvm

# 配置环境变量
echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc
echo '[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"' >> ~/.zshrc
echo '[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"' >> ~/.zshrc

# 重新加载配置
source ~/.zshrc

# 验证安装
nvm --version

Intel Mac 路径:

bash
# Intel Mac 使用 /usr/local 而非 /opt/homebrew
echo '[ -s "/usr/local/opt/nvm/nvm.sh" ] && \. "/usr/local/opt/nvm/nvm.sh"' >> ~/.zshrc

macOS/Linux(官方脚本)

bash
# 下载并执行安装脚本
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# 或使用 wget
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# 重新加载配置
source ~/.bashrc  # 或 source ~/.zshrc

# 验证安装
nvm --version

Windows(nvm-windows)

powershell
# 使用 Scoop
scoop install nvm

# 或使用安装包
# 下载:https://github.com/coreybutler/nvm-windows/releases

# 验证安装
nvm version

注意: Windows 用户使用 nvm-windows,命令略有不同:

  • nvm installnvm install
  • nvm usenvm use
  • nvm lsnvm list

配置 NVM

创建 .nvmrc 文件(可选):

bash
# 设置默认 Node 版本
echo "lts/*" > ~/.nvmrc

# 或指定具体版本
echo "18.19.0" > ~/.nvmrc

配置 NVM 镜像加速(国内用户):

bash
# 编辑配置文件
nano ~/.zshrc  # 或 ~/.bashrc

# 添加以下内容
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node

# 重新加载
source ~/.zshrc

安装多版本 node/npm

安装4.2.2版本:

bash
nvm install 4.2.2

安装最新的 4.2 系列的最新版本:

bash
nvm install 4.2

列出远程服务器上所有的可用版本:

bash
nvm ls-remote

安装命令详解

基本安装

bash
# 安装特定版本
nvm install 18.19.0

# 安装最新 LTS 版本(推荐)
nvm install --lts

# 安装最新稳定版
nvm install node

# 安装特定大版本
nvm install 18      # 安装 18.x 最新版
nvm install 20      # 安装 20.x 最新版

高级安装选项

bash
# 从源码编译安装
nvm install 18.19.0 --reinstall-packages-from=current

# 安装时跳过二进制下载(强制编译)
nvm install 18.19.0 --build-from-source

# 安装时迁移全局包
nvm install 18.19.0 --reinstall-packages-from=16.14.0

# 安装特定架构版本
nvm install 18.19.0 --arch=x64

查看可用版本

bash
# 列出所有远程可用版本
nvm ls-remote

# 列出 LTS 版本
nvm ls-remote --lts

# 筛选特定版本
nvm ls-remote | grep v18
nvm ls-remote | grep lts

# 查看最新版本
nvm ls-remote | tail -10

输出示例:

       v18.19.0   (Latest LTS: Hydrogen)
       v20.11.0   (Latest LTS: Iron)
       v21.6.0
->     v22.0.0

常用版本说明

版本代号版本号状态支持周期
Argonv4.xEOL已结束
Boronv6.xEOL已结束
Carbonv8.xEOL已结束
Dubniumv10.xEOL已结束
Erbiumv12.xEOL已结束
Fermiumv14.xEOL已结束
Galliumv16.xEOL已结束
Hydrogenv18.xMaintenance至 2025-04
Ironv20.xActive LTS至 2026-04
Jodv22.xCurrent至 2024-10

推荐选择:

  • 🟢 生产环境:最新 LTS 版本(当前 v20.x)
  • 🟡 新项目:Current 版本(当前 v22.x)
  • 🔴 老项目:根据项目要求选择

在不同版本间切换

切换到 4.2.2:

bash
nvm use 4.2.2

切换到 4.2.x:

bash
nvm use 4.2

切换到最新版:

bash
nvm use node

切换命令详解

基本切换

bash
# 切换到特定版本
nvm use 18.19.0

# 切换到最新 18.x
nvm use 18

# 切换到最新 LTS
nvm use --lts

# 切换到最新稳定版
nvm use node

# 切换到系统 Node(如果存在)
nvm use system

自动切换(.nvmrc)

bash
# 在项目根目录创建 .nvmrc
echo "18.19.0" > .nvmrc

# 进入目录后自动使用指定版本
cd my-project
nvm use  # 自动读取 .nvmrc

# 或使用自动切换工具
# 安装 auto-nvm
npm install -g auto-nvm

配置 Shell 自动切换:

bash
# 添加到 ~/.zshrc 或 ~/.bashrc
autoload -U add-zsh-hook
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
  fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc

设置默认版本

bash
# 设置默认 Node 版本
nvm alias default 18.19.0

# 设置别名为 LTS
nvm alias default lts/*

# 查看别名
nvm alias

# 删除别名
nvm unalias default

版本切换最佳实践

场景 1:多项目开发

bash
# 项目 A 使用 Node 18
cd project-a
echo "18.19.0" > .nvmrc
nvm use

# 项目 B 使用 Node 20
cd ../project-b
echo "20.11.0" > .nvmrc
nvm use

场景 2:测试兼容性

bash
# 测试代码在不同版本下的表现
for version in 16 18 20; do
  echo "Testing with Node $version"
  nvm use $version
  npm test
done

列出已安装实例

bash
nvm ls

列表命令详解

bash
# 列出本地已安装版本
nvm ls

# 列出远程可用版本
nvm ls-remote

# 列出 LTS 版本
nvm ls-remote --lts

# 查看当前使用版本
nvm current

# 查看版本详细信息
nvm version
nvm version 18.19.0

输出示例:

->     v18.19.0
       v20.11.0
       v22.0.0
default -> 18.19.0
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v22.0.0) (default)
stable -> 22.0 (-> v22.0.0) (default)
lts/* -> lts/iron (-> v20.11.0)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.21.3 (-> N/A)
lts/gallium -> v16.20.2 (-> N/A)
lts/hydrogen -> v18.19.0
lts/iron -> v20.11.0

符号说明:

  • -> 当前正在使用的版本
  • default 默认版本
  • lts/* 最新 LTS 版本
  • N/A 未安装该版本

在项目中使用不同版本的 Node

我们可以通过创建项目目录中的 .nvmrc 文件来指定要使用的 Node 版本。之后在项目目录中执行 nvm use 即可。

.nvmrc 文件内容只需要遵守上文提到的语义化版本规则即可

.nvmrc 文件详解

支持的格式

bash
# 精确版本
echo "18.19.0" > .nvmrc

# 大版本
echo "18" > .nvmrc

# 小版本
echo "18.19" > .nvmrc

# LTS 版本
echo "lts/*" > .nvmrc
echo "lts/hydrogen" > .nvmrc

# 最新版本
echo "node" > .nvmrc
echo "stable" > .nvmrc

实际项目示例

package.json 中声明引擎要求:

json
{
  "name": "my-project",
  "version": "1.0.0",
  "engines": {
    "node": ">=18.0.0 <21.0.0"
  }
}

配合 .nvmrc 使用:

bash
# 创建 .nvmrc
echo "18.19.0" > .nvmrc

# 提交到版本控制
git add .nvmrc
git commit -m "chore: add nvmrc for node version"

自动化插件

安装 zsh-nvm 插件:

bash
# Oh My Zsh
git clone https://github.com/lukechilds/zsh-nvm.git ~/.oh-my-zsh/custom/plugins/zsh-nvm

# 添加到 ~/.zshrc
plugins=(... zsh-nvm)

# 自动切换功能已内置

使用 direnv(更强大的方案):

bash
# 安装 direnv
brew install direnv

# 配置 Shell
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc

# 在项目目录创建 .envrc
echo "layout node" > .envrc
direnv allow

# 或指定版本
echo "use node 18.19.0" > .envrc
direnv allow

在多环境中使用npm

每个版本的 Node 都会自带一个不同版本的 npm,可以用 npm -v 来查看 npm 的版本。全局安装的 npm 包并不会在不同的 Node 环境中共享,因为这会引起兼容问题。它们被放在了不同版本的目录下,例如 ~/.nvm/versions/node/<version>/lib/node_modules</version> 这样的目录。这刚好也省去我们在 Linux 中使用 sudo 的功夫了。因为这是用户的主文件夹,并不会引起权限问题。

但问题来了,我们安装过的 npm 包,都要重新再装一次?幸运的是,我们有个办法来解决我们的问题,运行下面这个命令,可以从特定版本导入到我们将要安装的新版本 Node:

bash
nvm install v5.0.0 --reinstall-packages-from=4.2

npm 包管理详解

版本隔离机制

bash
# 每个 Node 版本有独立的 npm 和全局包
~/.nvm/versions/node/
├── v16.20.2/
   ├── bin/
   ├── node
   └── npm
   └── lib/
       └── node_modules/
           └── <全局>
├── v18.19.0/
   ├── bin/
   ├── node
   └── npm
   └── lib/
       └── node_modules/
           └── <全局>
└── v20.11.0/
    └── ...

优势:

  • ✅ 无权限问题(无需 sudo)
  • ✅ 版本隔离,避免冲突
  • ✅ 可以为不同项目使用不同全局包

迁移全局包

bash
# 方法 1:安装新版本时迁移
nvm install 18.19.0 --reinstall-packages-from=16.20.2

# 方法 2:手动迁移
nvm use 16.20.2
npm list -g --depth=0 > packages.txt
nvm use 18.19.0
xargs npm install -g < packages.txt

# 方法 3:使用 nvm 内置命令
nvm reinstall-packages 16.20.2

迁移过程示例:

bash
$ nvm install 18.19.0 --reinstall-packages-from=16.20.2
Downloading and installing node v18.19.0...
Computing checksum with sha256sum
Checksums matched!
Now using node v18.19.0 (npm v10.2.3)
Reinstalling global packages from v16.20.2...
Linking global packages from v16.20.2...

管理全局包

bash
# 查看当前版本的全局包
npm list -g --depth=0

# 安装全局包
npm install -g typescript eslint prettier

# 卸载全局包
npm uninstall -g typescript

# 更新全局包
npm update -g

# 清理缓存
npm cache clean --force

推荐的全局包:

bash
# 开发工具
npm install -g typescript ts-node nodemon

# 代码质量
npm install -g eslint prettier stylelint

# 脚手架工具
npm install -g create-react-app create-next-app @vue/cli

# 实用工具
npm install -g http-server serve json-server

使用局部依赖代替全局包

最佳实践:优先使用局部安装

bash
# ❌ 不推荐:全局安装
npm install -g typescript

# ✅ 推荐:局部安装
npm install --save-dev typescript

# 通过 npx 运行
npx tsc --version

# 或在 package.json 中添加脚本
{
  "scripts": {
    "build": "tsc",
    "lint": "eslint src/"
  }
}

优势:

  • ✅ 项目依赖明确
  • ✅ 版本可控
  • ✅ 团队协作一致
  • ✅ CI/CD 友好

高级用法与技巧

1. 批量操作

bash
# 卸载所有旧版本
nvm ls | grep -v "current\|system\|default" | xargs nvm uninstall

# 保留最新版本,卸载其他
nvm uninstall $(nvm ls | grep -v "v20" | grep "v[0-9]" | head -n -1)

2. 性能优化

bash
# 禁用颜色输出(提升速度)
export NVM_NO_COLORS=true

# 使用更快的镜像
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node

# 预下载二进制文件
nvm ls-remote | grep "LTS" | tail -5

3. 故障排查

问题 1:nvm command not found

bash
# 检查环境变量
echo $NVM_DIR

# 重新加载配置
source ~/.zshrc  # 或 source ~/.bashrc

# 检查安装
ls -la ~/.nvm/nvm.sh

问题 2:切换版本失败

bash
# 检查版本是否已安装
nvm ls

# 重新安装
nvm uninstall 18.19.0
nvm install 18.19.0

# 检查权限
ls -la ~/.nvm/versions/node/

问题 3:npm 全局包丢失

bash
# 重新链接
nvm reinstall-packages $(nvm version previous)

# 或重新安装
nvm use 18.19.0
npm install -g <packages>

4. CI/CD 集成

.github/workflows/test.yml

yaml
name: Test Multiple Node Versions

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16, 18, 20]
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      
      - run: npm ci
      - run: npm test

常见问题解答

Q1: NVM 和 NPM 有什么区别?

A:

  • NVM:管理 Node.js 版本本身
  • NPM:Node.js 的包管理器,管理依赖包
  • 两者互补,都需要使用

Q2: 如何完全卸载 NVM?

bash
# macOS/Linux
rm -rf ~/.nvm
# 从 ~/.zshrc 或 ~/.bashrc 中删除 NVM 相关配置
source ~/.zshrc

# Windows
# 通过控制面板卸载 nvm-windows

Q3: .nvmrc 文件应该提交到 Git 吗?

A:应该提交

  • 确保团队成员使用相同版本
  • CI/CD 环境可以自动使用正确版本
  • 避免因版本差异导致的 bug

Q4: 如何在 Docker 中使用 NVM?

dockerfile
FROM ubuntu:22.04

RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install 18
RUN . "$NVM_DIR/nvm.sh" && nvm use 18

CMD ["node", "--version"]

Q5: NVM 会影响系统性能吗?

A:

  • ⚡ 影响极小(仅 Shell 启动时加载)
  • 💾 占用磁盘空间(每个版本约 50-100MB)
  • 🎯 建议只保留常用的 2-3 个版本

总结

NVM 是 Node.js 开发者的必备工具:

  1. 版本管理:轻松安装和切换多个 Node 版本
  2. 权限友好:无需 sudo,用户级安装
  3. 项目隔离:通过 .nvmrc 为每个项目指定版本
  4. 包迁移:内置全局包迁移功能
  5. 跨平台:支持 macOS、Linux、Windows

关键命令速查:

bash
nvm install <version>          # 安装版本
nvm use <version>              # 切换版本
nvm ls                         # 列出已安装版本
nvm ls-remote                  # 列出可用版本
nvm alias default <version>    # 设置默认版本
nvm uninstall <version>        # 卸载版本

最佳实践:

  • 📝 每个项目添加 .nvmrc 文件
  • 🔄 定期更新到最新 LTS 版本
  • 📦 优先使用局部依赖而非全局包
  • 🗑️ 及时清理不再使用的版本

下一步学习:

开始使用 NVM,让你的 Node.js 开发更加高效!🚀✨