管理 node 版本,选择 nvm 还是 n?

451 查看

管理 node 版本,选择 nvm 还是 n?

很多同学在选择 node 的版本管理工具时,可能第一时间就直接使用了 nvm,一般不会再去调研另一个工具 n,更没有闲情去了解这两者的特性和差异。毕竟工具能用就行,没必要搞清其运作机制。

是的,我也不例外,然而直到有一天……


引子

我本机安装着 nvm,而 node 本来一直运行在 0.x 的老版本上。后来为了跑 ES6,我将 node 切换到 4.x 的版本,并且把老版本给删掉了。

然后我就碰到了两个问题。一是 WebStorm 报错说找不到 node 解释器了。我只好去设置里面重新设置一番解释器的路径:

WebStorm 的 node 设置

在我的记忆中,WebStorm 默认不需要设置 node 路径,它会去找 /usr/local/bin,即通常的 node 命令位置。而一旦使用 nvm 来安装和管理 node,甚至频繁切换的话,我们就得 手动地 指定 node 路径。

而且是如此硬编码的路径(硬编码了版本号),真不优雅……

第二个问题是,我曾经在全局安装的各种 node 模块们全都需要重新安装,因为全局模块被安装在每个 node 版本自己的沙箱中,因此它们和老版本的 node 一起被埋葬了。

事实上,这就是 nvm 的特性,然而喜不喜欢它则是另一回事儿了。

不管如何,由于发生了这些个问题,我决定稍微深入了解一下情况。

nvm 和 n

在 node 的版本管理工具中,nvm 自然声名远扬,然而我们也不能忘了来自 TJ 的 n。这两种,是目前最主流的方案。

关于这两个工具如何安装和使用,这里不再赘言,请见它们各自的主页:

接下来我们着重关注一下 nvm 和 n 的运作机制和特性。

n

n 是一个需要全局安装的 npm package。

这意味着,我们在使用 n 管理 node 版本前,首先需要一个 node 环境。我们或者用 Homebrew 来安装一个 node,或者从官网下载 pkg 来安装,总之我们得先自己装一个 node —— n 本身是没法给你装的。

然后我们可以使用 n 来安装不同版本的 node。

在安装的时候,n 会先将指定版本的 node 存储下来,然后将其复制到我们熟知的路径/usr/local/bin,非常简单明了。当然由于 n 会操作到非用户目录,所以需要加 sudo 来执行命令。

所以这样看来,n 在其实现上是一个非常易理解的方案。

nvm

我们再来看 nvm。不同于 n,nvm 不是一个 npm package,而是一个独立软件包。这意味着我们需要单独使用它的安装逻辑:

或者使用 Homebrew 来安装。安装完后,还需要修改一下 shell 配置(~/.zshrc or whatever),具体参见官方文档。

然后我们可以使用 nvm 来安装不同版本的 node。

在安装的时候,nvm 将不同的 node 版本存储到 ~/.nvm/<version>/ 下,然后修改$PATH,将指定版本的 node 路径加入,这样我们调用的 node 命令即是使用指定版本的 node。

nvm 显然比 n 要复杂一些,但是另一方面,由于它是一个独立软件包,因此它和 node 之间的关系看上去更合乎逻辑:nvm 不依赖 node 环境,是 node 依赖 nvm;而不像 n 那样产生类似循环依赖的问题。

如何选择?

这样看下来,nvm 和 n 的差异还是比较大的,具体体现在:

  • 安装简易度。nvm 安装起来显然是要麻烦不少;n 这种安装方式更符合 node 的惯性思维。见仁见智吧。
  • 系统支持。注意, nvm 不支持 Windows
  • 对全局模块的管理。n 对全局模块毫无作为,因此有可能在切换了 node 版本后发生全局模块执行出错的问题;nvm 的全局模块存在于各自版本的沙箱中,切换版本后需要重新安装,不同版本间也不存在任何冲突。
  • 关于 node 路径。n 是万年不变的 /usr/local/bin;nvm 需要手动指定路径。

所以,如何选择?真心见仁见智了,不过这里可以给出大体的建议:

  1. 如果你使用 Windows,那没得选了,使用 n,或者换一台 Mac。
  2. 如果你会频繁切换 node 版本(比如本地经常测试最新版的特性,同时又要兼顾代码在生产环境的兼容性),那么从全局模块兼容性的角度考虑,只能使用 nvm。
  3. 如果你是一个轻量级的用户,不需要担心兼容性的问题,更关心 node 安装和使用上的体验,那么选择 n。

你如果要问,楼主最终选用了谁?我会说,我选择了更流行的那一个。

n-star
nvm-star

引用

  1. nvm
  2. n
  3. Node.js – NVM vs N

题图:栎树主干产生的众多分支(Oak Tree Branches)。然而我们通常只关心它的叶子节点。

花絮:我之所以选择使用 nvm 而不迁移到 n,这其中的原因是及其复杂的 —— 唔……只是因为我不想再删掉重装一遍。