Node.js使得在服务器端使用JavaScript编写应用程序成为可能。它是基于V8Javascript运行时而且使用C++编写的,因此它的速度很快。最初,它旨在做为应用程序的服务器环境,可是开发人员使用它建立工具来帮助他们进行本地任务自动化。从那时起,一个全新的基于Node的工具生态系统(如Grunt,Gulp和Webpack)完全改变了前端开发的面貌。前端
为了在Node.js中使用这些工具(或者包),咱们须要可以以有效的方式安装和管理它们。这就是咱们即将要讨论的:npm--Node的包管理器。它负责安装你须要使用的包,而且提供一个有用的界面让你与它们交互。node
在本文中,我将介绍使用npm的基础知识。我将向你演示如何在本地和全局模式下安装包,以及删除,更新和安装某个版本的包。我还会告诉你如何使用package.json
处理项目的依赖。若是你更喜欢看视频,请注册SitePoint Premium观看咱们的免费录屏:什么是npm以及如何使用?。linux
在开始使用npm以前,首先须要在电脑中安装Node.js。webpack
去Node.js 下载页面获取你须要的版本。能够得到Windows和Mac环境的安装包和预编译的Linux二进制文件以及源代码。对于Linux环境,你还能够经过包管理器来安装Node,如这里所述。git
本教程咱们将使用v6.10.3稳定版本。在编写本文时,这是Node的当前长期支持(LTS)版本。github
提示: 你也能够考虑使用版本管理器来安装Node。这将消除下面提出的权限问题。web
咱们来看一下Node的安装位置以及版本。express
$ which node /usr/bin/node $ node --version v6.10.3
使用Node的REPL(交互式解释器)检查安装是否成功。npm
$ node > console.log('Node is running'); Node is running > .help .break Sometimes you get stuck, this gets you out .clear Alias for .break .exit Exit the repl .help Show repl options .load Load JS from a file into the REPL session .save Save all evaluated commands in this REPL session to a file > .exit
Node.js已经安装成功,如今咱们能够把注意力集中在npm上,npm已经集成在上述安装的Node.js中。json
$ which npm /usr/bin/npm $ npm --version 3.10.10
npm能够以本地或全局模式安装包。在本地模式下,将包安装在父工做目录中的node_modules
文件夹中。该位置由当前用户所拥有。安装在{prefix}/lib/node_modules/
中的全局包由user根目录所拥有({prefix}
一般是/usr/
或 /usr/local
)。这意味着你将不得不使用sudo全局安装包,这可能会在解决第三方依赖时致使权限错误,也可能致使安全问题。下面让咱们更改一下:
让咱们看看运行npm config list
输出了什么:
$ npm config list ; cli configs user-agent = "npm/3.10.10 node/v6.10.3 linux x64" ; userconfig /home/sitepoint/.npmrc prefix = "/home/sitepoint/.node_modules_global" ; node bin location = /usr/bin/nodejs ; cwd = /home/sitepoint ; HOME = /home/sitepoint ; "npm config ls -l" to show all defaults.
输出给了咱们有关npm的安装信息。如今,重要的是获取当前的全局位置。
$ npm config get prefix /usr
为了在主目录中安装全局包,咱们须要更改这个前缀。为此,你能够在主文件夹中建立一个新目录。
$ cd ~ && mkdir .node_modules_global $ npm config set prefix=$HOME/.node_modules_global
经过这个简单的配置更改,咱们将这个新目录位置设置为全局Node包安装的位置。这个更改同时会在咱们的主目录中建立了一个.npmrc文件。
$ npm config get prefix /home/sitepoint/.node_modules_global $ cat .npmrc prefix=/home/sitepoint/.node_modules_global
咱们仍然将npm安装在由user根目录全部的位置。可是要注意咱们已经在配置中改变了全局包安装的位置。咱们须要再次安装npm,可是这一次是安装在新用户所在的位置。固然,安装的将是npm的最新版本。
$ npm install npm --global └─┬ npm@5.0.2 ├── abbrev@1.1.0 ├── ansi-regex@2.1.1 .... ├── wrappy@1.0.2 └── write-file-atomic@2.1.0
最后,咱们须要添加.node_modules_global/bin
到$PATH环境变量中,以即可以从命令行运行全局包。为了作到这一点,你能够把下面这一行添加到.profile
,.bash_profile
或者.bashrc
文件中并从新启动终端。
export PATH="$HOME/.node_modules_global/bin:$PATH"
如今咱们能够找到npm的所在目录.node_modules_global/bin
而且使用合适的npm版本。
$ which npm /home/sitepoint/.node_modules_global/bin/npm $ npm --version 5.0.2
目前咱们只有一个安装在全局的包-那就是npm包自己。下面咱们来安装UglifyJS包(一个JavaScript的压缩工具)。咱们使用--global标记,也能够缩写为-g。
$ npm install uglify-js --global /home/sitepoint/.node_modules_global/bin/uglifyjs -> /home/sitepoint/.node_modules_global/lib/node_modules/uglify-js/bin/uglifyjs + uglify-js@3.0.15 added 4 packages in 5.836s
从输出能够看出,还安装了其余包, 这些包都是UglifyJS包的依赖项。
咱们可使用npm list
命令列出全局包。
$ npm list --global home/sitepoint/.node_modules_global/lib ├─┬ npm@5.0.2 │ ├── abbrev@1.1.0 │ ├── ansi-regex@2.1.1 │ ├── ansicolors@0.3.2 │ ├── ansistyles@0.1.3 .................... └─┬ uglify-js@3.0.15 ├─┬ commander@2.9.0 │ └── graceful-readlink@1.0.1 └── source-map@0.5.6
然而,输出十分冗长。咱们可使用--depth=0
选项进行优化。
$ npm list -g --depth=0 /home/sitepoint/.node_modules_global/lib ├── npm@5.0.2 └── uglify-js@3.0.15
咱们发现这要更友好 -- 只显示咱们安装的包及其版本号。
咱们能够在命令行中使用任何全局安装包。例如:下面的命令展示了如何使用Uglify 包将example.js
压缩到example.min.js
:
$ uglifyjs example.js -o example.min.js
当你在本地安装包时,一般会使用package.json文件进行安装。下面让咱们建立这样的一个文件。
$ npm init package name: (project) version: (1.0.0) description: Demo of package.json entry point: (index.js) test command: git repository: keywords: author: license: (ISC)
按Enter
接受默认值,而后键入yes
确认。这样将会在项目的根目录下建立一个package.json
文件。内容以下:
{ "name": "project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
提示:你可使用
npm init --y
命令以更快的方式生成package.json文件
除了main
和scripts
外,其余字段应该是一目了然的。main
字段是你程序的主入口,scripts
字段容许你指定在包的生命周期中的不一样时间运行的脚本命令。咱们暂时不讨论这些东西,可是若是你想了解更多相关信息,请参阅《npm中的package.json文档》和《使用npm做为构建工具》。
如今让咱们来安装underscore包。
$ npm install underscore npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN project@1.0.0 No description npm WARN project@1.0.0 No repository field. + underscore@1.8.3 added 1 package in 0.344s
注意这里建立了一个文件,咱们稍后会讲到它。
打开package.json文件咱们会看到dependencies
字段已经添加到了文件中:
{ ... "dependencies": { "underscore": "^1.8.3" } }
如你所见,underscore v1.8.3安装到了咱们的项目中。版本号前面的(^)符号表示安装时,npm将安装最高版本的包,npm还能够找到主版本能够匹配的惟一位置(除非存在package-lock.json
文件)。在咱们的例子中,这是V2.0.0版本如下的全部版本。版本控制依赖(major.minor.patch)的这种方法被称为语义化版本控制。你能够在《语义化版本控制:为何你应该使用它?》文章中了解更多相关知识。
还要注意,underscore被保存为dependencies字段的属性。这是最新版本npm的默认设置,用于运行应用程序所需的包(如underscore)。也能够经过指定--save-dev
标志将包保存为devDependency。devDependencies是用于开发目的的包,例如运行测试或解析代码。
你也能够给package.json文件添加private: true
以防止意外发布私有仓库而且阻止全部运行npm install
时生成的警告。
其实使用package.json
指定项目依赖的最大好处是可移植性。例如,当你克隆别人的代码时,你只须要在根目录运行npm i
便可,而后npm将解析并获取全部运行该应用程序必需的包。稍后咱们再来看这个。
在结束此部份内容以前,咱们快速检查一下underscore是否正在工做。在项目根目录下建立名为test.js的文件并写入下列内容:
const _ = require('underscore'); console.log(_.range(5));
使用node test.js
运行文件,你应该看到[0, 1, 2, 3, 4]输出到了屏幕。
npm是一个包管理器,因此它确定能够卸载一个包。咱们假设当前的underscore包致使了兼容性问题。咱们能够卸载这个包并安装旧版本,以下所示:
$ npm uninstall underscore removed 2 packages in 0.107s $ npm list project@1.0.0 /home/sitepoint/project └── (empty)
咱们经过使用@符号加一个版本号来安装特定版本的underscore包。
$ npm install underscore@1.8.2 + underscore@1.8.2 added 1 package in 1.574s $ npm list project@1.0.0 /home/sitepoint/project └── underscore@1.8.2
让咱们检查一下underscore包是否存在新版本:
$ npm outdated Package Current Wanted Latest Location underscore 1.8.2 1.8.3 1.8.3 project
Current
列告诉咱们当前安装的版本。Latest
列告诉咱们包的最新版本。 Wanted
列告诉咱们在不破坏现有的代码的前提下能够升级到的最新版本的包。
还记得以前的package-lock.json
文件吗?它是在npm v5中引入的,目的是确保安装在计算机上的全部项目的依赖保持不变。当npm修改node_modules文件夹或package.json文件时它会自动生成。
若是你喜欢,你能够继续尝试。删除node_modules
文件夹,而后从新运行npm i
。最新版本的npm将安装underscore v1.8.2(由于这是package-lock.json文件中指定的)。根据语义化版本控制的规范,v1 .8.3将向下兼容早期版本。在过去,不一致的包版本对开发人员来讲很头痛的事情。这个问题一般经过使用必须手动建立的npm-shrinkwrap.json
文件来解决。
如今,咱们假设最新版本的underscore修复了咱们以前提到的兼容性错误,咱们但愿将包更新为该版本。
$ npm update underscore + underscore@1.8.3 updated 1 package in 0.236s $ npm list project@1.0.0 /home/sitepoint/project └── underscore@1.8.3
提示:为了使上述命令工做正常,underscore必须被列为package.json的依赖项。若是咱们有更多的过期模块,咱们也能够执行
npm update
。
在本教程中咱们已经屡次使用了mkdir
命令。是否存在一个包作相同的事情呢?让咱们使用npm search
命令看一下。
$ npm search mkdir NAME | DESCRIPTION | AUTHOR | DATE | VERSION mkdir | Directory crea… | =joehewitt | 2012-04-17 | 0.0.2 fs-extra | fs-extra conta… | =jprichardson… | 2017-05-04 | 3.0.1 mkdirp | Recursively mkdir,… | =substack | 2015-05-14 | 0.5.1 ...
这里有一个mkdirp
包,咱们来安装它。
$ npm install mkdirp + mkdirp@0.5.1 added 2 packages in 3.357s
建立mkdir.js
文件并复制粘贴此代码:
const mkdirp = require('mkdirp'); mkdirp('foo', function (err) { if (err) console.error(err) else console.log('Directory created!') });
从终端运行这个文件:
$ node mkdir.js Directory created!
咱们先安装一个包:
$ npm install request + request@2.81.0 added 54 packages in 15.92s
检查package.json
文件。
"dependencies": { "mkdirp": "^0.5.1", "request": "^2.81.0", "underscore": "^1.8.2" },
注意依赖项列表会自动更新。在之前的npm版本中,你将不得不执行npm install request --save
以保存package.json
中的依赖关系。若是你想安装一个包而不在package.json中保存它,只需使用--no-save
参数。
假设你将项目源代码克隆到了另外一台计算机,如今须要安装依赖项。咱们先删除node_modules
文件夹而后执行npm install
。
$ rm -R node-modules $ npm list project@1.0.0 /home/sitepoint/project ├── UNMET DEPENDENCY mkdirp@^0.5.1 ├── UNMET DEPENDENCY request@^2.81.0 └── UNMET DEPENDENCY underscore@^1.8.2 npm ERR! missing: mkdirp@^0.5.1, required by project@1.0.0 npm ERR! missing: request@^2.81.0, required by project@1.0.0 npm ERR! missing: underscore@^1.8.2, required by project@1.0.0 $ npm install added 57 packages in 1.595s
注意观察node_modules
文件夹,你会发现它已经被从新建立。像这样,你就能够轻松地与他人共享你的代码,而不会致使你的项目和源依赖仓库膨胀。
当npm安装一个包时,其实它保存了一个副本。因此下次你安装这个包的时候就不须要再链接网络。这些副本缓存在你的主路径下的.npm
目录中。
$ ls ~/.npm anonymous-cli-metrics.json _cacache _locks npm registry.npmjs.org
这个目录会随着时间的推移而变得乱七八糟,因此有时候要清理它。
$ npm cache clean
若是你要清理系统上的多个Node项目,还能够从工做区清除全部node_module
文件夹。
find . -name "node_modules" -type d -exec rm -rf '{}' +
可能你已经注意到,运行npm命令有多种方式。如下是一些经常使用的npm别名的简要列表:
npm i <package>
- 安装本地包
npm i -g <package>
- 安装全局包
npm un <package>
- 卸载本地包
npm up
- npm更新包
npm t
- 运行测试
npm ls
- 列出已安装的模块
npm ll
或npm la
- 在列出模块时打印附加包信息
你也能够一次安装多个软件包:
$ npm i express momemt lodash mongoose body-parser webpack
若是想要学习全部常见的npm命令,执行npm help
获取完整的命令列表。你也能够在个人《10个技巧,使你成为npm忍者》文章中学到更多相关知识。
有几种有用的工具可让你在同一台机器上管理多个版本的Node.js。其中一个就是n
,另外一个是nvm
(Node 版本管理器)。若是这是你感兴趣的内容,能够看看咱们的教程:《使用nvm安装多个版本的Node.js》。
在本教程中,我介绍了使用npm的基础知识,演示了如何从下载页面安装Node.js,如何更改全局包的位置(因此咱们能够避免使用sudo)以及如何在本地和全局模式下安装包。我还介绍了删除,更新和安装某个版本的包,以及管理项目的依赖。若是你想了解有关最新版本中的新功能的更多信息,能够访问npm Github发行页面。
随着版本5的发行,npm正在向前端开发的世界迈进。根据其首席运营官的介绍,npm用户基础正在发生变化,其中大多数开发者使用它们并无使用它来编写Node。相反,它正在成为人们在前端开发中整合JavaScript的工具(你可使用它来安装任何东西)而且它正在成为编写现代JavaScript的组成部分。你在你的项目中使用npm了吗?若是没有,如今是开始使用它的好时机。