本节内容:
- 什么是模块
- 如何创建模块
- 如何创建一个包;
- 如何使用包管理器并发布自己创建的包
1.什么是模块
模块是Node.js应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个Node.js文件就是一个模块,这个文件可能是JavaScript代码,JSON或者编译过的C/C++扩展。
前面用过var http = require('http'),其中http是Node.js的一个模块,其内部是用到了C++实现,外部用JavaScript封装。我们通过require函数获取了这个模块,然后才能使用其中的对象。
2.创建及加载模块
在Node.js中,创建一个模块非常简单,因为一个文件就是一个模块,我们要关注的问题是如何在其他文件中获取这个模块。Node.js提供了exports和require两个对象,其中exports是模块公开的接口,require用于从外部获取一个模块的接口,即所获取模块的exports对象。以例子来说明。
创建一个module.js文件。内容是
//module.js var name; exports.setName = function(thyName){ name = thyName; }; exports.sayHello = function(){ console.log('Hello '+ name); };
在同一目录下创建getmodule.js。
//getmodule.js var myModule = require('./module'); myModule.setName('Mi'); myModule.sayHello();
在以上示例中。module.js通过exports对象把setName和sayHello作为模块的访问接口,在getmodule.js中通过require('./module.js')加载这个模块("./表示当前目录"),然后就可以直接访问module.js中exports对象的成员函数了。
3. 创建包
Node.js的包类似于C/C++的函数库或者Java/.Net的类库。它将某个独立的功能封装起来,用于发布,更新,依赖管理和版本控制。Node.js根据CommonJs规范实现了包机制,开发了npm来解决包的发布和获取需求。
Node.js的包是一个目录,其中包含一个JSON格式的包说明文件package.json。
符合CommonJS规范的具有以下特征:
package.json必须在包的顶层目录下;
二进制文件应该在bin目录下;
JavaScript代码应该在lib目录下;
文档应该在doc目录下;
单元测试应该在test目录下;
Node.js对包的要求没有这么严格,只要顶层目录下有package.json,并符合一些规范即可。当然为了提高兼容性,我们还是建议你在制作包的时候,遵守CommonJS规范。
3.1 作为文件夹的模块
模块与文件是一一对应的。最简单的包是作为一个文件夹的模块。
建立一个文件夹somepackage的文件夹,在文件夹里创建index.js,代码如下:
//somepackage/index.js exports.hello = function(){ console.log('Hello.'); }
然后在somepackage同一层目录建getpackage.js。代码如下:
//getpackage.js var somepackage = require('./somepackage'); somepackage.hello();
运行node getpackage.js。结果是Hello.
以上是把文件夹封装为一个模块,也就是所谓的包。
3.2 package.json
在上面的基础上。我们使用规范的操作。在somepackage文件夹下,创建一个叫package.json的文件,代码如下:
{ "main" : "./lib/interface.js" }
之后,在somepackage文件夹下,再创建一个叫lib的文件夹,把index.js改名为interface.js。并移动到lib下。
再次运行node getpackage.js.结果同样。
Node.js在调用包时,会首先检查包中的package.json文件的main字段,将其作为包的接口模块,如果package.js或者main字段不存在,会尝试首先寻找index.js或者index.node作为包的接口。
package.json的字段都有以下字段:
name: 包的名称,必须是唯一的,由小写英文字母,数字和下划线组成,不能包括空格。
description: 包的简要说明。
version: 版本字符串
keywords: 关键字数组,通常用于搜索
maintainers: 维护者数组,每个元素要包含name,email(可选),web(可选)字段
contributors: 贡献者数组,格式与maintainers相同。
bugs: 提交bug的地址,可以是网址或者 电子邮件
licenses: 许可证数组,每个元素要包含type(许可证名称)和url(连接到许可证文本的地址)字段
repositories:仓库托管地址数组,每个元素要包含type(仓库的类型,如git)
url(仓库的地址)和path(相对于仓库的路径,可选)字段。
dependencies:包的依赖,一个关联数组,由名名称和版本号组成。
4.Node.js包管理器
Node.js包管理器,即npm是Node.js官方提供的包管理工具,它已经成了Node.js包的标准发布平台,用于Node.js包的发布,传播,依赖控制,并且npm提供了命令行工具.
4.1 获取一个包
命令 : npm [install/i] [package_name]
比如: npm install express 或者 npm i express
安装的包会出现在当前目录的node_modules子目录。
4.2 本地模式和全局模式
在使用npm安装包的时候,有两种模式:本地模式和全局模式。
默认情况下我们使用npminstall命令是本地模式,Node.js的require在加载模块时会尝试搜寻node_modules子目录,因此本地模式安装的包可以直接被引用 。
npm另一种全局模式使用方法:
npm [install] -g [package_name]
全局模式是为了在命令行运行使用的,比如讲过的supervisor script.js,就需要在PATH环境变量中注册supervisor。
使用全局模式的包并不能直接在Javascript文件中使用require获得。
总结: 当我们要把某个包作为工程运行时的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式。
4.3 包的发布
使用npm init命令可以根据交互式问答产生一个标准的package.json,方便地发布一个包。
比如,以命令行方式进入byMyModule目录(byMyModule是我所创建一个文件夹)
然后输入npm init,根据当前提示输入相关内容,如图
name:模块名字(要小写)
version(0.0.1): 模块版本号
description: 模块说明
entry point: 模块的入口文件,例子是index.js
test command: 测试脚本,选填
git repository: 模块的git仓库,选填。npm的用户一般都使用github做为自己的git仓库
keywords: 关键字
author: 模块的作者
license: 许可证,选填
然后输入yes,就在byMyModule目录下创建了一个package.json 。有个警告提示,可以暂时忽略。
接下来创建账号:
在发布之前,要创建一个账号用于维护自己的包。使用命令npm adduser根据提示输入用户名,密码,邮箱等待账号创建完成。
使用npm whoami测试是否已经取得账号.
最后一步: 在package.json所在的目录运行npm publish,就可以完成发布了.
现在马上去http://search.npmjs.org/, 看一下自己发布的包,如图