runoops.com

NPM 使用介绍

NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:

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

由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了。同样可以通过输入 "npm -v" 来测试是否成功安装。命令如下,出现版本提示表示安装成功:

$ npm -v
6.14.10

如果你安装的是旧版本的 npm,可以很容易得通过 npm 命令来升级,命令如下:

$ sudo npm install npm -g

如果是 Window 系统使用以下命令即可:

npm install npm -g

使用淘宝镜像的命令(临时):

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

淘宝镜像已到期,改成国内镜像(临时):

npm install cnpm -g --registry=https://registry.npmmirror.com

npm永久使用国内镜像:

npm config set registry https://registry.npmmirror.com

查看npm镜像设置:

npm config get registry

如果设置了npm为淘宝镜像,需要恢复为默认源时:

npm config set registry=https://registry.npmjs.org 

使用 npm 命令安装模块

npm 安装 Node.js 模块语法格式如下:

$ npm install <Module Name>

以下实例,我们使用 npm 命令安装常用的 Node.js web框架模块 express:

$ npm install express

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

var express = require('express');

全局安装与本地安装

npm 的包安装分为本地安装(local)、全局安装(global)两种,从敲的命令行来看,差别只是有没有-g而已,比如:

npm install express          # 本地安装
npm install express -g   # 全局安装

如果出现以下错误:

npm err! Error: connect ECONNREFUSED 127.0.0.1:8087 

解决办法为:

$ npm config set proxy null

本地安装

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

全局安装

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

如果你希望具备两者功能,则需要在两个地方安装它或使用 npm link

接下来我们使用全局方式安装 express

$ npm install express -g

安装过程输出如下内容,输出了模块的版本号及安装位置。

cnpm install express -g
Downloading express to C:\Users\Administrator\AppData\Roaming\npm\node_modules\express_tmp
Copying C:\Users\Administrator\AppData\Roaming\npm\node_modules\express_tmp\_express@4.17.1@express to C:\Users\Administrator\AppData\Roaming\npm\node_modules\express
Installing express's dependencies to C:\Users\Administrator\AppData\Roaming\npm\node_modules\express/node_modules
[1/30] cookie-signature@1.0.6 installed at node_modules\_cookie-signature@1.0.6@cookie-signature
[2/30] cookie@0.4.0 installed at node_modules\_cookie@0.4.0@cookie
[3/30] array-flatten@1.1.1 installed at node_modules\_array-flatten@1.1.1@array-flatten
[4/30] encodeurl@~1.0.2 installed at node_modules\_encodeurl@1.0.2@encodeurl
[5/30] content-type@~1.0.4 installed at node_modules\_content-type@1.0.4@content-type
[6/30] depd@~1.1.2 installed at node_modules\_depd@1.1.2@depd
[7/30] escape-html@~1.0.3 installed at node_modules\_escape-html@1.0.3@escape-html
[8/30] etag@~1.8.1 installed at node_modules\_etag@1.8.1@etag
[9/30] on-finished@~2.3.0 existed at node_modules\_on-finished@2.3.0@on-finished
[10/30] fresh@0.5.2 installed at node_modules\_fresh@0.5.2@fresh
[11/30] debug@2.6.9 installed at node_modules\_debug@2.6.9@debug
[12/30] content-disposition@0.5.3 installed at node_modules\_content-disposition@0.5.3@content-disposition
[13/30] methods@~1.1.2 installed at node_modules\_methods@1.1.2@methods
[14/30] merge-descriptors@1.0.1 installed at node_modules\_merge-descriptors@1.0.1@merge-descriptors
[15/30] safe-buffer@5.1.2 existed at node_modules\_safe-buffer@5.1.2@safe-buffer
[16/30] qs@6.7.0 existed at node_modules\_qs@6.7.0@qs
[17/30] path-to-regexp@0.1.7 installed at node_modules\_path-to-regexp@0.1.7@path-to-regexp
[18/30] statuses@~1.5.0 existed at node_modules\_statuses@1.5.0@statuses
[19/30] parseurl@~1.3.3 existed at node_modules\_parseurl@1.3.3@parseurl
[20/30] setprototypeof@1.1.1 existed at node_modules\_setprototypeof@1.1.1@setprototypeof
[21/30] range-parser@~1.2.1 installed at node_modules\_range-parser@1.2.1@range-parser
[22/30] accepts@~1.3.7 installed at node_modules\_accepts@1.3.7@accepts
[23/30] type-is@~1.6.18 existed at node_modules\_type-is@1.6.18@type-is
[24/30] finalhandler@~1.1.2 installed at node_modules\_finalhandler@1.1.2@finalhandler
[25/30] serve-static@1.14.1 installed at node_modules\_serve-static@1.14.1@serve-static
[26/30] body-parser@1.19.0 installed at node_modules\_body-parser@1.19.0@body-parser
[27/30] vary@~1.1.2 installed at node_modules\_vary@1.1.2@vary
[28/30] utils-merge@1.0.1 installed at node_modules\_utils-merge@1.0.1@utils-merge
[29/30] proxy-addr@~2.0.5 installed at node_modules\_proxy-addr@2.0.6@proxy-addr
[30/30] send@0.17.1 installed at node_modules\_send@0.17.1@send
All packages installed (51 packages installed from npm registry, used 1s(network 1s), speed 486.64kB/s, json 48(96.75kB), tarball 494.03kB)

