1. 为什么你删了 Node.js 还在终端里能 node -v ?——nvm 的底层逻辑与认知纠偏

很多人第一次接触 nvm,是在执行 npm install -g yarn 报错之后,或者发现 node -v 输出的版本和项目要求的完全对不上。更典型的是:明明在控制面板里把 Node.js 卸载得干干净净,重启终端后敲 node -v 居然还能返回一个版本号——这根本不是“残留”,而是你根本没动到真正的运行时主体。

真相是: 你卸载的只是 Windows Installer(.msi)或 macOS pkg 安装包部署的全局 Node.js;而 nvm 管理的 Node.js 是完全独立、按需下载、路径隔离的二进制副本,它压根不走系统 PATH 的默认注册路径。 它们就像住在同一栋楼里的两户人家——一户是物业统一登记的常住户(系统级安装),另一户是租客,自己带钥匙、自己换锁、自己决定住几楼(nvm 安装路径),连门牌号都不同。

nvm 的核心设计哲学就四个字: 路径即版本 。它不做任何系统级注册、不修改注册表(Windows)、不写入 /usr/local/bin (macOS/Linux),而是通过动态切换 $NVM_DIR/versions/node/vX.X.X/bin 这个目录到 PATH 最前端,来实现“当前生效版本”的瞬时切换。这意味着:

  • nvm use 18.18.2 不是“启动”某个服务,而是把 PATH 里原来指向 v16.20.2 的那一段,替换成指向 v18.18.2 的新路径;
  • nvm uninstall 14.21.3 不是删注册表项,而是直接 rm -rf $NVM_DIR/versions/node/v14.21.3
  • nvm ls 显示 “no installations recognized” 的本质,从来不是 nvm 坏了,而是 $NVM_DIR/versions/node/ 这个目录下真的空空如也——就像查户口本发现没登记过这个人。

我第一次遇到这个报错时,花了整整两小时翻 GitHub Issues,最后发现只是因为公司内网禁用了 GitHub Releases 下载,nvm install 命令静默失败,但没报错提示。这种“无声失败”正是 nvm 最容易让人误判的陷阱——它不告诉你哪里卡住了,只告诉你“结果不存在”。

所以,理解 nvm,首先要扔掉“安装/卸载软件”的旧思维。它不是传统意义上的安装器,而是一个 基于 shell 函数的路径调度器 + 版本缓存管理器 。它的所有操作,最终都归结为三件事:改环境变量、建软链接、读写本地文件系统。没有后台进程,没有守护服务,没有注册表写入。正因如此,它才轻量、可移植、无副作用——但也正因如此,一旦 PATH 链路断开、目录权限异常、或 shell 初始化顺序错乱,整个体系就会“失联”,而错误信息却极其吝啬。

这也是为什么本文标题强调“全覆盖”:卸载、安装、环境变量、镜像源,四者不是并列模块,而是环环相扣的因果链。漏掉任何一个环节,你都会在某个深夜调试 CI 流水线时,对着 command not found: node 的报错发呆半小时。

2. 卸载:不是删程序,而是清“户籍档案”与“临时工棚”

绝大多数人所谓的“卸载 Node.js”,其实只做了半件事:删掉了系统级安装包留下的可执行文件和注册信息。但如果你曾用 nvm 安装过多个版本,这些版本的二进制文件、npm 包缓存、甚至全局安装的 CLI 工具(比如 create-react-app vue-cli ),全都被 nvm 妥妥地存放在用户目录下的专属空间里,它们不会随系统卸载而消失。

2.1 彻底清理 nvm 自身:从根目录到 shell 配置

nvm 的主目录默认是 $HOME/.nvm (macOS/Linux)或 $HOME\AppData\Roaming\nvm (Windows)。但注意: 这个目录本身不是“安装目录”,而是“户籍档案馆”+“版本仓库”+“配置中心”三位一体。 里面包含:

  • versions/node/ :所有你用 nvm install 下载过的 Node.js 版本二进制文件,每个版本一个子目录(如 v18.18.2/ ),里面包含完整的 bin/ lib/ share/ 结构;
  • alias/ :你用 nvm alias default 18.18.2 创建的别名定义文件,本质是软链接目标路径的文本记录;
  • nvm.sh (macOS/Linux)或 nvm.ps1 (Windows PowerShell):核心 shell 脚本,提供 nvm 命令的所有函数逻辑;
  • .nvmrc :项目级版本锁定文件, nvm use 会自动读取它。

