团队锁 Node.js LTS:nvm 别名、.nvmrc 与 Volta pin 的可用组合
项目信息:
- nvm:nvm-sh/nvm
- Volta 包管理文档:docs.volta.sh/advanced/packages
volta pin参考:voltajs.com/reference/pin.html- Node 下载页:nodejs.org/en/download
- Node 发布计划:github.com/nodejs/Release
nvm 的 LTS 别名怎么用
Node 有 LTS 计划。在别名和 .nvmrc 里可以用 lts/* 指最新 LTS,用 lts/argon 这种写法指某条 LTS 线("argon" 线)的发布。下面这些命令都接受 LTS 参数:
nvm install --lts
nvm install --lts=argon
nvm install 'lts/*'
nvm install lts/argon
nvm uninstall --lts
nvm uninstall --lts=argon
nvm uninstall 'lts/*'
nvm uninstall lts/argon
nvm use --lts
nvm use --lts=argon
nvm use 'lts/*'
nvm use lts/argon
nvm exec --lts
nvm exec --lts=argon
nvm exec 'lts/*'
nvm exec lts/argon
nvm run --lts
nvm run --lts=argon
nvm run 'lts/*'
nvm run lts/argon
nvm ls-remote --lts
nvm ls-remote --lts=argon
nvm ls-remote 'lts/*'
nvm ls-remote lts/argon
nvm 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,并把当前已装的全局包迁过去:
nvm install --reinstall-packages-from=current 'lts/*'
.nvmrc 的查找规则和边界
在项目根目录(或任意上层目录)放一个 .nvmrc,内容可以是版本号,也可以是 nvm 能理解的任意字符串(见 nvm --help)。之后 nvm use、nvm install、nvm which 在命令行没给版本时会读 .nvmrc;如果找不到 .nvmrc,它们以状态码 127 退出。
nvm exec 和 nvm run 走同样的 .nvmrc 查找,但两者都解析不出来时会回退到当前 active 的 node — 这个回退按未定义行为处理,脚本里要可预测就显式传版本。
想用当前已激活的版本,显式传 current,例如 nvm which current。current 不受 .nvmrc 影响。
写入示例:
$ echo "5.9" > .nvmrc
$ echo "lts/*" > .nvmrc # 默认使用最新 LTS
$ echo "node" > .nvmrc # 默认使用最新版本
这几个例子假定 echo 是 POSIX 兼容 shell 的实现。在 Windows cmd 环境里写 .nvmrc(比如该文件是给远端 Linux 部署用的),要记住引号会被一并写入,生成的文件因此无效,得手动把引号去掉。
Volta:把精确版本写进 package.json
volta pin 更新项目的 package.json,把选定的工具版本固定下来。
volta pin [FLAGS] ...
参数 ... 是要 pin 的工具,例如 node@lts 或 yarn@^1.14。
Pin Node.js:
volta pin node— pin 最新 LTSvolta pin node@16.14.2— 特定版本volta pin node@16— 范围
pin 之后,package.json 里会多出一段:
{ "volta": { "node": "16.14.2" } }
被 pin 的工具优先于 volta install 设置的默认版本。volta 段可以包含 node、npm、yarn、pnpm。版本写法可以是精确版本(16.14.2)、主版本(16)、主次版本(16.14)、semver 范围(^16.14.0)、标签(lts、latest)。
Volta 文档对 pin 的 Node 版本是这样描述的:volta install 内部用 npm 风格解析决定可用版本和下载位置。安装工具时 Volta 会 pin 一个 Node 版本,这样即使默认 Node 版本变了,该工具仍能继续使用。流程是:如果 package.json 里指定了 engines,就用满足 engines 要求的最新 Node;否则用最新的 Node。在 Volta 0.6.8–0.8.7 期间,行为是优先选满足 engines 的最新 LTS,否则选整体最新,再否则选最近的 LTS;从 Volta 0.9.0 起,Volta 会把包 pin 到安装该工具时的当前默认 Node 版本。旧版本区间的行为如需依赖,建议自行验证。
Volta 维护者的说法:volta pin node@14 会在当下解析出版本,并把精确版本写进 package.json,之后不再变动(除非你显式改它)。Volta 没有 Node「当前版本」这个概念,每次执行命令时它自己判断上下文,跑对应的版本。
升级到新 LTS 的几条路径
先确认现状:node --version。
用版本管理器升级:
nvm install --lts && nvm use --lts # nvm
fnm install --lts && fnm use lts-latest # fnm
volta install node@lts # Volta
如果是从 nodejs.org 装的,下载最新 LTS 安装包重跑一遍,会替换已有安装。Linux 上没有版本管理器时用 NodeSource:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && sudo apt-get install -y nodejs
macOS Homebrew:brew upgrade node。Windows:winget upgrade OpenJS.NodeJS,或从 nodejs.org 重装。
升级后跑 node --version 和 npm --version 确认。然后在使用原生模块的项目里执行 npm rebuild,让 bcrypt、sharp、node-sass、better-sqlite3 这类模块针对新 ABI 重新编译。
想升到某个指定主版本而不是最新 LTS,把 --lts 换成版本号即可:nvm install 22.11.0、fnm install 22.11.0、volta install node@22。
除非有明确理由留在 Current,否则选 LTS。npm 上的库声明的 engines.node 范围是面向 LTS 的,CI 矩阵应当跟它对齐。Current 用在个人项目上没问题,但每六个月这条线 EOL 就得再升一次。
工具对照
| 工具 | 平台 | 速度 | 自动切换 | 锁定文件 | 适合谁 |
|---|---|---|---|---|---|
| nvm | Linux、macOS(Bash) | shell 启动慢 | 手动或 nvm use | .nvmrc | 默认选择,大量教程以它为准 |
| nvm-windows | 仅 Windows | 尚可 | 手动 | 无 | 想要 nvm 语法的 Windows 用户 |
| fnm | Linux、macOS、Windows | 很快(Rust) | 是(shell hook) | .nvmrc 或 .node-version | 受够 nvm 慢的人 |
| Volta | Linux、macOS、Windows | 快 | 是(按项目) | package.json 的 volta 键 | 想把 Node 和包管理器版本一起钉在仓库里的团队 |
| n | Linux、macOS | 快 | 手动 | 原生无 | 简单场景,不需要锁定 |
| asdf | Linux、macOS | 尚可 | 是 | .tool-versions | 用一套工具管 Node + Ruby + Python + Go 的多语言开发者 |
按项目切换用 .nvmrc:
echo "22" > .nvmrc # 也可以写 "lts/iron" 或 "22.11.0"
nvm use
版本声明文件各管什么
| 文件 | 谁读 | 作用 |
|---|---|---|
.nvmrc | nvm、fnm、GitHub actions/setup-node | 只钉 Node |
.node-version | fnm、asdf、GitHub actions/setup-node | 只钉 Node |
package.json engines.node | npm(不匹配只警告)、yarn(报错)、pnpm(配合 engine-strict=true 报错) | Node 下限,建议性 |
package.json volta | Volta、GitHub actions/setup-node | Node 和包管理器 |
engines 默认只是建议,除非在 .npmrc 里加上 engine-strict=true。加了这个标志后,npm install 在超出范围的 Node 上会直接失败而不是警告。库项目推荐这么配,免得有人从非预期的 Node 版本发版。
三层锁定组合
.nvmrc写一行,例如22或lts/iron,nvm、fnm、GitHub actions/setup-node 都能读。- package.json 里写
engines: { node: '>=22.0.0' },配合.npmrc的engine-strict=true,不匹配时安装直接失败。 - Volta:
volta pin node@22.11.0往 package.json 写入volta键,仓库里每个开发者都透明地拿到这个精确版本。