查看安装信息

你可以使用以下命令来查看所有全局安装的模块:

cnpm list -g
D:\ProgramFiles\nodejs
`-- npm@6.14.10
  +-- abbrev@1.1.1
  +-- ansicolors@0.3.2
  +-- ansistyles@0.1.3
  +-- aproba@2.0.0
  +-- archy@1.0.0
  +-- bin-links@1.1.8
......

如果要查看某个模块的版本号,可以使用命令如下:

cnpm list express
D:\PhpStudyV8\WWW\nodejstest
`-- express@4.17.1  -> D:\PhpStudyV8\WWW\nodejstest\node_modules\_express@4.17.1@express

使用 package.json

package.json 位于模块的目录下,用于定义包的属性。接下来让我们来看下 express 包的 package.json 文件,位于 node_modules/express/package.json 内容:

{
  "name": "express",
  "description": "Fast, unopinionated, minimalist web framework",
  "version": "4.17.1",
  "author": "TJ Holowaychuk <tj@vision-media.ca>",
  "contributors": [
    "Aaron Heckmann <aaron.heckmann+github@gmail.com>",
    "Ciaran Jessup <ciaranj@gmail.com>",
    "Douglas Christopher Wilson <doug@somethingdoug.com>",
    "Guillermo Rauch <rauchg@gmail.com>",
    "Jonathan Ong <me@jongleberry.com>",
    "Roman Shtylman <shtylman+expressjs@gmail.com>",
    "Young Jae Sim <hanul@hanul.me>"
  ],
  "license": "MIT",
  "repository": "expressjs/express",
  "homepage": "http://expressjs.com/",
  "keywords": [
    "express",
    "framework",
    "sinatra",
    "web",
    "rest",
    "restful",
    "router",
    "app",
    "api"
  ],
  "dependencies": {
    "accepts": "~1.3.7",
    "array-flatten": "1.1.1",
    "body-parser": "1.19.0",
    "content-disposition": "0.5.3",
    "content-type": "~1.0.4",
    "cookie": "0.4.0",
    "cookie-signature": "1.0.6",
    "debug": "2.6.9",
    "depd": "~1.1.2",
    "encodeurl": "~1.0.2",
    "escape-html": "~1.0.3",
    "etag": "~1.8.1",
    "finalhandler": "~1.1.2",
    "fresh": "0.5.2",
    "merge-descriptors": "1.0.1",
    "methods": "~1.1.2",
    "on-finished": "~2.3.0",
    "parseurl": "~1.3.3",
    "path-to-regexp": "0.1.7",
    "proxy-addr": "~2.0.5",
    "qs": "6.7.0",
    "range-parser": "~1.2.1",
    "safe-buffer": "5.1.2",
    "send": "0.17.1",
    "serve-static": "1.14.1",
    "setprototypeof": "1.1.1",
    "statuses": "~1.5.0",
    "type-is": "~1.6.18",
    "utils-merge": "1.0.1",
    "vary": "~1.1.2"
  },
  "devDependencies": {
    "after": "0.8.2",
    "connect-redis": "3.4.1",
    "cookie-parser": "~1.4.4",
    "cookie-session": "1.3.3",
    "ejs": "2.6.1",
    "eslint": "2.13.1",
    "express-session": "1.16.1",
    "hbs": "4.0.4",
    "istanbul": "0.4.5",
    "marked": "0.6.2",
    "method-override": "3.0.0",
    "mocha": "5.2.0",
    "morgan": "1.9.1",
    "multiparty": "4.2.1",
    "pbkdf2-password": "1.2.1",
    "should": "13.2.3",
    "supertest": "3.3.0",
    "vhost": "~3.0.2"
  },
  "engines": {
    "node": ">= 0.10.0"
  },
  "files": [
    "LICENSE",
    "History.md",
    "Readme.md",
    "index.js",
    "lib/"
  ],
  "scripts": {
    "lint": "eslint .",
    "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/",
    "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/",
    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
    "test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
  },
  "__npminstall_done": "Tue Feb 02 2021 21:36:31 GMT+0800 (中国标准时间)",
  "_from": "express@4.17.1",
  "_resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz"
}

