news 2026/10/12 3:11:38

Linux 下用 nvm 安装 Node v23 与 npm 10,实现多版本隔离管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 下用 nvm 安装 Node v23 与 npm 10,实现多版本隔离管理

1. 项目概述

1.1 为什么需要 nvm,而不是直接改系统的 Node

先说个我踩过的坑。早些年我在一台服务器上把 Node 从 v16 升到 v18,直接拿了官方 tar 包覆盖,结果系统里某老运维脚本里硬编码的 npm 路径全部炸掉,找问题花了整整半天。后来养成的习惯是:凡是 Linux 机器上要动 Node 版本,第一反应就是 nvm,绝不用系统包管理器硬升。

nvm 的全称是 Node Version Manager,作用用一句话说清楚:它把不同版本的 Node.js 和配套的 npm 安装到你当前用户的家目录里,然后通过修改当前终端的 PATH 环境变量来决定"现在用哪个版本"。整个过程不碰系统自带的 /usr/bin/node、/usr/bin/npm,不污染系统目录,不依赖 sudo 权限。

这次的目标版本是 Node v23.x 搭配 npm 10.x。Node 23 属于当前的非 LTS 版本线,它把很多新特性(比如更稳定的 ESM 支持、内置的 --run 命令实验性能力、性能改进的 fetch)带进了日常可用状态。npm 则对应 10.x,跟随 Node 23 官方默认自带的 npm 版本,不出意外会是 npm 10.9.x 或更高的小版本。

1.2 这套操作适合谁、解决什么问题

适用人群目标很明确:主要说给 Linux 服务器管理员、需要频繁切换 Node 版本的进阶前端开发者,以及那些被"系统 Node 改不动、一改就崩"困扰的运维新人。

解决的问题也直白:当你需要在新项目里用 Node 23 的新特性,但旧系统项目还挂在 Node 16/18 上时,你不能为了一个新项目把机器上所有老项目都拖进升级漩涡。用 nvm 做隔离管理,新老版本并存,随时切换,这才是正经解法。

1.3 nvm 的核心价值与影响范围

对于个人开发机,影响是自由:一个命令切版本,本地跑什么项目就用什么 Node。

对于生产服务器,影响是安全:不覆盖系统文件,不影响其他依赖系统 Node 的服务,升级失败随时回滚。

对于 CI/CD 流水线,影响是确定性:同一个 nvm 安装命令在任何 Linux 发行版上都一致,流水线上的 Node 版本可以被精确锁定。

2. 动手前的环境准备

2.1 检查当前环境状态

装 nvm 之前,先花两分钟确认一下当前机器状态,这事别省。有些发行版预装了 Node,有些是空机器,两种情况后续处理思路完全不同。

先看现在有没有 Node:

node -v which node

再看有没有安装 git 和 curl。nvm 安装脚本本体是通过 curl 或 wget 下载的,git 则在后续切换 Node 版本时用来获取远程版本列表:

git --version curl --version

比较新的官方安装脚本方式是用 curl 直接拉取。如果机器上 curl 没有,可以用 wget 或先装 curl:

# Ubuntu / Debian sudo apt update && sudo apt install -y curl git # CentOS / RHEL / Rocky sudo yum install -y curl git

还有一件事容易被忽略:确认当前用户的 shell 是什么。nvm 官方支持的 shell 主要为 bash 和 zsh,如果你日常用的是 fish 这种非 POSIX 系 shell,安装 nvm 之后需要额外处理兼容配置,它不是开箱即用的。

检查 shell:

echo $SHELL

绝大多数 Linux 默认是 bash,不用额外担心。

2.2 卸载系统自带 Node 的取舍

这里有个很多人纠结的点:到底要不要先卸载系统自带的 Node?

我的建议是:不要主动卸载。nvm 的工作机制决定了它会覆盖 PATH 环境变量里的 node 路径,只要配置正确,你平时在终端里跑 node -v 时,命中的一定是 nvm 管理的版本,和系统自带版本无关。

系统自带的 Node 可以作为"兜底版本"留在那,不影响 nvm 的正常工作。真正需要卸载系统 Node 的场景只有一种:你的系统里存在其他服务,比如某个旧打包工具,它们写死了调用 /usr/bin/node 路径,这些服务必须使用系统版本,那就更不要动它了。nvm 的好处恰恰就在于不用动它。

