NodeJS中模块和包
模块
什么是模块
模块是Node.js应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个Node.js文件就是一个模块,这个文件可能是JavaScript代码、JSON或者编译过的C/C++扩展。
创建及加载模块
- 创建模块
在Node.js中,创建一个模块非常简单,因为一个文件就是一个模块,我们要关注的问题仅仅在于如何在其他文件中获取这个模块。Node.js提供了exports和require两个对象,其中exports是模块公开的接口,require用于从外部获取一个模块的接口,即所获取模块的exports对象。 - 单次加载
require不会重复加载模块,也就是说无论调用多少次require,获得的模块都是同一个。(类似于java中获得的对象是单例的) - 覆盖exports
有时候我们只是想把一个对象封装到模块中,例如
//singleobject.js
function Hello(){
var name;
this.setName = function(thyName){
name = thyName;
};
this.sayHello = function(){
console.log('Hello '+ name);
};
};
exports.Hello = Hello;
此时,我们在其他文件中需要通过require(‘./singleobject’).Hello来获取Hello对象,这略显冗余,可以用下面方法稍微简化:
//hello.js
function Hello(){
var name;
this.setName = function(thyName){
name = thyName;
};
this.sayHello = function(){
console.log('Hello '+ name);
};
};
module.exports = Hello;
这样就可以直接获得这个对象了:
//gethello.js
var Hello = require('./hello');
hello = new Hello();
hello.setName('BYVoid');
hello.sayHello();
注意,模块接口的唯一变化是使用module.exports = Hello代替了exports.Hello= Hello。在外部引用该模块时,其接口对象就是要输出的Hello对象本身,而不是原先的exports。
事实上,exports本身仅仅是一个普通的空对象,即{ },它专门用来声明接口,本质上是通过它为模块闭包的内部建立了一个有限的访问接口。因为它没有任何特殊的地方,所以可以用其他东西来替代,譬如我们上面例子中的Hello对象。
创建包
包是在模块基础上更深一步的抽象,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,并符合一些规范即可。作文件夹的模块
模块和文件是一一对应的。最简单的包,就是一个作为文件夹的模块。- package.json
Node.js在调用某个包时,会首先检查包中package.json文件的main字段,将其作为包的接口模块,如果package.json活main字段不存在,会尝试寻找index.js或index.node作为包的接口。
package.json是CommonJS规定的用来描述包的文件,完全符合规范的package.json文件应该含有以下字段。 - name: 包的名称,必须是唯一的,由小写英文字母、数字和下划线组成,不能包含空格。
- description:包的简要说明。
- version:符合语义化版本识别规范的版本
- keywords:关键字数组,通常用于搜索。
- maintainers:维护者数组,每个元素包含name、email(可选)、web(可选)字段。
- contributors:贡献者数组,格式与maintainers相同。包的作者应该是贡献者数组的第一个元素。
- licenses:许可证数组,每个元素要包含type(许可证的名称)和url(链接到许可证文本的地址)字段。
- repositories:仓库托管地址数组,每个元素要包含type(仓库的类型,如git)、url(仓库的地址)和path(相对于仓库的路径,可选)字段。
- dependencies:包的依赖,一个关联数组,由包名称和版本号组成。
下一篇: UDP 广播