Pages

Friday, 20 January 2017

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

 安装nvm,参见http://briteming.blogspot.com/2014/01/node-version-manager-nvm.html

很多同学在选择 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。





npm install -g n
这意味着,我们在使用 n 管理 node 版本前,首先需要一个 node 环境。我们或者用 Homebrew 来安装一个 node,或者从官网下载 pkg 来安装,总之我们得先自己装一个 node —— n 本身是没法给你装的。
然后我们可以使用 n 来安装不同版本的 node。
在安装的时候,n 会先将指定版本的 node 存储下来,然后将其复制到我们熟知的路径 /usr/local/bin,非常简单明了。当然由于 n 会操作到非用户目录,所以需要加 sudo 来执行命令。
所以这样看来,n 在其实现上是一个非常易理解的方案。

nvm

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





curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh | bash
或者使用 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。
你如果要问,楼主最终选用了谁?我会说,我选择了更流行的那一个.

from http://taobaofed.org/blog/2015/11/17/nvm-or-n/
(我更愿意使用nvm)
----------------------------

Node.js – `NVM` vs `N`


I recently started doing an online course on “MEAN” applications for fun. If you’re not familiar, MEAN stands for Mongo, Express, Angular, Node. It’s pretty neat to see the kinds of things that you can throw together. I still don’t think I’d write something for production that uses Node.js, but other people have had good experience with it.
While doing my learning, the course recommended not to just install node, but to install it with nvm, n or something similar. I could guess by the name that they’re similar to rvm and things similar to rvm (which I finally got around to learning about), but that was about it.
I wanted to know the differences between them, and was hoping someone else had already done the work, but unfortunately googling “nvm vs n” didn’t yield the best results. The most useful article I could find was this. Unfortunately, it was only partially informative – it taught me more than I knew before, but I was interested in learning some of the finer details. So I thought it warranted playing with them both.
Both N and NVM are just node.js version managers. That’s it. They won’t magically write your projects for you, but they can help you keep things separated when working on multiple projects, which as we all know happens too often.

N


Github link
N is pretty easy to get installed. First you install node.js, then you run  npm install -g n. The irony is not lost on me that you must first install node in order to install the node manager.
The way N works is it installs the n executable to your path. You then use it to install different versions of node.
and you can switch between them just by running  n and picking the version you want from a list.
Here’s where things get tricky.
N works by storing different versions of node in some directory somewhere and when you switch versions, it will copy it to  /usr/local/bin. This is great for simplicity. It’s easy to install, easy to use, the only problem is that you basically have to  sudo every command.
Also, because it’s just swapping out different versions of node from your install directory, it doesn’t have a good way of handling those pesky npm install -g packages.
If you install something globally, then switch out versions of node, you may be left confused as to why things aren’t working.

NVM


Github link
NVM works a little differently. To install it, run
It might not install itself quite right in os x, so you may need to check to make sure it put this in your ~/.bash_profile
on my machine, it put that in  .bashrc even though that file doesn’t work in os x.
Then you need to restart your terminal to get your path working, and you can start installing node versions like this
When NVM installs versions of node, it works a lot more like RVM. NVM installs node to ~/.nvm/<version>/. Then it modifies your PATH to include the proper bin directory.
This does make things slightly more complicated than it does with N, but it does grant one benefit. When installing global packages, they too get installed under  ~/.nvm/<version>. So if you’re working on two different projects and each of them needs a version of karma-cli, you can be sure you’re using the proper version. Now node is still fairly new, so there aren’t that many versions of the different packages that tend to be installed globally, but give it time, you never know what will happen.
The only thing that NVM is missing in my mind is an equivalent to RVM’s gemsets.

from https://encyclopediaofdaniel.com/blog/node-js-nvm-vs-n/
-------------

使用 nvm 一键切换多版本 node

 有时候不同项目需要切换不同版本的 node。

在同一个机器上切换过 node (特定是 windows 环境)遇到过各种各样莫名其妙的问题,就知道能无痛一键切换 node 是多么开心的事情了。
尝试过很多工具,最后总结出最理想的就是 nvm 这货了。
以下几个步骤亲测在 mac/linux 上都很好用,如果是 windows 的话,也有 nvm-windows 可以选择。
nvm 官方地址:https://github.com/creationix/nvm
nvm-windows 官方地址:https://github.com/coreybutler/nvm-windows
简单总结下步骤:
下载 nvm
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash
启动 nvm$ . ~/.nvm/nvm.sh
安装特定版本的 node$ nvm install 4.4.2
使用特定版本的 node$ nvm use 4.2.4
现在就可以看到 node 版本已经切换
$ node -v
$ npm -v
注意这种切换只在当前 shell 环境有效,也就是下次重新打开 shell 的话,就退回默认的 node 版本了。
重启 shell 后需要再重启 nvm 切换 node 版本。
这样虽然麻烦了点,但是非常灵活。
觉得重启麻烦,可以把以下配置加到 ~/.bashrc、 ~/.profile 或 ~/.zshrc 文件中:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
注意:
文章里的 nvm 说的不是 https://www.npmjs.com/package/nvm
而是 https://github.com/creationix/nvm
虽然都叫 nvm 但不是同一个东西!
nvm 不使用 npm 安装,有自己的安装和配置方式,有自己独立的目录管理依赖,安装繁琐一些,但使用起来感觉是更为灵活。
nvm 和 n 的对比,可以看看这篇文章:http://taobaofed.org/blog/2015/11/17/nvm-or-n/
----------------------

