5. NPM 包管理器

节点包管理器(NPM)提供两个主要功能:可在search.nodejs.org上搜索的node.js包/模块的联机存储库。用于安装Node.js包的命令行实用程序,执行Node.js包的版本管理和依赖关系管理。
  • 在v0.6.3版本之后,NPM捆绑了Node.js可安装程序。 要验证相同,请打开控制台并键入以下命令并查看结果:
    $ npm --version
    2.7.1
    
  • 如果您运行的是旧版本的NPM,则可以很容易地将其更新到最新版本。 只需使用root中的以下命令:
    $ sudo npm install npm -g
    /usr/bin/npm -> /usr/lib/node_modules/npm/bin/npm-cli.js
    npm@2.7.1 /usr/lib/node_modules/npm
    

5.1. 使用NPM安装模块

  • 有一个简单的语法来安装任何Node.js模块:
    $ npm install <Module Name>
    
  • 例如,以下是安装名为express的着名Node.js Web框架模块的命令:
    $ npm install express
    
  • 现在您可以在js文件中使用此模块,如下所示:
    var express = require('express');
    

5.2. 全局与本地安装

默认情况下,NPM在本地模式下安装任何依赖项。 这里的本地模式是指node_modules目录中的软件包安装,该目录位于存在Node应用程序的文件夹中。 可以通过require()方法访问本地部署的包。 例如,当我们安装express模块时,它在安装express模块的当前目录中创建了node_modules目录。

$ ls -l
total 0
drwxr-xr-x 3 root root 20 Mar 17 02:23 node_modules

或者,您可以使用 npm ls 命令列出所有本地安装的模块。

全局安装的包/依赖项存储在系统目录中。 此类依赖项可用于任何node.js的CLI(命令行界面)功能,但不能直接使用Node应用程序中的 require() 导入。 现在让我们尝试使用全局安装来安装快速模块。

$ npm install express -g

这将产生类似的结果,但模块将全局安装。 这里,第一行显示模块版本及其安装位置。

<b>express@4.12.2 /usr/lib/node_modules/express</b>
├── merge-descriptors@1.0.0
├── utils-merge@1.0.0
├── cookie-signature@1.0.6
├── methods@1.1.1
├── fresh@0.2.4
├── cookie@0.1.2
├── escape-html@1.0.1
├── range-parser@1.0.2
├── content-type@1.0.1
├── finalhandler@0.3.3
├── vary@1.0.0
├── parseurl@1.3.0
├── content-disposition@0.5.0
├── path-to-regexp@0.1.3
├── depd@1.0.0
├── qs@2.3.3
├── on-finished@2.2.0 (ee-first@1.1.0)
├── etag@1.5.1 (crc@3.2.1)
├── debug@2.1.3 (ms@0.7.0)
├── proxy-addr@1.0.7 (forwarded@0.1.0, ipaddr.js@0.1.9)
├── send@0.12.1 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)
├── serve-static@1.9.2 (send@0.12.2)
├── accepts@1.2.5 (negotiator@0.5.1, mime-types@2.0.10)
└── type-is@1.6.1 (media-typer@0.3.0, mime-types@2.0.10)

您可以使用以下命令检查全局安装的所有模块:

$ npm ls -g

5.3. 使用 package.json

package.json 存在于任何Node应用程序/模块的根目录中,用于定义包的属性。 让我们打开node_modules/express/ 的express包的package.json。

