Nodejs包管理器,即npm是Nodejs官方提供的包管理工具,它已经成了Nodejs包的标准发布平台,用于Nodejs包的发布、传播、依赖控制。你可以使用npm的命令行工具方便的下载、安装、升级、删除包。
在2.2节中我们介绍了使用npm安装包的时候有两种模式:本地模式和全局模式。默认情况下我们使用如下代码:
npm install 包名
采取本地模式从http://npmjs.org
搜索或下载包,将包安装到当前目录的node_modules
子目录下(如果没有node_modules
,则创建之)。把包安装到当前目录,也就是本地,可以解决不同程序依赖不同版本的包的问题,减轻作者API的压力,但缺陷是同一个包可能会被安装很多次。
使用全局模式只需加上-g
标识。还记得我们在2.2节对npm全局模式进行的配置吗?npm全局模式的设计其实并不在于解决一个包被安装多次这样没有成本的问题,也不是因为许多程序都有可能用到它,之所以要使用全局模式,是因为只有全局模式才会注册path环境变量,才能在命令行中才能直接调用。比如直接执行supervisor app.js
。如果不注册path环境变量的话,命令行会提示你“XXX不是内部或外部命令,也不是可运行的程序或批处理文件。”但要注意,如果你更改了node全局安装的默认位置,要进行一系列环境变量的更改。具体更改方式2.2节有详细的介绍
还有一个区别在于全局模式安装的包不能通过require()获取到,因为require()不会去搜索你在全局模式包安装的文件夹。npm link命令可以打破这一限制,可以连接本地到全局或者全局到本地,这种命令有利于我们在不同的工程间进行测试。因为这个命令是不支持windows的,所以我不打算探究它。
总而言之,当我们要把某个包作为工程运行时的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式。
还记得最开始时我们试着安装的express吗?就是一个经典的第三方模块。他可以帮助我们快速的构建我们的网站。像express这样的第三方模块在使用npm下载后会被放在一个叫做node_modules的文件夹里。
我们在定义包时,往往要求模块在文件系统中使用相对路径存放,对于组织特定程序很有帮助,但对于程序间共享或跟他人共享代码却用处不大。因为当你下载像express这样的,别人写好的第三方node模块时,不可能去关注你所下载的包里面的文件模块的路径关系。
Nodejs有一个独特的机制,这个机制就是使用node_modules
机制。如果你引入模块的方式不是像这样./XXX
相对路径的方式,而是直接写的模块名,Nodejs会按照从内往外的次序依次检查该文件所在目录及其所有祖先目录中的node_modules
文件夹,看里面是否存在文件名为模块名的文件,如果找到,则导出模块,否则会看模块是否在由环境变量NODE_PATH
指定的目录下(对于全局安装的模块),如果仍然找不到,则报错。搜寻模块接口的规则如图所示:
这里的核心模块指的是像fs、http等nodejs内置的模块。
package.json是commonJS规定用来描述包的文件,CommonJS为其提供了一套规范。npm有一套以CommonJS为基础的规范,但是与之并不完全一致,主要是必填的字段不同。
在控制台输入下面代码,npm将以一问一答的方式为你生产符合npm标准的package.json。
npm init
nodejs会揣测你的答案,并在问题后面的()中把它的推测提供给你,直接按下回车就会按照()中提示的内容进行填写:
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 json` for definitive documentation on these fields
and exactly what they do.
Use `npm install --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: (somepackage)
version: (1.0.0)
description: my first try to create a package.json
entry point: (index.js) ./lib/interface.js
test command:
git repository:
keywords:
author: hukaihe
license: (ISC)
About to write to D:\WebStorm 2016.2\WSPro\Node\C3\modulesAndPackages\package\somepackage\package.json:
{
"name": "somepackage",
"version": "1.0.0",
"description": "my first try to create a package.json",
"main": "./lib/interface.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "hukaihe",
"license": "ISC"
}
Is this ok? (yes)
下面是一个符合npm标准的package.json文件:
{
“name”: “somepackage”,
“version”: “1.0.0”,
“description”: “my first try to create a package.json”,
“main”: “./lib/interface.js”,
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1”
},
“author”: “hukaihe”,
“license”: “ISC”,
“dependencies”: {
“cheerio”: “^0.22.0”
},
“repository”:{
“url”:””
}
}
下面两个是我为了演示加上的:
我们可以把我们写好的包发布到npm社区:http://npmjs.org
但在此之前,我们需要现在这个社区注册一个账号。我们可以使用npm命令行来注册账号,方式还是一问一答,但注意用户名必须小写;输入密码时密码不会显示在命令行上,输入完毕后直接回车即可。
npm adduser
创建完成后可以通过下面的代码来检测是否已经取得了账号
npm whoami
npm可以非常方便的发布一个包,但在发布之前,需要首先通过
npm init
生成一个包的描述文件package.json,我们已经在上一节对package.json进行了详细的讲解。
接下来,在package.json所在的目录下运行
npm publish
即可发布该包。但注意,包的名字不能和npm社区已经存在的包名相同,否则会报错。换句话说,package.json里的name元素的值不能相同。如果文件夹名和name元素的值不相等,那么在发布成功后,npm会改变文件夹的名称以至于它和name元素的名称相同。
发布成功后,你就可以在任意一台计算机使用npm install 包名
下载这个包。同时,在npm的网站上就可以找到自己刚刚发布的包了。
如果你的包有更新,只需改变package.json里的version然后重新发布上去就行了。
如果你对发布的包不满意,可以使用
npm unpublish 项目名@版本号
命令来取消发布。
这里推荐大家使用webStorm等IDE进行调试,一是因为我们现在的项目开发基本很难不依赖于IDE,再者,这些IDE确实非常方便。
WebStorm是真正的前端开发神器,能够帮助我们迅速组织好代码。从今以后的代码我们都将在Webstorm上进行开发。首先我们先告诉webstorm我们的项目(或者某个文件)是node项目,它不依赖于浏览器。
我们在Webstorm里随便新建一个JS文件夹叫做debugging,在里面新建一个叫做test.js的文件,随意在文件里书写一些简单的JS代码,打开设置,进入如下目录,选中Nodejs and NPM:
设置coding assistant为enabled,并设置【usage scope】指定其作用范围(即在那些文件夹下node coding assistant会发挥作用)。设置好后,你会发现你设置的文件夹下的JS文件的图标都发生了改变,变成六边形的了,这是WebStorm给node的“专属套装”。我使用的WS版本是2016.2.2。
好,现在我们试着在test.js文件的内容里加上一些断点,如图所示,单击鼠标右键,点击debug,这时系统就会开始调试并为我们打开debugger。
除了使用WS等IDEA可以对Nodejs项目进行调试外,你还可以使用node-inspector等优秀的调试工具进行调试,这里我们不再赘述。