管理多版本 node -- nvm 的使用

公司有个老项目要维护,git 拉下来项目就是一阵安装依赖。之后直接 npm run dev。结果失败了。才想起来这个项目要用 node 11 以下版本。自己的 MacOS 已经在官网安装了 node v12,总不能为此降级成 v10。突然想起了 nvm 这个管理库。虽然刚入门时候用过一个管理库,忘了是 n 还是 nvm-widnows 了,这次也正好也好好体验一番。

由于我不用 windows,不确定以下操作是否通用。

安装

项目地址:https://github.com/nvm-sh/nvm

如果是 MacOS 或者 Linux,比较方便,直接 curl 或者 wget 就行了。

1
2
3
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
# 或者
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

之后,它提示我不用配置环境变量了,因为已经帮我配置好了(我用的 zsh)。

其他 shell 不确定是否要自己配置下。安装结束时会有提示。

通过 nvm 安装的 node,会存放在 ~/.nvm 下。

使用

查询安装的 node

由于我系统已经安装过了,并且通过 nvm 安装了两个版本(10.19.0 和 12.16.1)。

上面三行,显示了安装了那些版本的 node。之后的,都是默认提供的别名(alias)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nvm ls

-> v10.19.0 # 手动安装的版本,前方有箭头表示当前正在使用此版本
v12.16.1 # 手动安装的版本
system # 系统已安装的版本
default -> 10.19.0 (-> v10.19.0) # 当前默认版本
node -> stable (-> v12.16.1) (default) # 当前最新的 node 版本
stable -> 12.16 (-> v12.16.1) (default) # (已废弃)针对 0.12 之前版本有效,现在和 node 内容完全一致
iojs -> N/A (default) # 当前最新的 iojs 版本(曾经node)
unstable -> N/A (default) # 非稳定版本,我没装
lts/* -> lts/erbium (-> v12.16.1) # 最新的LTS长期支持版本,装了12.16.1
lts/argon -> v4.9.1 (-> N/A) # LTS长期支持版本 v4系列,没装
lts/boron -> v6.17.1 (-> N/A) # LTS长期支持版本 v6系列,没装
lts/carbon -> v8.17.0 (-> N/A) # LTS长期支持版本 v8系列,没装
lts/dubnium -> v10.19.0 # LTS长期支持版本 v10系列,装了
lts/erbium -> v12.16.1 # LTS长期支持版本 v12系列,装了12.16.1

查询当前使用的 node 版本

1
2
3
nvm ls      # 可以查看,就是返回内容太多了
nvm current # 直接返回当前是用的版本号
node -v # 直接调用 node 查询版本号,我一般都用这个查

查询远端 node 版本

1
nvm ls-remote

这个命令会返回所有的 node 版本,费时还不找好。一般都是进行过滤。

比如安装 LTS 长期支持版本,可以加上参数 --lts

1
nvm ls-remote --lts

如果需要查询 v8 系列 LTS 的版本,可以使用官方语法,但你必须知道它的英文名字:

1
nvm ls-remote --lts=carbon

不过,我一般都是采用字符串过滤的方案,这样无需记忆每个版本的名字。最主要是,如果不是 LTS 版本,是没有名字的:

1
2
nvm  ls-remote --lts | grep v8
nvm ls-remote | grep v13

还有一种方案,就是手动去 nodejs.org 查询具体的每个版本。

安装 node

1
2
3
4
nvm install v12.16.1  # 直接输入版本号进行安装
nvm install 12.16.1 # 可以忽略v标记
nvm install 12 # 输入主版本号也可以安装
nvm install --lts # 安装最新的 LTS 版本

切换 node 版本

1
2
3
nvm use v12.16.1     # 直接输入版本号进行切换
nvm use 12 # 输入主版本好也可以切换
nvm use --lts # 使用最新的 LTS 版本

查询 node 安装位置

1
2
nvm which current   # 查询当前版本安装位置
nvm witch 12 # 同样支持简写

移除已经安装的 node 版本

不可以移除当前使用中的版本。

1
nvm uninstall 11    # 同上,可以使用简写

使用指定版本 node 运行程序

1
2
nvm run 6.10.3 app.js # 用 6.10.3 执行 app.js
nvm exec 4.8.3 node app.js # 用 4.8.3 的环境执行 `node app.js`

我认为 nvm runnvm exec 的精简命令。run 后面一定接的是 node 命令。即:

1
2
3
nvm exec 12.16.0 node main.js
# 可以精简为
nvm run 12.16.0 main.js

nvm exec 没用了吗?当然不是,比如,用 12.16.0 的环境,执行 npm 命令:

1
nvm exec 12.16.0 npm install

给 node 版本起别名

比如我安装了 node v11.15.0,用于一个项目的测试任务。我想给这个版本起名为 test,则可以:

1
nvm alias test 11 # 版本号这里我喜欢简写

查询现在有哪些别名,可以使用

1
nvm alias # 会返回所有带有别名的列表。和 nvm ls 类似,就是没有当前安装的版本列表而已。

之后需要切换版本,可以使用:

1
nvm use test # 其中 test 是别名,代表了 11.15.0 版本

小结

这次尝试使用了 nvm 后,发现再也离不开了。主要表现在三个方面。

更容易安装 node

如果是 windows 或者 MacOS 还好,官方有提供安装包,下载双击即可。但是如果是 Linux 就比较麻烦了。

比如 Ubuntu,官方的 apt 安装版本比较老,每次就需要手动安装。下载、解压、放到合理的目录,最后做好软连接。实在是繁琐。

MacOS / Linux 环境,如果网络可以的话(需要访问 github),使用 nvm,安装可以归纳为:

  1. 下载 nvm:

    1
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
  2. 配置环境变量(这步估计是最复杂的)

  3. 安装最新稳定版 node: nvm install --lts

支持多版本 node 共存

不用 nvm,应该很难解决多版本共享的问题。而实际却有这种需求。尤其对于我现在手上的老项目,升级依赖不现实,只能用更低版本的 node,方便快捷。

更方便升级

由于支持多版本 node 共存,想升级也是易如反掌。想升级时候,只需要安装一个最新版本即可。老版本课保留可删除。

不过这样有一个缺陷:我看通过 npm install xxx -g 全局安装的工具,是直接安装到当前版本的目录下的。例如 ~/.nvm/versions/node/v12.16.1/lib/node_modules。切换版本后,该工具就失效了。这么做应该是为了防止你安装工具不支持其他版本而考虑的吧。

所以如果是 v12.16.0 升级到 v12.16.1,安装的全局工具就消失了。即便工具可以支持升级后的版本也不行。

–END–