NPM

npm 是什么?

NPM 是随同 NodeJS 一起安装的包管理工具(这里的包,其实就是指的模块既Module),能够解决 Nodejs 的构建和部署的问题,常见的使用场景有以下几种:

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

补充,就类似于 java 工程项目中的 maven,用来管理 java 项目的包依赖以及相互的构建关系;只是 NPM 是用来管理 Nodejs 的包依赖关系和构建关系的。

npm 版本查看

1
2
>> npm -v
3.10.3

npm 升级

  1. linux

    1
    2
    3
    >> sudo npm install npm -g
    /usr/local/bin/npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
    npm@3.10.3 /usr/local/lib/node_modules/npm
  2. windows

    1
    >> npm install npm -g
  3. 使用淘宝镜像

    1
    >> cnpm install npm -g

npm 安装模块

安装指定模块

标准命令格式,

1
>> $ npm install <Module Name>

例子,安装 express 模块

1
>> $ npm install express

安装好之后,express 包就放在了工程目录下的 node_modules 目录中,因此在代码中只需要通过 require(‘express’) 的方式就好,无需指定第三方包路径。

1
var express = require('express');

全局安装与局部(本地)安装

1
2
npm install express      # 局部安装
npm install express -g # 全局安装

局部安装,

  1. 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。
  2. 可以通过 require() 来引入本地安装的包。

全局安装,

  1. 将安装包放在 /usr/local 下或者你 node 的安装目录。
  2. 可以直接在命令行里使用。

局部和全局同时安装,两种方法

  1. 分别使用局部安装和全局安装
  2. 或者使用npm link
    TODO: 未验证

查看所有全局安装的模块

1
>> npm ls -g

查看所有局部(本地)安装的模块

1
>> npm ls

使用 package.json

package.json 是什么

补充,package.json 就相当于 maven 的 pom.xml,用来管理模块以及模块之间的相互关系以及构建行为的。

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

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"name": "test",
"version": "0.1.0",
"description": "A testing package",
"author": "A messed author <messed@example.com>",
"dependencies": {
"express": "1.x.x",
"ejs": "0.4.2",
"redis": ">= 0.6.7"
},
"devDependencies": {
"vows": "0.5.x"
},
"main": "index",
"bin": {
"test": "./bin/test.js"
},
"scripts": {
"start": "node server.js",
"test": "vows test/*.js",
"preinstall": "./configure",
"install": "make && make install"
},
"engines": {
"node": "0.4.x"
}
}

  1. 属性 name
    其它模块可以通过名称test来引用该模块,require('test')

  2. 属性 main,定义入口文件

    1
    "main": "index"

    通过main指定入口文件,这里是index.js,当通过require('test')引用该模块的时候,入口文件index.js将会被执行。

  3. 属性 scripts

    • script.start
      这里定义的定 node server.js 会在npm start时被调用
    • script.test
      通过,会在npm test的时候被调用
    • preinstall/install
      在有些 native 模块需要编译的话,我们可以定义预编译和编译的命令
  4. dependencies
    应用依赖模块,应用依赖模块会在安装时安装到当前模块的 node_modules 目录下;(是指的运行npm install的时候吗?); 这不就是 maven 的 dependencies 吗?

  5. devDependencies
    开发环境依赖模块,主要是在开发环境中用到的依赖模块,用命令 npm 的命令 install 或 link 加上参数 —dev 安装到当前模块的 node_modules 目录下。

dependencies 和 devDependencies 之间的异同是什么?
devDependencies 可以看做是 maven 中的 <scope>test</scope> 这样的依赖关系,只会在测试的时候用到。而 dependencies 相当于是发布环境中所依赖的包。

npm 安装模块

npm install

  1. 安装 package.json 配置好的模块

    1
    $ npm install

    模块将会自动的安装到本地 ./node_modules 目录当中;

  2. 安装 package.json “没有”配置好的模块,比如

    1. 未指定版本

      1
      $ npm install express

      上面的方式会安装 express 的最新版本到 ./node_modules 中并且更新 package.json

    2. 指定版本
      1
      $ npm install express@4.15.2

npm install –save-dev

1
>> npm install grunt --save-dev
  1. 安装 grunt 模块,并将模块安装到 ./node_modules 目录中。
  2. 并且将 grunt 添加到package.json

npm 卸载模块

1
>> npm uninstall express

npm 更新模块

1
>> npm update express

npm 搜索模块

1
>> npm search express

npm 检查模块的版本

npm list 用来检查 local 的安装包的版本,使用 npm list -g 可以用来查询全局的按转包的版本;

  1. 检查本地所有模块的版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ npm list
    passport-local-demo@0.0.0 /Users/mac/workspace/javascript/nodejs/express-example/passport-local-demo
    ├─┬ body-parser@1.18.2
    │ ├── bytes@3.0.0
    │ ├── content-type@1.0.4
    │ ├── debug@2.6.9 deduped
    │ ├── depd@1.1.2
    │ ├─┬ http-errors@1.6.2
    ...
  2. 检查本地某个模块的版本

    1
    2
    3
    $ npm list express
    passport-local-demo@0.0.0 /Users/mac/workspace/javascript/nodejs/express-example/passport-local-demo
    └── express@4.15.5

npm 创建模块

什么是模块

用 Nodejs 所构建的一个 Module,必须在模块的根路径上包含package.json以用来描述该模块的基本信息,模块的依赖关系等。

创建过程

npm init

在模块根路径上用控制台执行命令$ npm init,然后根据提示依次输入必要的信息,最后生成package.json;或者直接通过$ npm init -y直接生成package.json文件并跳过提示。

npm adduser

在 npm 资源仓库中注册用户,类似于docker hub,专门用来管理 nodejs 模块的。

1
2
3
4
$ npm adduser
Username: mcmohd
Password:
Email: (this IS public) mcmohd@gmail.com

npm publish

最后,通过npm publish发布你的模块即可。

淘宝 NPM 镜像

淘宝 NPM 镜像是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。你可以使用淘宝定制的cnpm(gzip 压缩支持) 命令行工具代替默认的npm:

1
$ npm install -g cnpm --registry=https://registry.npm.taobao.org

这样就可以使用cnpm命令来安装模块了:

1
$ cnpm install [name]

更多信息可以查阅:http://npm.taobao.org/。

搭建 NPM 私有仓库

https://segmentfault.com/a/1190000000368906

故障排除

npm WARN deprecated

在执行 npm install 构建命令的时候,往往会出现某些依赖的组件版本过低而导致 install 失败,比如

1
2
3
4
5
6
7
8
npm WARN deprecated graceful-fs@2.0.3: graceful-fs v3.0.0 and before will fail on node releases >= v7.0. Please update to graceful-fs@^4.0.0 as soon as possible. Use 'npm ls graceful-fs' to find it in the tree.
npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated CSSselect@0.4.1: the module is now available as 'css-select'
npm WARN deprecated minimatch@0.2.14: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated node-uuid@1.4.7: use uuid module instead
npm WARN deprecated tough-cookie@0.9.15: ReDoS vulnerability parsing Set-Cookie https://nodesecurity.io/advisories/130
npm WARN deprecated npmconf@2.1.2: this package has been reintegrated into npm and is now out of date with respect to npm

修正的办法,

1
$ npm install minimatch@"3.0.2"

References

如何使用NPM来管理你的Node.js依赖
npm offical site
使用cnpm搭建企业内部私有NPM仓库