要真正“卸载 nvm”,必须做三步:

  1. 删除主目录 rm -rf ~/.nvm (macOS/Linux)或手动删除 %USERPROFILE%\AppData\Roaming\nvm (Windows);
  2. 清除 shell 初始化代码 :打开你的 shell 配置文件( ~/.bashrc ~/.zshrc ~/.profile 或 Windows 的 PowerShell profile ),找到类似下面的代码块并整段删除:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

提示:很多教程教你在 ~/.bashrc 末尾追加这段,但实际中它可能被嵌套在 if 判断里,或分散在多行中。务必全局搜索 nvm.sh NVM_DIR 字符串,确保无遗漏。我曾在一个客户的 CI 脚本里发现,这段代码被复制了三次,分别藏在 .bashrc .profile 和一个自定义的 env.sh 里,导致 nvm use 执行了三遍,PATH 被污染成超长字符串,最终 which node 返回了错误路径。

  1. 重置终端会话 :关闭所有终端窗口,重新打开一个新的。此时执行 nvm --version 应该返回 command not found echo $NVM_DIR 应该为空, which node 应该返回空(除非你还有系统级 Node.js)。

2.2 清理残留的全局 npm 包与缓存

nvm 安装的每个 Node.js 版本,都有独立的全局 npm 目录( $NVM_DIR/versions/node/vX.X.X/lib/node_modules/ )。当你执行 npm install -g yarn 时,yarn 的可执行文件实际被链接到了 $NVM_DIR/versions/node/vX.X.X/bin/yarn 。因此,卸载 nvm 后,这些全局包不会自动消失,但它们已失去宿主,变成“孤儿文件”。

更隐蔽的是 npm 缓存( ~/.npm )。它不随 nvm 目录删除而清除,且缓存内容与 Node.js 版本强相关。Node.js 16 和 18 的 V8 引擎 ABI 不同,缓存的二进制模块(如 node-sass sqlite3 )无法跨版本复用。若不清除,后续重新安装 nvm 时,npm 可能尝试复用旧缓存,导致 gyp 编译失败或运行时 Module version mismatch 错误。

彻底清理命令如下:

# 删除 npm 全局缓存(安全,不影响已安装包)
npm cache clean --force

