Node.js包管理工具NPM

1 min read

NPM,一般认为是Node Package Manager的缩写。简单来说,NPM类似Java中的Maven,Python中的pip,Ruby中的Gem等,是一个命令行下的软件,用来安装和管理node模块和管理Node.js项目中的依赖。常见的使用场景如下:

  • 允许用户从NPM服务器下载别人编写的第三方包到本地使用。
  • 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
  • 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

npm不需要单独安装。在安装node.js的时候,会连带一起安装npm。但是,node.js附带的npm可能不是最新版本,最好用下面的命令,更新到最新版本。

安装完毕后的一些简单的指令

npm的配置

npm 拥有很多默认配置。你可以使用这些默认的配置,也可以修改这些默认的配置,甚至可以在环境变量或命令行下修改这些配置。

配置的权重是如下顺序定义的:

  • 命令行,使用—为前缀的参数。比如 —foo bar,设定变量 foo 的值为“bar”。—foo 后不带值的参数,设定 foo 的值为 true 。
  • 环境变量,所有 npm_config_ 为前缀的环境变量。比如 npm_config_foo = bar ,设定变量 foo 为 “bar”。
  • 用户定义。所有的变量存储在 $HOME/.npmrc 文件里的变量。
  • 全局。所有 $PREFIX/etc/npmrc 文件里的变量。$PREFIX 变量可通过 npm prefix -g 获取,一般默认是 /usr/local。

由于npm的源在国外,所以国内用户使用起来各种不方便。最常用的配置是将默认的资源库修改为镜像地址,国内优秀npm镜像:

  • 淘宝npm镜像
    • 搜索地址:http://npm.taobao.org/
    • registry地址:http://registry.npm.taobao.org/
  • cnpmjs镜像
    • 搜索地址:http://cnpmjs.org/
    • registry地址:http://r.cnpmjs.org/

有很多方法来配置npm的registry地址,下面根据不同情境列出几种比较常用的方法。以淘宝npm镜像举例:

临时使用

持久使用

通过cnpm使用

npm init

npm init用来初始化生成一个新的package.json文件。它会向用户提一系列问题,如果你觉得不用修改默认配置,一路回车就可以了。如果使用了-f(代表force)、-y(代表yes),则跳过提问阶段,直接生成一个新的package.json文件。

npm命令运行时会读取当前目录的 package.json 文件和解释这个文件,这个文件基于Packages/1.1规范。在这个文件里你可以定义你的应用名称( name )、应用描述( description )、关键字( keywords )、版本号( version )、应用的配置项( config )、主页( homepage )、作者( author )、资源仓库地址( repository )、bug的提交地址( bugs ),授权方式( licenses )、目录( directories )、应用入口文件( main )、命令行文件( bin )、应用依赖模块( dependencies )、开发环境依赖模块( devDependencies )、运行引擎( engines )和脚本( scripts )等。对于开发者而言,开发和发布模块都依赖于他对这个文件 package.json 所包含的意义的正确理解。我们下面用一个例子来说明:

 

这个例子里我们定义了应用的入口文件( main )为 index ,当其他应用引用了我们的模块 require(‘test’) 时,这个 main 的值 index.js 文件被调用。脚本( scripts )使用hash 表定义了几个不同的命令。script.start 里的定义的 node server.js 会在 npm start 时被调用,同样的 npm test 调用时对应的 scripts.test 里定义的命令被调用。在有些 native 模块需要编译的话,我们可以定义预编译和编译的命令。本例中还定义了应用依赖模块( dependencies )和开发环境依赖模块( devDependencies )。应用依赖模块会在安装时安装到当前模块的 node_modules 目录下。开发环境依赖模块主要时在开发环境中用到的依赖模块,用命令 npm 的命令 install 或 link 加上参数 —dev 安装到当前模块的 node_modules 目录下。

package.json 里的版本号有些是 >= 0.6.7 有些是 1.x.x,这有什么区别?npm 使用于语义化的版本识别来进行版本管理。并不是所有的模块都会提供向后兼容性,有时候某些模块因为某些原因导致不向后兼容。所以我们需要定义一些规则来保证模块能够在某些特定的版本中可用,并且保证能用最新的版本,因为那些版本总是修改了一些 bug 或提升了性能等。

在上面 package.json 的定义里我们确信模块在所有的 Nodejs 0.4及以上和0.5以下版本里都能运行。依赖模块 redis 在所有大于或等于0.6.7的版本上都能运行,依赖模块 ejs 只能确保运行在0.4.2版本里,依赖模块 express 确保能够兼容大于或等于1.0.0并且小于2.0.0。

Package.json 属性说明

  • name – 包名。
  • version – 包的版本号。
  • description – 包的描述。
  • homepage – 包的官网 url 。
  • author – 包的作者姓名。
  • contributors – 包的其他贡献者姓名。
  • dependencies – 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。
  • repository – 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。
  • main – main 字段是一个模块ID,它是一个指向你程序的主要项目。就是说,如果你包的名字叫 express,然后用户安装它,然后require(“express”)。
  • keywords – 关键字

npm set

npm set用来设置环境变量。

上面命令等于为npm init设置了默认值,以后执行npm init的时候,package.json的作者姓名、邮件、主页、许可证字段就会自动写入预设的值。这些信息会存放在用户主目录的~/.npmrc文件,使得用户不用每个项目都输入。如果某个项目有不同的设置,可以针对该项目运行npm config。