{
   "name": "express",
      "description": "Fast, unopinionated, minimalist web framework",
      "version": "4.11.2",
      "author": {
         "name": "TJ Holowaychuk",
         "email": "tj@vision-media.ca"
      },
   "contributors": [{
      "name": "Aaron Heckmann",
      "email": "aaron.heckmann+github@gmail.com"
   }, 
   {
      "name": "Ciaran Jessup",
      "email": "ciaranj@gmail.com"
   },
   {
      "name": "Douglas Christopher Wilson",
      "email": "doug@somethingdoug.com"
   },
   {
      "name": "Guillermo Rauch",
      "email": "rauchg@gmail.com"
   },
   {
      "name": "Jonathan Ong",
      "email": "me@jongleberry.com"
   },
   {
      "name": "Roman Shtylman",
      "email": "shtylman+expressjs@gmail.com"
   },
   {
      "name": "Young Jae Sim",
      "email": "hanul@hanul.me"
   } ],
   "license": "MIT", "repository": {
      "type": "git",
      "url": "https://github.com/strongloop/express"
   },
   "homepage": "https://expressjs.com/", "keywords": [
      "express",
      "framework",
      "sinatra",
      "web",
      "rest",
      "restful",
      "router",
      "app",
      "api"
   ],
   "dependencies": {
      "accepts": "~1.2.3",
      "content-disposition": "0.5.0",
      "cookie-signature": "1.0.5",
      "debug": "~2.1.1",
      "depd": "~1.0.0",
      "escape-html": "1.0.1",
      "etag": "~1.5.1",
      "finalhandler": "0.3.3",
      "fresh": "0.2.4",
      "media-typer": "0.3.0",
      "methods": "~1.1.1",
      "on-finished": "~2.2.0",
      "parseurl": "~1.3.0",
      "path-to-regexp": "0.1.3",
      "proxy-addr": "~1.0.6",
      "qs": "2.3.3",
      "range-parser": "~1.0.2",
      "send": "0.11.1",
      "serve-static": "~1.8.1",
      "type-is": "~1.5.6",
      "vary": "~1.0.0",
      "cookie": "0.1.2",
      "merge-descriptors": "0.0.2",
      "utils-merge": "1.0.0"
   },
   "devDependencies": {
      "after": "0.8.1",
      "ejs": "2.1.4",
      "istanbul": "0.3.5",
      "marked": "0.3.3",
      "mocha": "~2.1.0",
      "should": "~4.6.2",
      "supertest": "~0.15.0",
      "hjs": "~0.0.6",
      "body-parser": "~1.11.0",
      "connect-redis": "~2.2.0",
      "cookie-parser": "~1.3.3",
      "express-session": "~1.10.2",
      "jade": "~1.9.1",
      "method-override": "~2.3.1",
      "morgan": "~1.5.1",
      "multiparty": "~4.1.1",
      "vhost": "~3.0.0"
   },
   "engines": {
      "node": ">= 0.10.0"
   },
   "files": [
      "LICENSE",
      "History.md",
      "Readme.md",
      "index.js",
      "lib/"
   ],
   "scripts": {
      "test": "mocha --require test/support/env 
         --reporter spec --bail --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/",
      "test-travis": "istanbul cover node_modules/mocha/bin/_mocha 
         --report lcovonly -- --require test/support/env 
         --reporter spec --check-leaks test/ test/acceptance/"
   },
   "gitHead": "63ab25579bda70b4927a179b580a9c580b6c7ada",
   "bugs": {
      "url": "https://github.com/strongloop/express/issues"
   },
   "_id": "express@4.11.2",
   "_shasum": "8df3d5a9ac848585f00a0777601823faecd3b148",
   "_from": "express@*",
   "_npmVersion": "1.4.28",
   "_npmUser": {
      "name": "dougwilson",
      "email": "doug@somethingdoug.com"
   },
   "maintainers": [{
      "name": "tjholowaychuk",
      "email": "tj@vision-media.ca"
   },
   {
      "name": "jongleberry",
      "email": "jonathanrichardong@gmail.com"
   },
   {
      "name": "shtylman",
      "email": "shtylman@gmail.com"
   },
   {
      "name": "dougwilson",
      "email": "doug@somethingdoug.com"
   },
   {
      "name": "aredridel",
      "email": "aredridel@nbtsc.org"
   },
   {
      "name": "strongloop",
      "email": "callback@strongloop.com"
   },
   {
      "name": "rfeng",
      "email": "enjoyjava@gmail.com"
   }],
   "dist": {
      "shasum": "8df3d5a9ac848585f00a0777601823faecd3b148",
      "tarball": "https://registry.npmjs.org/express/-/express-4.11.2.tgz"
   },
   "directories": {},
      "_resolved": "https://registry.npmjs.org/express/-/express-4.11.2.tgz",
      "readme": "ERROR: No README data found!"
}

5.4. Package.json的属性

  • name :包的名称
  • version :包的版本
  • description :包的描述
  • homepage :包的主页
  • author :包的作者
  • contributors :包的贡献者的名称
  • dependenciesdependencies 列表。 NPM会自动在程序包的node_module文件夹中安装此处提到的所有依赖项。
  • repository :存储库类型和包的URL
  • main :包裹的入口点
  • keywords :关键字

5.5. 卸载模块

  • 使用以下命令卸载Node.js模块:
    $ npm uninstall express
    
  • NPM卸载软件包后,您可以通过查看/ node_modules /目录的内容来验证它,或者键入以下命令:
    $ npm ls
    

5.6. 更新模块

  • 更新package.json并更改要更新的依赖项的版本并运行以下命令:
    $ npm update express
    

5.7. 搜索模块

  • 使用NPM搜索包名称。
    $ npm search express
    

5.8. 创建一个模块

创建模块需要生成package.json。 让我们使用NPM生成package.json,它将生成package.json的基本框架。

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.
See 'npm help json' for definitive documentation on these fields
and exactly what they do.
Use 'npm install <pkg> --save' afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (webmaster)

您需要提供有关模块的所有必需信息。 您可以从上面提到的package.json文件中获取帮助,以了解所需的各种信息的含义。 生成package.json后,使用以下命令使用有效的电子邮件地址向NPM存储库站点注册。

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

是时候发布您的模块了:$ npm publish

如果您的模块一切正常,那么它将在存储库中发布,并且可以像使用任何其他Node.js模块一样使用NPM进行安装。

下一节:回调是函数的异步等价物。 在给定任务完成时调用回调函数。 Node大量使用回调。 Node的所有API都以支持回调的方式编写。

例如,读取文件的功能可以开始读取文件并立即将控制返回到执行环境,以便可以执行下一条指令。 一旦文件I/O完成,它将在传递回调函数时调用回调函数,该文件的内容作为参数。 因此没有阻塞或等待文件I/O. 这使得Node.js具有高度可扩展性,因为它可以处理大量请求,而无需等待任何函数返回结果。