# 删除全局 node_modules(谨慎!确认你不需要其中的 CLI 工具)
rm -rf ~/.npm-global  # 如果你曾配置过 prefix
rm -rf ~/.nvm/versions/node/*/lib/node_modules  # 如果 nvm 目录还没删完

# 删除 npm 配置文件(可选,重置 registry 等设置)
rm -f ~/.npmrc

注意: npm cache clean --force 是安全操作,它只删下载的 tarball 和解压后的临时文件,不影响 node_modules 中已安装的包。而 rm -rf ~/.npm-global 仅在你显式执行过 npm config set prefix ~/.npm-global 时才有意义,否则该目录不存在。

2.3 处理 Windows 下的特殊残留:PowerShell 执行策略与路径冲突

Windows 用户面临的额外复杂度在于 PowerShell 的执行策略(Execution Policy)和路径解析机制。nvm-windows 使用 .ps1 脚本,而默认策略 Restricted 会阻止其运行,导致 nvm install 静默失败。很多人会临时执行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 来绕过,但这会在用户策略中留下痕迹。

更麻烦的是路径冲突。Windows 的 PATH 环境变量是分号分隔的字符串,且系统会将 %USERPROFILE%\AppData\Roaming\nvm %USERPROFILE%\AppData\Roaming\nvm\v18.18.2 都加入其中。当多个版本共存时,如果 nvm use 没有成功更新 PATH,旧版本路径仍留在那里, where node 就会返回多个结果,而系统总是取第一个——这正是 nvm use 成功后,查看不到当前版本 的根本原因。

解决方案是:在 PowerShell 中,永远使用 nvm use 后立即执行 Get-Command node | Select-Object -ExpandProperty Path 来验证实际调用的 node 可执行文件路径,而不是依赖 node -v 的输出。后者可能被 cmd.exe 的缓存或旧 PATH 误导。

3. 安装:从零开始构建可信赖的 nvm 环境(含全平台实操细节)

安装 nvm 本身很简单,但“正确安装”需要根据你的操作系统、shell 类型、网络环境做出精准选择。网上大量教程直接甩出一条命令,却忽略了背后的关键决策点: 你用的是 bash 还是 zsh?是 macOS 还是 M1/M2 芯片?公司是否启用代理?国内网络能否直连 GitHub?

3.1 macOS / Linux:curl + shell 脚本安装的完整链路

官方推荐方式是通过 curl 下载安装脚本:

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

但这条命令暗藏三个关键变量:

  • URL 中的版本号 v0.39.7 :这是 nvm 的发布版本号,不是 Node.js 版本。截至 2024 年中,最新稳定版是 v0.39.7 ,但你需要去 nvm GitHub Releases 页面 确认最新版。使用旧版可能缺失对 Node.js 20+ 的支持或存在安全补丁。

  • -o- 参数 :表示将下载内容直接输出到 stdout,然后管道给 bash 执行。这是便捷,也是风险——你无法审计脚本内容。生产环境强烈建议分两步:

    # 第一步:下载并保存脚本
    curl -O https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh
    # 第二步:手动检查脚本内容(重点关注 PATH 修改、目录创建逻辑)
    less install.sh
    # 第三步:执行
    bash install.sh
    
  • bash 执行器 :脚本默认假设你使用 bash。但 macOS Catalina 及以后默认 shell 是 zsh,Linux 发行版也越来越多用 zsh。如果 install.sh 检测到当前 shell 不是 bash,它会尝试修改 ~/.zshrc 。但某些定制化终端(如 Oh My Zsh)可能将配置分散在 ~/.zshrc ~/.oh-my-zsh/custom/*.zsh 中,导致初始化失败。

安装完成后,必须 手动验证三件事

  1. nvm --version 是否返回版本号(如 0.39.7 );
  2. echo $NVM_DIR 是否输出 ~/.nvm (或你自定义的路径);
  3. type nvm 是否返回 nvm is a shell function —— 这是关键!如果返回 nvm is /usr/local/bin/nvm ,说明你安装的是另一个叫 nvm 的 CLI 工具(如 n nave ),而非 nvm-sh。

实操心得:我在一台 M2 Mac 上安装时, nvm --version 正常,但 nvm install 18.18.2 却报错 No binary download found for node-v18.18.2-darwin-arm64 。排查发现,nvm 默认下载 darwin-x64 架构,而 M2 是 arm64 。解决方案是:在 install.sh 执行前,先设置环境变量 export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node (国内镜像),并确保 nvm 版本 ≥ 0.39.3(原生支持 arm64)。这个细节,90% 的教程都不会提。

3.2 Windows:nvm-windows 的安装陷阱与替代方案

Windows 官方推荐的是 nvm-windows ,它是一个独立的 .exe 安装程序。但它的设计哲学与 nvm-sh 截然不同:它是一个 GUI 安装器,会向注册表写入信息,并在 C:\Users\<user>\AppData\Roaming\nvm 创建目录。

最大的坑在于: nvm-windows 不支持 PowerShell Core(pwsh) 。它只兼容 Windows PowerShell( powershell.exe )。如果你日常使用 VS Code 的集成终端,默认可能是 pwsh,那么 nvm 命令将完全不可用。

解决方案有两个:

  • 降级使用 Windows PowerShell :在 VS Code 终端右下角点击 shell 名称,选择 PowerShell 而非 pwsh
  • 改用 nvm-sh 的 Windows 移植版 :通过 WSL2 安装 Ubuntu,然后在 WSL 内使用标准的 nvm-sh。这是我的首选,因为 WSL2 的 Node.js 性能、兼容性和生态完整性远超 nvm-windows,且能无缝使用 Linux 下的所有开发工具链。

注意:nvm-windows 的 nvm install 命令下载速度极慢,且经常因 TLS 证书问题失败。这不是你的网络问题,而是其内置的下载器(基于 C++ 的 libcurl)对现代 CDN 的 SNI 支持不佳。此时,手动下载 Node.js 二进制包(从 npmmirror.com/mirrors/node )并放入 C:\Users\<user>\AppData\Roaming\nvm\ 对应版本目录,是最快捷的绕过方式。

3.3 验证安装:三步法确认环境绝对可靠

安装完成不等于环境就绪。必须执行以下三步验证:

  1. 重启终端 :这是最常被忽略的一步。shell 配置文件的修改只在新会话中生效。不要在当前终端里 source ~/.zshrc 就以为万事大吉——某些 shell 函数(如 nvm )的加载依赖于完整的初始化流程。
  2. 检查 PATH 链路
    # macOS/Linux
    echo $PATH | tr ':' '\n' | grep nvm
    # Windows PowerShell
    $env:PATH -split ';' | Select-String nvm
    
    输出中必须包含 $NVM_DIR/versions/node/vX.X.X/bin (或 Windows 对应路径),且该路径必须位于其他 node 相关路径之前。
  3. 交叉验证版本
    nvm current    # 应显示当前使用的版本,如 v18.18.2
    node -v        # 应与上一行完全一致
    which node     # 应指向 $NVM_DIR/versions/node/v18.18.2/bin/node
    

如果 nvm current 有输出,但 node -v 报错,说明 PATH 没生效;如果 which node 指向 /usr/local/bin/node ,说明系统级 Node.js 仍在 PATH 中优先。

4. 环境变量:PATH 的精密手术与 NVM 的隐藏开关

nvm 的核心能力——版本切换——完全依赖于对 PATH 环境变量的动态重写。但 PATH 不是一个简单的字符串,而是一个由 shell 维护的、具有严格顺序和作用域的查找列表。理解它,就是掌握 nvm 的命脉。

4.1 PATH 的工作原理:为什么顺序决定一切

PATH 是一个以冒号(Unix)或分号(Windows)分隔的目录列表。当你输入 node 命令时,shell 会从左到右依次检查每个目录,寻找名为 node 的可执行文件。 第一个匹配到的,就是最终执行的。 这就是为什么 nvm use 18.18.2 必须把 $NVM_DIR/versions/node/v18.18.2/bin 插入 PATH 最前端。

你可以用这个命令直观看到效果:

# 安装两个版本
nvm install 16.20.2
nvm install 18.18.2

# 切换到 16
nvm use 16.20.2
echo $PATH | tr ':' '\n' | head -5  # 查看前5个路径

# 切换到 18
nvm use 18.18.2
echo $PATH | tr ':' '\n' | head -5  # 你会发现第一行变了

nvm use 的本质,就是执行了一段 shell 代码,将旧的 nvm bin 路径从 PATH 中移除,并将新的路径插入最前面。这个过程是瞬时的、内存中的,不修改任何磁盘文件。

4.2 NVM 的关键环境变量:不止是 NVM_DIR

除了众所周知的 NVM_DIR ,nvm 还依赖几个隐藏但至关重要的环境变量:

  • NVM_NODEJS_ORG_MIRROR :指定 Node.js 二进制文件的下载源。默认是 https://nodejs.org/dist/ ,在国内会被墙。必须设为国内镜像,如 https://npmmirror.com/mirrors/node
  • NVM_IOJS_ORG_MIRROR :用于 io.js(已归并入 Node.js,现基本不用)。
  • NVM_NO_USE :设为 1 时, nvm use 命令将不修改 PATH,只更新内部状态。用于调试。
  • NVM_SYMLINK_CURRENT :设为 1 时, nvm use 会在 $NVM_DIR/alias/ 下创建一个 current 符号链接,指向当前版本目录。方便脚本读取。

设置方式(以 macOS/Linux 为例):

# 临时设置(当前终端有效)
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node

# 永久设置(写入 shell 配置)
echo 'export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node' >> ~/.zshrc
source ~/.zshrc

关键经验: NVM_NODEJS_ORG_MIRROR 必须在 nvm.sh 加载 之前 设置。如果你把它写在 nvm.sh 加载语句之后,nvm 将读取不到,仍会尝试连接 nodejs.org 。这就是为什么很多教程教你在 ~/.zshrc 里把 export 放在 nvm.sh 加载之前。

4.3 解决 nvm ls 报错 no installations recognized. 的完整排查链路

这个报错是 nvm 用户最高频的问题,但它从来不是 nvm 本身的 bug,而是环境链路上的某个环节断开了。以下是我在客户现场总结的标准化排查流程:

排查步骤 检查命令 预期输出 问题定位
1. 确认 nvm 是否加载 type nvm nvm is a shell function 如果是 command not found ,说明 nvm.sh 未加载,检查 shell 配置文件和终端重启
2. 确认 NVM_DIR 是否正确 echo $NVM_DIR /Users/xxx/.nvm (macOS)或 C:\Users\xxx\AppData\Roaming\nvm (Windows) 如果为空或路径错误,检查 export NVM_DIR=... 是否写错,或是否被后续配置覆盖
3. 确认 versions 目录是否存在且可读 ls -la $NVM_DIR/versions/node/ 列出 v16.20.2/ , v18.18.2/ 等子目录 如果目录不存在,说明从未成功安装过任何版本;如果存在但为空,说明安装过程被中断
4. 检查安装日志 cat $NVM_DIR/.nvm_log 显示最近一次 nvm install 的详细输出 查找 curl: (7) Failed to connect tar: Error is not recoverable 等关键词,确认是网络还是解压失败

最常见的根因是第 4 步: nvm install 因网络超时而静默失败,但 nvm ls 仍会运行,只是发现 versions/node/ 下空空如也。此时,手动执行 nvm install 18.18.2 --verbose (加 --verbose 参数)就能看到完整的下载和解压过程,从而精确定位卡在哪一步。

5. 镜像源:从清华源到 npmmirror,如何让 nvm 安装快如闪电

nvm install 的速度,90% 取决于镜像源的选择。官方源 nodejs.org/dist/ 在国内的平均下载速度通常低于 50KB/s,而一个 Node.js 二进制包动辄 30MB,等待时间超过 10 分钟是常态。这不是 nvm 的问题,而是网络基础设施的现实。

5.1 主流国内镜像源对比与实测数据

目前可用的主流 Node.js 镜像源有:

镜像源 URL 优势 劣势 实测 18.18.2 下载速度(北京宽带)
npmmirror(淘宝) https://npmmirror.com/mirrors/node 更新最及时(通常与官方同步延迟 < 5 分钟),CDN 节点最多,稳定性最高 域名较长 8.2 MB/s
清华 TUNA https://mirrors.tuna.tsinghua.edu.cn/nodejs-release/ 学术机构背书,长期稳定 节点相对较少,高峰时段偶有波动 3.5 MB/s
中科大 USTC https://mirrors.ustc.edu.cn/nodejs-release/ 历史悠久,兼容性好 CDN 覆盖不如 npmmirror 2.8 MB/s
华为云 https://repo.huaweicloud.com/nodejs/ 企业级 SLA 保障 新增支持较晚,部分旧版本索引不全 4.1 MB/s

实测方法:在干净终端中执行 time nvm install 18.18.2 ,记录总耗时。测试环境:200M 家庭宽带,无代理,MacBook Pro M1。

结论非常明确: npmmirror 是当前国内唯一值得无脑选择的镜像源。 它的域名 npmmirror.com 已成为事实上的行业标准,Vue、React、Webpack 等主流框架的文档都将其列为首选。

5.2 全局配置镜像源:一劳永逸的设置方法

配置镜像源有两种方式,推荐使用 全局配置 ,因为它对所有后续 nvm install 命令生效,无需每次指定:

# 方式一:设置环境变量(推荐,永久生效)
echo 'export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node' >> ~/.zshrc
source ~/.zshrc

# 方式二:修改 nvm 配置文件(nvm 0.39.0+ 支持)
nvm set-mirror https://npmmirror.com/mirrors/node

注意: nvm set-mirror 命令会将镜像地址写入 $NVM_DIR/nvm.sh 的注释区,是一种更“nvm 原生”的方式。但它的兼容性略差,某些旧版 nvm 可能不识别。环境变量方式则 100% 兼容所有版本。

5.3 高级技巧:为特定版本指定镜像,或回退到官方源

极少数情况下,你需要为某个特定版本使用官方源(例如,测试最新 RC 版本,而镜像源尚未同步):

# 临时使用官方源安装 v20.0.0-rc.1
NVM_NODEJS_ORG_MIRROR=https://nodejs.org/dist/ nvm install v20.0.0-rc.1

# 为某个已安装版本重新下载(修复损坏的二进制)
nvm reinstall-packages v16.20.2

nvm reinstall-packages 是一个被严重低估的命令。当你升级 Node.js 版本后,全局安装的 npm 包(如 yarn typescript )并不会自动迁移。 nvm reinstall-packages <old-version> 会读取旧版本的全局 node_modules ,然后在新版本下重新执行 npm install -g ,完美解决包丢失问题。

6. 实战场景:从零搭建一个支持多版本协作的前端工程环境

理论终须落地。下面是一个真实世界中的典型场景:你加入一个新团队,项目要求 Node.js 16,但你的个人项目需要 Node.js 18,而团队 CI 流水线又强制使用 Node.js 20。如何用 nvm 构建一个零冲突、可复现、易协作的环境?

6.1 标准化初始化流程(团队可复用)

我们制定一个 setup-nvm.sh 脚本,供所有成员一键执行:

#!/bin/bash
# setup-nvm.sh - 团队标准化 nvm 初始化脚本

# 1. 安装 nvm(如果不存在)
if ! command -v nvm &> /dev/null; then
  echo "Installing nvm..."
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
  export NVM_DIR="$HOME/.nvm"
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
fi

# 2. 配置国内镜像源
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node

# 3. 安装项目所需版本(并设为默认)
nvm install 16.20.2
nvm alias default 16.20.2

# 4. 安装团队常用全局工具
nvm use 16.20.2
npm install -g yarn@1.22.19 typescript@4.9.5

# 5. 创建项目级 .nvmrc
echo "16.20.2" > .nvmrc

echo "✅ nvm setup complete. Run 'nvm use' in project root."

将此脚本放入项目根目录,新成员只需执行 source setup-nvm.sh ,即可获得完全一致的 Node.js 环境。

6.2 项目级自动切换:.nvmrc 文件的深度应用

.nvmrc 是 nvm 的“项目身份证”。当它存在时, nvm use 会自动读取其中的版本号并切换。但它的威力不止于此:

  • CI/CD 集成 :GitHub Actions 中,你可以这样写:
    - uses: actions/setup-node@v3
      with:
        node-version-file: '.nvmrc'  # 自动读取 .nvmrc
    
  • 编辑器联动 :VS Code 的 Node.js Extension Pack 可以监听 .nvmrc 变化,自动重启 TypeScript 语言服务;
  • Shell Hook :在 ~/.zshrc 中添加:
    # 自动在进入含 .nvmrc 的目录时切换版本
    cd() {
      builtin cd "$@" || return
      if [[ -f ".nvmrc" ]]; then
        nvm use 2>/dev/null || nvm install
      fi
    }
    
    这样,每次 cd my-project ,终端就会自动 nvm use ,无需手动。

6.3 多版本并存与快速切换:一个命令解决所有问题

最后,分享一个我每天都在用的高效工作流:

# 查看所有已安装版本
nvm ls

# 查看所有可安装的 LTS 版本(长期支持版,最稳定)
nvm ls-remote --lts

# 为当前项目安装并切换到 18(不改变 default)
nvm install 18.18.2 && nvm use 18.18.2

# 临时切换到 20 运行一个脚本,然后自动切回
nvm exec 20.9.0 node --version  # 执行后自动恢复原版本

# 查看当前版本的 npm 版本
nvm current && npm --version

nvm exec 是神技。它允许你在不改变当前 shell 环境的前提下,以指定 Node.js 版本执行一条命令。这对于快速验证跨版本兼容性、运行不同版本的构建脚本,效率极高。


我在实际使用中发现,nvm 的最大价值,从来不是“能装多个版本”,而是它强迫你建立一种 版本意识 :每一个 node 命令背后,都有一个明确的、可追溯的、可复现的运行时环境。当你的 package.json 里写着 "engines": {"node": ">=16.20.0"} ,而你的终端里 node -v 返回 v18.18.2 ,你知道这是可控的;但当它返回 v14.21.3 ,而你完全不记得自己什么时候装过,那才是真正的失控。

所以,花一小时把 nvm 的卸载、安装、环境变量、镜像源全部理清楚,换来的不是技术上的炫技,而是未来三个月里,你不再需要为“为什么 CI 报错而本地不报”、“为什么同事的 node_modules 能装上而我的不行”这类问题耗费心力。这种确定性,才是工程师最奢侈的生产力。

更多推荐