nvm

安装nvm两种方式:
curl https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh
wget -qO- https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh
使用nvm安装其他版本的Node(如安装4.6.1版本):
nvm install 4.6.1
切换到某个版本的Node(如切换到4.6.1版本):
nvm use 4.6.1
查看已经安装的Node版本:
nvm ls
查看当前正在使用的Node版本:
nvm current
以指定版本执行脚本(如指定4.6.1版本来执行test.js):
nvm run 4.6.1 test.js
移除某个版本(如移除4.6.1版本):
n uninstall 4.6.1
卸载nvm
rm -rf ~/.nvm
安装nvm之后会clone到~/.nvm,然后会在~/.bash_profile~/.zshrc~/.profile末尾添加source.
------------

使用nodejs的版本管理器nvm

nvm 是 Tim Caswell 开发的一款 Mac/linux系统中使用的通过命令方式管理多版本 Node.js 的软件。
nvm 软件的相关介绍,可以访问 该项目的github主页:https://github.com/creationix/nvm
如果是 Windows 系统的,可以参考 nvm-windows的github主页

通过 nvm 安装 Node.js

1. 安装 nvm 版本管理器

打开“终端”窗口,输入如下命令,在线安装 nvm 软件:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh|bash
值得注意的是:
想要成功的安装 nvm,Mac 系统下必须要先安装 Xcode 软件。
由于 Xcode 软件大概在 4.3GB 左右,如果不想安装 Xcode 软件,又想可以成功安装 nvm 的话,可以按照以下方式操作。
  • 打开“终端”窗口,并输入以下命令。
xcode-select --install
  • 执行上述命令后,会自动弹出软件安装的提示窗口。点击【Install】按钮,进行安装。(这个软件大概 130MB 左右)
通过上述步骤可以替代安装 Xcode 软件,以保证成功安装 nvm 软件。
如果是 Windows 系统的话,可以从 https://github.com/coreybutler/nvm-windows/releases 下载安装文件,安装即可。
安装成功之后,在“终端”窗口,输入 nvm 命令,验证 nvm 是否安装成功。

2. 使用 nvm 安装 Node.js

以下操作都是在“终端”窗口中完成。

1) 安装指定版本的 Node.js

我们可以通过以下 nvm 命令在线安装指定版本的 Node.js。
nvm install [nodeversion]
例如,需要安装 v6.9.1 版本的 Node.js,那可以通过以下命令完成。
nvm install v6.9.1

2) 指定当前使用的 Node.js 版本

通过 nvm 可以同时安装多个版本的 Node.js,我们可以指定某个版本的使用。
nvm use [nodeversion]
例如,需要使用 v6.9.1 版本的 Node.js,那可以通过以下命令完成。
nvm use v6.9.1

3) 查看当前安装的 Node.js 版本列表

由于通过 nvm 可以安装多个 Node.js,版本多了不好管理。我们还可以随时查看当前安装了哪些 Node.js 的版本。
nvm ls

4) nvm 的其他命令

nvm 还提供一些命令,方便我们平时管理 Node.js 的版本。
  • nvm uninstall [nodeversion]: 表示删除指定版本的 Node.js,用法类似于 install 命令。
  • nvm current: 表示显示当前使用的 Node.js 版本。
  • nvm reinstall-packages [npmversion]: 表示在当前的 Node.js 版本下,安装指定版本的 npm 包管理器。

3. 安装多个版本 Node.js 的意义

自从 Node.js 基金会成立,Node.js 就有一个发布计划,就是同时存在两个发布版本:稳定版和试验版。
在 Node.js 中,带有长期支持(LTS)的稳定版是以偶数开始(4,6,8...),而试验版是从奇数开始(5, 7...)。我们推荐在生产环境中用 LTS 版本,而用试验版尝试新东西。

4. 国内环境的问题

由于国内在一些情况下有些特殊。Node.js 官方镜像源又在国外,经常通过 nvm 安装 Node.js 时,速度比较慢,或者没有响应。
根据这种情况,nvm 允许更改安装的镜像源,我们可以将镜像源切换到国内的淘宝提供的镜像源。