提示:nvm 管理的 node 安装路径形如 ~/.nvm/versions/node/v23.x.x/bin/node,实际运行时通过 PATH 前置覆盖,系统版本原封不动。

2.3 通过官方脚本安装 nvm

装 nvm 有两条路:官方 GitHub 安装脚本和手动 clone。平时推荐官方脚本,因为它会自动帮你把配置写进 ~/.bashrc 或 ~/.zshrc,省去手动配环境变量的麻烦。

执行下面这条命令,注意这里的地址是 nvm 官方的版本管理安装入口,不用纠结细节,跟着走:

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

当前 nvm 的稳定版本线是 v0.40.x,建议装到最新稳定版。执行完脚本后,终端会提示你 nvm 已经安装完成,并且自动往 ~/.bashrc 里追加了几行配置。

如果网络拉取 GitHub 原始文件不顺畅,也可以使用手动 clone 方式,这是同样可靠的备选路径:

git clone https://github.com/nvm-sh/nvm.git ~/.nvm cd ~/.nvm # 切到明确版本标签 git checkout v0.40.1 # 手动把加载配置写进 bashrc echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> ~/.bashrc

无论是官方脚本还是手动 clone,装完记得重载 shell 配置,让 nvm 命令立刻可用:

source ~/.bashrc

如果当前 shell 是 zsh,要把上面 .bashrc 全部替换为 .zshrc。

验证 nvm 是否装好:

nvm --version

看到 v0.40.1 之类的输出就说明安装成功了。

3. 使用 nvm 安装指定 Node 版本

3.1 查看可用的远程版本列表

nvm 的核心操作逻辑是先查版本、再装版本、然后用版本。下面这个命令会拉取远程所有可用版本,数量很多,建议用 grep 过滤:

nvm ls-remote

输出是按版本号排序的长列表,从最早的 v0.x 一直到最新的 v23.x。想看 LTS 版本可以这样:

nvm ls-remote --lts

如果你想针对性地看 v23 都有哪些具体小版本:

nvm ls-remote | grep "v23"

正常情况下你会看到类似 v23.3.0、v23.5.0 这样的一串小版本号。小版本之间的差异主要在于 Bug 修复、V8 引擎更新和部分新特性的 backport,原则是优先选当前最新的小版本,除非项目对某特定小版本有兼容性要求。

3.2 安装 Node v23.x 并确认 npm 版本

直接安装最新 v23:

nvm install 23

nvm 的版本号匹配规则很灵活:nvm install 23 会自动解析为当前 23 版本线的最新小版本。如果你明确了要某一具体版本,可以直接写全版本号,例如:

nvm install 23.5.0

安装过程 nvm 会从 Node 官方预编译二进制仓库下载对应压缩包并解压到 ~/.nvm/versions/node/ 目录下。正常情况下几十秒就能完成。

安装完成后,nvm 会自动把当前 shell 切换到新版本,并提示你当前正在使用的版本号。这一步建议立刻验证两次,一是 node 版本,二是 npm 版本:

node -v npm -v

Node v23.x 官方自带的 npm 对应 10.x 系列。例如 Node v23.5.0 默认捆绑 npm 10.9.2,Node v23.6.0 可能捆绑 npm 10.9.4。捆绑版本随 Node 发布节奏微调,保持在 10.x 范围内没问题。

注意:npm 的版本不是你想当然的固定值,它是 Node 发布时锁定的配套版本。除非你有特殊需求主动升级 npm,否则不需要操心"如何把 npm 升到 10.x"这件事,装对 Node 版本就自动满足了。

如果你想主动将 npm 升级到某特定 10.x 小版本,也是允许的:

npm install -g npm@10.9.4

但注意这将独立于 Node 本体,下次 nvm 切换 Node 版本时还需重新确认 npm 状态。

3.3 验证安装对系统的无侵入性

这点是这个项目标题的立身之本,单独说一下。安装完 v23 后系统自带的 Node 还在吗?验证一下:

ls -l /usr/bin/node /usr/bin/node -v

在没升级系统包的前提下,/usr/bin/node 原来的版本纹丝不动。而现在终端里的 node 命令指向的是 nvm 的目录:

which node