上面命令设置加入模块时,package.json将记录模块的确切版本,而不是一个可选的版本范围。

npm install

Node模块采用npm install命令安装。每个模块可以“全局安装”,也可以“本地安装”。“全局安装”指的是将一个模块安装到系统目录中,各个项目都可以调用。一般来说,全局安装只适用于工具模块,比如npm和grunt。“本地安装”指的是将一个模块下载到当前项目的node_modules子目录,然后只有在项目目录之中,才能调用这个模块。

  • 全局安装会把模块安装在 $PREFIX/lib/node_modules下,可通过命令npm root -g查看全局模块的安装目录。json里定义的bin会安装到$PREFIX/bin目录下,如果模块带有man page会安装到 $PREFIX/share/man 目录下。
  • 本地路安装,从当前目录一直查找到根目录/下有没有node_modules目录,有模块安装到这个目录下的node_modules目录里,如果没有找到则把模块安装到当前目录node_modules目录下。josn 定义的bin 会安装到 node_modules/.bin 目录下,man page 则不会安装。

基本用法

npm install也支持直接输入Github代码库地址。

安装之前,npm install会先检查,node_modules目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也是如此。

如果你希望,一个模块不管是否安装过,npm 都要强制重新安装,可以使用-f或–force参数。

如果你希望,所有模块都要强制重新安装,那就删除node_modules目录,重新执行npm install。

安装不同版本

install命令总是安装模块的最新版本,如果要安装模块的特定版本,可以在模块名后面加上@和版本号。

如果使用–save-exact参数,会在package.json文件指定安装模块的确切版本。

install命令可以使用不同参数,指定所安装的模块属于哪一种性质的依赖关系,即出现在packages.json文件的哪一项中。

  • –save:模块名将被添加到dependencies,可以简化为参数-S。
  • –save-dev: 模块名将被添加到devDependencies,可以简化为参数-D。

如果要安装beta版本的模块,需要使用下面的命令。

npm install默认会安装dependencies字段和devDependencies字段中的所有模块,如果使用production参数,可以只安装dependencies字段的模块。

一旦安装了某个模块,就可以在代码中用require命令调用这个模块。

npm link

一般来说,每个项目都会在项目目录内,安装所需的模块文件。也就是说,各个模块是局部安装。但是有时候,我们希望模块是一个符号链接,连到外部文件,这时候就需要用到npm link命令。为了理解npm link,请设想这样一个场景。你开发了一个模块myModule,目录为src/myModule,你自己的项目myProject要用到这个模块,项目目录为src/myProject。每一次,你更新myModule,就要用npm publish命令发布,然后切换到项目目录,使用npm update更新模块。这样显然很不方便,如果我们可以从项目目录建立一个符号链接,直接连到模块目录,就省去了中间步骤,项目可以直接使用最新版的模块。

先在模块目录(src/myModule)下运行npm link命令。

上面的命令会在npm的全局模块目录内(比如/usr/local/lib/node_modules/),生成一个符号链接文件,该文件的名字就是package.json文件中指定的文件名。

然后,切换到你需要放置该模块的项目目录,再次运行npm link命令,并指定模块名。

上面命令等同于生成了本地模块的符号链接。

然后,就可以在你的项目中,加载该模块了。

这样一来,myModule的任何变化,都可以直接在myProject中调用。但是,同时也出现了风险,任何在myProject目录中对myModule的修改,都会反映到模块的源码中。

npm link命令有一个简写形式,显示连接模块的本地目录。

上面的命令等同于下面几条命令。

如果你的项目不再需要该模块,可以在项目目录内使用npm unlink命令,删除符号链接。

一般来说,npm公共模块都安装在系统目录(比如/usr/local/lib/),普通用户没有写入权限,需要用到sudo命令。这不是很方便,我们可以在没有root的情况下,用好npm。

首先在主目录下新建配置文件.npmrc,然后在该文件中将prefix变量定义到主目录下面。

然后在主目录下新建npm子目录。

此后,全局安装的模块都会安装在这个子目录中,npm也会到~/npm/bin目录去寻找命令。因此,npm link就不再需要 root权限了。

最后,将这个路径在.bash_profile文件(或.bashrc文件)中加入PATH变量。

npm publish

npm publish用于将当前模块发布到npmjs.com。执行之前,需要向npmjs.com申请用户名。

$ npm adduser

如果已经注册过,就使用下面的命令登录。

最后,使用npm publish命令发布。

如果当前模块是一个beta版,比如1.3.1-beta.3,那么发布的时候需要使用tag参数。

如果发布私有模块,模块初始化的时候,需要加上scope参数。只有npm的付费用户才能发布私有模块。

其他常用命令

另外使用npm help <command>可查看某条命令的详细帮助,例如npm help install

参考文档:https://docs.npmjs.com/

打赏作者
微信支付标点符 wechat qrcode
支付宝标点符 alipay qrcode

C语言学习:size_t

在学习C语言的时候,遇到了一个新的数据类型size_t,截止目前也没有完全理清这个类似的具体场景及出现的原因。
44 sec read

C语言学习:main()函数的正确写法

C语言虽然是一门古老的语言,但是其标准一直在完善,所以很多以前支持的语法在到当前已经不能在使用了。 C语言的版
41 sec read

Scipy数学函数的Scala实现

最近在推进项目的时候,遇到需要将线下的Python代码转化成线上的集群代码,由于机器代码环境是Scala,所以
4 min read

发表评论

电子邮件地址不会被公开。 必填项已用*标注