1) Mac 系统的 nvm 软件切换镜像源

根据 nvm 官方提供的帮助文档,我们可以通过以下命令进行切换。
export NVM_NODEJS_ORG_MIRROR="http://npm.taobao.org/mirrors/node"
http://npm.taobao.org/mirrors/node淘宝NPM镜像 提供的国内 Node.js 的安装镜像源。
值得注意的是:
种方式,在每次重启“终端”会失效。也就是说,每次打开“终端”都需要执行上述命令。
如果并不想每次打开“终端”,都需要重新设置 NVM_NODEJS_ORG_MIRROR 环境变量。
  • 如果“终端”使用的是 bash Shell 的话(一般是 Mac 系统终端默认)向 ~/.bash_profile 文件(如果没有,会自动创建)增加以下内容:
# nvm
export NVM_NODEJS_ORG_MIRROR="http://npm.taobao.org/mirrors/node"
source ~/.nvm/nvm.sh
  • 如果“终端”使用的是 zsh Shell 的话(一般是 Mac 开发人员使用)向 ~/.zshrc 文件(如果没有,会自动创建)增加以下内容:
# nvm
export NVM_NODEJS_ORG_MIRROR="http://npm.taobao.org/mirrors/node"
source ~/.nvm/nvm.sh

2) Windows 系统的 nvm-windows 软件切换镜像源

我们可以找到 nvm-windows 软件的安装目录中的 settings.txt 文件,增加以下内容:
node_mirror=http://npm.taobao.org/mirrors/node/
添加成功之后,需要重新打开命令行窗口.
---------------------------

在mac上,安装nvm

运行:brew install nvm
会显示:

Updating Homebrew...
^C
==> Downloading https://github.com/creationix/nvm/archive/v0.34.0.tar.gz
==> Downloading from https://codeload.github.com/nvm-sh/nvm/tar.gz/v0.34.0
######################################################################## 100.0%
==> Caveats
Please note that upstream has asked us to make explicit managing
nvm via Homebrew is unsupported by them and you should check any
problems against the standard nvm install method prior to reporting.

You should create NVM's working directory if it doesn't exist:

  mkdir ~/.nvm

Add the following to ~/.bash_profile or your desired shell
configuration file:

  export NVM_DIR="$HOME/.nvm"
  [ -s "/usr/local/opt/nvm/nvm.sh" ] && . "/usr/local/opt/nvm/nvm.sh"  # This loads nvm
  [ -s "/usr/local/opt/nvm/etc/bash_completion" ] && . "/usr/local/opt/nvm/etc/bash_completion"  # This loads nvm bash_completion

You can set $NVM_DIR to any location, but leaving it unchanged from
/usr/local/opt/nvm will destroy any nvm-installed Node installations
upon upgrade/reinstall.

Type `nvm help` for further information.

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/nvm/0.34.0: 7 files, 141.7KB, built in 28 seconds
---------------------------------------------------------------------------------------------


n – Interactively Manage Your Node.js Versions

Join the chat at https://gitter.im/tj/n npm npm npm npm
Node.js version management: no subshells, no profile setup, no convoluted API, just simple.

Want to install Node nightly releases? Try this!