输出类似 /home/你的用户名/.nvm/versions/node/v23.5.0/bin/node。这就是 nvm 的核心机制:通过修改 PATH 环境变量,让你在同一台机器上拥有"系统版本"和"nvm 版本"两套 Node,彼此互不干扰。

再看一看当前 PATH 变量的变更方式:

echo $PATH

你会发现 ~/.nvm/versions/node/v23.x.x/bin 被插入到了 PATH 的最前面,所以终端执行 node 时优先命中它,而系统原生命令路径排在其后。

4. 多版本管理与日常切换实操

4.1 安装多个版本并随时切换

Node 项目多、版本需求杂的同学,nvm 的最大价值就体现在这里。比如机器上已经有一个稳定版本 v20.11.1 在跑老项目,现在又需要 v23.x 来跑新业务代码,继续执行安装:

nvm install 20.11.1 nvm install 23

此时机器上就并存了多个版本。查看本地已安装版本:

nvm ls

输出会列出所有本地版本,并标注当前正在使用的是哪一个,以及系统自带版本的位置。切到某个版本:

nvm use 23

切到另一个:

nvm use 20.11.1

如果你懒得每次手动切,可以为某个目录绑定固定版本 nvm 语法在项目里创建一个 .nvmrc 文件,文件里只写版本号。比如在项目根目录:

echo "23" > .nvmrc nvm use

nvm use 在没有指定版本参数时,会优先读取当前目录下的 .nvmrc 文件,自动切换到对应版本。这是多项目协作时最省心的做法,每个开发者拿到项目后只需要 nvm use 一下,Node 版本就对上了。

4.2 设置默认版本

对于个人开发机,希望每次新开终端都自动落到 v23,可以设默认版本:

nvm alias default 23

设置之后新打开的终端,nvm 会自动加载 default 别名对应的版本。这个设置不影响系统版本。

对于服务器场景,默认版本设置更要谨慎。因为服务器上可能存在由 systemd 管理的 Node 服务,它们如果依赖系统环境变量里的 node 路径,nvm 不会自动介入服务进程的环境。默认版本只在交互式 shell 里生效,cron 任务、systemd 服务拿到的环境变量里没有 nvm 路径。

4.3 卸载版本

某天你不需要某个版本了,卸载也简单:

nvm uninstall 20.11.1

卸载前建议确认没有活动项目正在使用该版本。虽然卸载后切到别的版本也能继续工作,但旧项目如果写死了绝对路径引用 ~/.nvm/versions/node/v20.11.1/bin/node,就会直接挂掉。稳妥起见,先 nvm use 切到别的版本再执行卸载。

4.4 针对性经验分享:服务器环境的一个坑

我在一台 CentOS 7 机器上遇到过这个问题:nvm 装完一切正常,终端里切版本也正常,但只要通过 systemd 启动某 Node 服务,服务进程里面使用的 Node 还是系统旧版本,导致新特性代码直接崩。原因就是 systemd 服务默认不会加载用户 shell 里的 nvm 环境变量。

解决方案有两种。第一种是把服务的 ExecStart 里改成使用 nvm 的绝对路径,写在 service 文件里:

ExecStart=/home/用户名/.nvm/versions/node/v23.5.0/bin/node /opt/myapp/server.js

第二种是在 service 文件里显式填入 PATH:

Environment=PATH=/home/用户名/.nvm/versions/node/v23.5.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

这两种方案都能让服务进程用到 nvm 版本。如果你是完全用 nvm 管理的机器,推荐第二种,因为以后 nvm 版本更新,只需要改一个 PATH 即可。

注意:生产服务器请不要过分依赖个人的 shell 配置,所有服务都应当通过 systemd unit 文件的 Environment 显式指定 PATH,这比依赖用户 shell 配置更稳。

5. 常见问题与排查技巧实录

5.1 nvm 命令找不到

装完 nvm 之后新开终端居然提示 command not found,这个问题出现频率非常高。

先确认 config 是否写进了正确的 shell 配置。大多数 Linux 默认 shell 是 bash,nvm 官方脚本写入 ~/.bashrc 没问题。但如果你用的是 zsh,脚本玩不转时会写进 ~/.bashrc,而 zsh 根本不读取它。

排查顺序:

# 1. 看当前 shell echo $SHELL # 2. 确认配置内容是否存在 grep "nvm" ~/.bashrc ~/.zshrc 2>/dev/null # 3. 手动加载测试 source ~/.nvm/nvm.sh nvm --version

