为什么你的n(Node版本管理)命令不起作用
发布于 8 年前 作者 ncuzp 17921 次浏览 来自 分享

查看原文

本文目标 Node版本管理工具n的基本原理介绍

环境说明

  • 基于Centos 7
  • Node 0.12.7
  • n 2.1.0
  • vagrant中安装Centos 7

Node编译安装

在Centos中一般需要根据项目的环境安装指定版本的Node, 而现有的yum源版本一般不够全面也不一定找的到所需要的指定版本, 此时就必须自行下载Node源码进行编译安装了, 此处一点需要注意:如果打算后续使用Node的版本管理工具n及不想要安装冗余的Node话, 那么在configure时就需要注意下设置Node安装路径前缀为--prefix=/usr/local而不是其他路径, 这样安装完成后指定的Node版本就安装到了/usr/local下面(当然后续还需要使用n命令重新安装该版本因为当前版本不在/usr/local/n/versions/node目录下面,或者一开始即可将Node安装到/usr/local/n/versions/node/[version](版本号)路径下面该种方法最优, 本文就使用第一种方法介绍), 该路径会出现以下四个文件夹: Node目录 稍后解释为什么需要这么安装? 当前安装完成后需要设置环境变量, 永久性全局修改的方式如下(其它方式请自行search):

export NODE_HOME=/usr/local
export PATH=$NODE_HOME/bin:$PATH
export NODE_PATH=$NODE_HOME/lib/node_modules:$PATH

(最后一项是不同Node版本包路径)

关于Node版本管理工具n

n是tj(Express框架作者)编写的Node版本管理工具, 其使用linux中的bash shell编写。默认情况下当使用$npm install n -g安装时会将n安装到/usr/local下面, /usr/local/n下面只有一个versions文件夹, 其目录内容如下: n-versions目录 其中包含io/node/两个目录分别用来存放不同的io和Node版本, 其中node的目录结构如下: n-versions目录 可以看到里面包含了四个文件夹也即上述Node编译安装所展示动四个文件夹, 接下来简单阐述下当执行n [node-version]([node-version])命令时其工作过程. 首先, 关于该过程可参考n原文件处的install和active函数. 执行n命令切换版本后大致经过如下步骤:

  • 检测输入版本的有效性
  • 查找/usr/local/n/versions/下面是否已有指定的版本
  • 如果有则执行active函数
  • 如果没有则运行$GET(curl or wget)命令到Node源或者io源下载指定版本并解压到当前目录

active函数的源码如下:

#!/usr/bin/env bash

...

activate() {
  local version=$1
  check_current_version
  if test "$version" != "$active"; then
    local dir=$BASE_VERSIONS_DIR/$version
    for subdir in bin lib include share; do
      if test -L "$N_PREFIX/$subdir"; then
        find "$dir/$subdir" -mindepth 1 -maxdepth 1 -exec cp -fR "{}" "$N_PREFIX/$subdir" \;
      else
        cp -fR "$dir/$subdir" $N_PREFIX
      fi
    done
    disable_pax_mprotect "$N_PREFIX/bin/node"
  fi
}

其执行过程大概是:

  • 检测当前Node版本是否为即将要切换的版本
  • 如果是则不做任何操作,如果不是则循环遍历/usr/local/n/versions/node/[version](Node版本号)/目录
  • 依次将bin lib include share目录复制到/usr/local目录下面 (此处有一点需要注意, 这里对当前的子目录是否为一个链接进行了不同的处理)

以上大致就是n切换Node版本的工作过程, 如果需要了解更详细的信息可参考GitHub-n, 此处也就解释了为什么一开始需要将Node安装到Centos系统的/usr/local下面了, 首先是因为设置了Node的环境变量, 其次n每次只是简单的将Node指定版本下面的四个目录复制到/usr/local下面, 因此如果Node最开始安装的路径与n复制的Node文件的路径不在一个目录那么无论n怎么切换版本, 执行Node命令时系统找的路径始终不在/usr/local下面自然也就找不到指定版本的Node了。

回到顶部