(Unfortunately n is not supported on Windows yet. If you're able to make it work, send in a pull request!)

Installation

Since you probably already have node, the easiest way to install n is through npm:
$ npm install -g n
Alternatively, you can clone this repo and
$ make install
to install n to bin/n of the directory specified in the environment variable $PREFIX, which defaults to /usr/local (note that you will likely need to use sudo). To install n in a custom location (such as $CUSTOM_LOCATION/bin/n), run PREFIX=$CUSTOM_LOCATION make install.
Once installed, n installs node versions to subdirectory n/versions of the directory specified in environment variable N_PREFIX, which defaults to /usr/local; the active node/iojs version is installed directly in N_PREFIX. To change the default to, say, $HOME, prefix later calls to n with N_PREFIX=$HOME or add export N_PREFIX=$HOME to your shell initialization file.
Additionally, consider third-party installer n-install, which allows installation directly from GitHub; for instance,
curl -L https://git.io/n-install | bash
sets both PREFIX and N_PREFIX to $HOME/n, installs n to $HOME/n/bin, modifies the initialization files of supported shells to export N_PREFIX and add $HOME/n/bin to the PATH, and installs the latest stable node version.
As a result, both n itself and all node versions it manages are hosted inside a single, optionally configurable directory, which you can later remove with the included n-uninstall script. n-update updates n itself to the latest version. See the n-install repo for more details.

Installing/Activating Versions

Simply execute n <version> to install a version of node. If <version> has already been installed (via n), n will activate that version.
$ n 0.8.14
$ n 0.8.17
$ n 0.9.6
Execute n on its own to view your currently installed versions. Use the up and down arrow keys to navigate and press enter to select. Use q or ^C (control + C) to exit the selection screen. If you like vim key bindings during the selection of node versions, you can use j and k to navigate up or down without using arrows.
$ n

  0.8.14
ο 0.8.17
  0.9.6
Use or install the latest official release:
$ n latest
Use or install the latest LTS official release:
$ n lts

Removing Versions

Remove some versions:
$ n rm 0.9.4 v0.10.0
Alternatively, you can use - in lieu of rm:
$ n - 0.9.4
Removing all versions except the current version:
$ n prune

Binary Usage

When running multiple versions of node, we can target them directly by asking n for the binary path:
$ n bin 0.9.4
/usr/local/n/versions/0.9.4/bin/node
Or by using a specific version through n's use sub-command:
$ n use 0.9.4 some.js
Flags also work here:
$ n as 0.9.4 --debug some.js

Working with npm

After switching Node.js versions using nnpm may not work properly. This should fix it (thanks @mikemoser!):
$ curl -0 -L https://npmjs.com/install.sh | sudo sh
sudo may not be required depending on your system configuration.

Usage

Output can also be obtained from n --help.
Usage: n [options/env] [COMMAND] [args]

Environments:
 n [COMMAND] [args]            Uses default env (node)
 n io [COMMAND]                Sets env as io

Commands:

  n                              Output versions installed
  n latest                       Install or activate the latest node release
  n -a x86 latest                As above but force 32 bit architecture
  n lts                          Install or activate the latest LTS node release
  n <version>                    Install node <version>
  n use <version> [args ...]     Execute node <version> with [args ...]
  n bin <version>                Output bin path for <version>
  n rm <version ...>             Remove the given version(s)
  n prune                        Remove all versions except the current version
  n --latest                     Output the latest node version available
  n --lts                        Output the latest LTS node version available
  n ls                           Output the versions of node available

(iojs):

  n io latest                    Install or activate the latest iojs release
  n io -a x86 latest             As above but force 32 bit architecture
  n io <version>                 Install iojs <version>
  n io use <version> [args ...]  Execute iojs <version> with [args ...]
  n io bin <version>             Output bin path for <version>
  n io rm <version ...>          Remove the given version(s)
  n io --latest                  Output the latest iojs version available
  n io ls                        Output the versions of iojs available

Options:

  -V, --version   Output current version of n
  -h, --help      Display help information
  -q, --quiet     Disable curl output (if available)
  -d, --download  Download only
  -a, --arch      Override system architecture

Aliases:

  which   bin
  use     as
  list    ls
  -       rm
  stable  lts

Custom source

If you would like to use a project other than the official Node.js or io.js projects, you can use the special n project [command] which allows you to control the behavior of n using environment variables.
For example, to grab the latest io.js version but name it "foo" instead,
  PROJECT_NAME="foo" PROJECT_URL="https://iojs.org/dist/" n project latest
Required Variables:
  • PROJECT_NAME: The name the project will be stored under
  • PROJECT_URL: The location to download the project from. Note, this must follow the same format as the io.js/Node.js repos
Optional Variables:
  • HTTP_USER: The username if the PROJECT_URL is protected by basic authentication
  • HTTP_PASSWORD: The password if the PROJECT_URL is protected by basic authentication
  • PROJECT_VERSION_CHECK: Many custom projects keep the same version number as the Node.js release they are based on, and maintain their own separate version in process. This allows you to define a JavaScript variable that will be used to check for the version of the process, for example: process.versions.node

Custom architecture

By default n picks the binaries matching your system architecture, e.g. n will download 64 bit binaries for a 64 bit system. You can override this by using the -a or --arch option.
Download and use latest 32 bit version of node:
$ n --arch x86 latest
Download and use latest 32 bit version of iojs:
$ n io --arch x86 latest
Download and use 64 bit LTS version of node for older Mac Intel Core 2 Duo systems (x86 image is no longer available but x64 runs fine):
$ n --arch x64 lts

Additional Details

n installs versions to /usr/local/n/versions by default. Here, it can see what versions are currently installed and activate previously installed versions accordingly when n <version> is invoked again.
Activated versions are then installed to the prefix /usr/local, which may be altered via the N_PREFIX environment variable.
To alter where n operates, simply export N_PREFIX.
n does not work on Windows at the moment. Pull Requests are appreciated.
If you are searching for the latest version of n below 2.x.x, check out the branch 1.x.x.

Core Team

Please Read Contributing Docs

from https://github.com/tj/n
-------

brew install n
brew link --overwrite n
n -h
sudo n 8.11.1 (安装8.11.1版)

(运行:n 8.11.1
显示:
  installing : node-v8.11.1
       mkdir : /usr/local/n/versions/node/8.11.1
       fetch : https://nodejs.org/dist/v8.11.1/node-v8.11.1-darwin-x64.tar.gz