如果是 shell 不匹配,手动把配置写进目标 shell 配置即可。

5.2 下载安装时显示 checksum 校验失败

Node 官方发布版本都有对应的校验值,下载到本地后 nvm 会做校验。如果你网络环境不太稳定,下载过程发生数据损坏,就会出现这类报错。

处理方式很简单,清掉本地缓存后再试一次:

nvm clear-cache nvm install 23

如果反复失败,考虑是下载镜像源的问题。nvm 默认走 Node 官方源 {node_version}/node-v{node_version}-linux-x64.tar.xz,在国内网络环境下偶尔抽风。可以临时切换镜像:

export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node nvm install 23

如果自定义镜像没有归档某些历史版本,可能跟 nvm ls-remote 返回的列表不一致,导致部分版本找不到,此时把环境变量清掉恢复默认源即可:

unset NVM_NODEJS_ORG_MIRROR

5.3 nvm use 切换失败,提示权限问题

权限问题的最常见来源是某次安装 Node 包时用了 sudo 把全局权限搞乱了。这正好呼应了标题里的"不破坏系统":任何时候都不要用 sudo npm install -g 去装包,nvm 用户目录的权限是普通用户级的,sudo 装的全局包会落到 /usr/lib/node_modules,和 nvm 路径互不相通。

如果你在 nvm 上无意中使用了 sudo,修复方式是:把 nvm 目录权限改回当前用户,把 sudo 装的全局 npm 包清理掉,然后重新用普通用户安装。

sudo chown -R 用户名:用户名 ~/.nvm

执行完重新加载 nvm:

source ~/.bashrc

从这里开始,永远不要在 nvm 命令前加 sudo。nvm 的安装原理就是用户级管理,不需要也不可能需要 root 权限。

5.4 npm 全局包在切换版本后丢失

nvm 切换版本后,之前 npm install -g 的全局包找不到了?这不是 bug,而是 nvm 的版本隔离机制导致的。

每个 Node 版本对应独立的全局包目录:~/.nvm/versions/node/v23.5.0/lib/node_modules 和 ~/.nvm/versions/node/v20.11.1/lib/node_modules 是两套完全隔离的目录。你切换到 v23 时,PATH 里只包含 v23 的 bin 目录,v20 全局包自然看不见。

解决方案有两个方向。第一个是接受隔离机制,每个版本各自装全局包,适合全局包不多的人。第二个是使用 nvm 的 reinstall-packages 命令,把一个版本的全局包迁移到另一个版本:

nvm reinstall-packages 20.11.1

执行后 nvm 会把源版本的所有全局包重新安装到当前版本里。这个特性在多版本频繁切换的工作流里很实用。

5.5 Node 版本对 npm 10.x 的兼容性说明

标题里提到了 npm 10.x,这里补充一个知识点:npm 10 的引擎声明支持 Node ^18.17.0 || >=20.5.0(具体小版本限制随 npm 版本略有调整)。Node v23 完全在支持范围内。所以 nvm install 23 装完,npm 10.x 开箱即用,不需要额外做任何版本适配。

如果哪天你发现 npm -v 显示的版本不在 10.x,大概率是以下两种情况:

  • 你用的 Node 版本不是通过 nvm 装的,而是系统自带或手动安装的,它们自带的 npm 版本可能为 9.x 或 6.x。此时 nvm 管理的 Node 与系统 npm 混用了。
  • 你手动执行过 npm install -g npm@9 或类似操作,把某个版本的全局 npm 降级了。处理方式是对该 Node 版本重新安装 npm:
nvm use 23 npm install -g npm@10

5.6 日常避坑速查表

场景容易踩的坑推荐做法
安装 nvm使用系统包管理器安装 nvm使用官方安装脚本,不用 apt/yum
装 Node 新版本先卸载旧版本多版本并存,nvm use 切换
自定义镜像安装镜像缺少部分历史版本优先官方源,失败再切镜象
systemd 服务依赖 shell 环境变量显式设置服务单元的 PATH
全局 npm 包使用 sudo 装包普通用户 npm install -g
CI/CD 流水线每台机器手动装 Node在流水线脚本中先执行 nvm install

5.7 两次实际部署的经验总结