Package.json 属性说明

  • name - 包名。
  • version - 包的版本号。
  • description - 包的描述。
  • homepage - 包的官网 url 。
  • author - 包的作者姓名。
  • contributors - 包的其他贡献者姓名。
  • dependencies - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。
  • repository - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。
  • main - main 字段指定了程序的主入口文件,require('moduleName') 就会加载这个文件。这个字段的默认值是模块根目录下面的 index.js。
  • keywords - 关键字

卸载模块

我们可以使用以下命令来卸载 Node.js 模块。

$ npm uninstall express

卸载后,你可以到 /node_modules/ 目录下查看包是否还存在,或者使用以下命令查看:

$ npm ls

更新模块

我们可以使用以下命令更新模块:

$ npm update express

搜索模块

使用以下来搜索模块:

$ npm search express

创建模块

创建模块,package.json 文件是必不可少的。我们可以使用 NPM 生成 package.json 文件,生成的文件包含了基本的结果:

cnpm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (nodejstest) runoops
version: (1.0.0)
description: Node.js测试模块(runoops.com)
entry point: (index.js)
test command: make test
git repository: https://github.com/liqiang88/nodejsTest.git
keywords: node.js test
author: lcz
license: (ISC)
About to write to D:\PhpStudyV8\WWW\nodejstest\package.json:

{
  "name": "runoops",
  "version": "1.0.0",
......
}
Is this ok? (yes) yes

以上的信息,你需要根据你自己的情况输入。在最后输入 "yes" 后会生成 package.json 文件。

接下来我们可以使用以下命令在 npm 资源库中注册用户(使用邮箱注册):

$ npm adduser
Username: mcmohd
Password:
Email: (this IS public) xxx@gmail.com

接下来我们就用以下命令来发布模块:

$ npm publish

如果你以上的步骤都操作正确,你就可以跟其他模块一样使用 npm 来安装。


版本号

使用NPM下载和发布代码时都会接触到版本号。NPM使用语义版本号来管理代码,这里简单介绍一下。

语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。

  • 如果只是修复bug,需要更新Z位。
  • 如果是新增了功能,但是向下兼容,需要更新Y位。
  • 如果有大变动,向下不兼容,需要更新X位。

版本号有了这个保证后,在申明第三方包依赖时,除了可依赖于一个固定版本号外,还可依赖于某个范围的版本号。例如"argv": "0.0.x"表示依赖于0.0.x系列的最新版argv。


NPM 常用命令

除了本章介绍的部分外,NPM还提供了很多功能,package.json里也有很多其它有用的字段。

除了可以在npmjs.org/doc/查看官方文档外,这里再介绍一些NPM常用命令。

NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。

  • NPM提供了很多命令,例如installpublish,使用npm help可查看所有命令。
  • 使用npm help <command>可查看某条命令的详细帮助,例如npm help install
  • package.json所在目录下使用npm install . -g可先在本地安装当前命令行程序,可用于发布前的本地测试。
  • 使用npm update <package>可以把当前目录下node_modules子目录里边的对应模块更新至最新版本。
  • 使用npm update <package> -g可以把全局安装的对应命令行程序更新至最新版。
  • 使用npm cache clear可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。
  • 使用npm unpublish <package>@<version>可以撤销发布自己发布过的某个版本代码。

使用淘宝 NPM 镜像

大家都知道国内直接使用 npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像。

淘宝 NPM 镜像是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。

你可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org
//改用国内镜像,如下:
npm install cnpm -g --registry=https://registry.npmmirror.com

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

$ cnpm install [name]

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