第一次:某内部测试环境,原本系统 Node v18,需要在同一个 CI runner 上构建两个前端项目,一个要求 Node 20,一个要求 Node 23。装完 nvm 后,两个项目各自配置 .nvmrc,构建脚本开头加一行 nvm use,再无版本冲突问题,整个构建时长没有明显增加。

第二次:某线上数据服务,旧服务基于系统 Node 16,新服务需要 Node 23 的 WebSocket 性能和并发能力。通过 nvm 安装 v23 后,systemd 里按绝对路径指定新服务的 node 路径,旧服务保持系统版本不受影响。运行数月未出现由版本切换引发的故障。

两次经历让我始终确信:nvm 在 Linux 上的价值,不只是版本管理工具,它的核心价值是"系统稳定性与项目灵活性之间的安全桥"。

6. 补充建议与工作流优化

6.1 配合 .nvmrc 锁定项目版本

团队协作中,把 Node 版本写进项目仓库是规范动作。 .nvmrc 文件只有一行版本号,提交进代码仓库后,其他人 clone 项目只需执行:

nvm use

如果你的 shell 装了自动加载插件(比如 zsh 的 nvm-autoload),进入项目目录就自动触发 .nvmrc 的版本切换,甚至不需要手动执行任何命令。这样可以最大限度消除"我本地跑好好的,怎么你那就报错"这类环境不一致问题。

6.2 给 CI 流水线的建议

如果你的 CI 跑在 Linux 容器里,建议流水线开头写:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash export NVM_DIR="$HOME/.nvm" . "$NVM_DIR/nvm.sh" nvm install 23 nvm use 23 node -v

这段脚本的关键点是手动加载 nvm.sh,因为非交互式 shell 默认不会读取 .bashrc,直接调用 nvm 命令大概率失败。CI 流水线跑一次之后,你会理解"每一行都是必要的"是什么意思。

我个人在实际操作中的体会是:nvm 这类工具最怕的不是功能不够,而是使用者忽视环境隔离带来的隐性约束。花十分钟理清 PATH 的优先级和服务进程的环境来源,能在后续项目切换中省下数小时排错时间。

最后再分享一个实用小技巧:nvm 自带了 nvm debug 命令,当环境异常时可以快速输出当前 shell、PATH 条目、nvm 目录路径等关键诊断信息,比起一条条手动查要快得多。遇到诡异问题先跑一下 nvm debug,往往一眼就能定位到 PATH 没有被正确前置或 NVM_DIR 指向错误这类基础问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 3:10:57

OpenCV 4.8.0 DNN模块集成ONNX Runtime,推理加速与部署实践指南

简介:OpenCV 4.8.0 是一套跨平台计算机视觉与机器学习库,面向 C、Python、Java 开发者,覆盖图像处理、特征检测、对象识别、深度学习模型部署等常见任务。该版本整合 core、imgproc、dnn、calib3d 等核心模块,并针对硬件加速和运行…

作者头像 李华
网站建设 2026/10/12 3:10:50

从InfluxDB到Doris:DolphinScheduler离线同步实践

最近在调数据中台的离线链路时,我把一条一直很“绕”的路真正打通了:在AllData数据中台的离线开发平台(集成DolphinScheduler)上,把InfluxDB里的监控指标同步到Doris进行分析。其实InfluxDB和Doris我都用了很长时间&am…

作者头像 李华
网站建设 2026/10/12 3:10:46

ArcGIS新手Day1:理解坐标系、属性表与专题图

我第一次打开ArcGIS的时候,整个人是懵的:窗口密密麻麻全是按钮,工具栏层层叠叠,地图区域一片空白,完全不知道从哪里下手。后面用得久了才想明白,ArcGIS本质上并不是一个“画图软件”,而是一套围…

作者头像 李华
网站建设 2026/10/12 3:08:19

Tesseract 5.0编译后完整版本实战:从安装配置到中文识别避坑

简介:一份Tesseract 5.0编译后的完整版资源包,面向OCR应用开发者与图像文本识别场景。包内已集成核心引擎、依赖库及常用工具,可开箱即用或作为二次开发基础,降低自行编译源码的门槛。压缩包共496个文件,涵盖动态库、静…

作者头像 李华
网站建设 2026/10/12 3:07:55

5G NSA接入信令改进实战:压时延、防风暴、快接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华