模块(Module)和包(Package)是Node.js最重要的支柱。对使用者来说,模块和包的区别是透明的,因此经常不作区分。如果要辨析,可以把包理解成实现了某个功能模块的集合,用于发布和维护。
创建模块
在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);
};
在同一目录下创建test.js,内容是:
//test.js
var myModule=require('./module.js');
myModule.setName('Jack');
myModule.sayHello();
运行node test.js
结果是Hello,Jack
require是单次加载的
require不会重复加载模块,也就是说不论调用多少次require,获得的模块都是同一个,和对象有着本质的区别。
修改text.js内容如下
var hello=require('./module');
hello.setName('Jack');
var hello2=require('./module');
hello2.setName('Bob');
hello.sayHello();
运行结果:
运行后发现输出结果是Hello,Bob,这是因为变量hello和hello2指向的是同一个实例,因此hello.setName的结果被hello2.setName覆盖,最终输出的结果是由后者决定的。
把一个对象封装到模块中
//module.js
function Hello(){
var name;
this.setName=function(thename){
name=thename;
};
this.sayHello=function(){
console.log('Hello,'+name);
};
};
module.exports=Hello;
//test.js
var Hello=require('./module'),
hello=new Hello();
hello.setName('Jack');
hello.sayHello();
运行结果:
创建包
包是在模块基础上更深一步的抽象,Node.js的包类似于C/C++的函数库或者Java/.Net的类库。它将某个独立的功能封装起来,用于发布、更新、依赖管理和版本控制。Node.js根据CommonJS规范实现了包机制,开发了npm来解决包的发布和获取需求。Node.js的包是一个目录,其中包含一个JSON格式的包说明文件package.json。
作为文件夹的模块
模块与文件是对应的。文件不仅可以是代码文件,还可以是一个文件夹。最简单的包,就是一个作为文件夹的模块。
例如:建立一个叫做package的文件夹,在其中创建index.js.
//package/index.js
exports.hello=function(){
console.log('Hello');
};
然后在package之外建立getpackage.js
//getpackage.js
var package=require('./package');
package.Hello();
运行node getpackage.js,控制台将输出结果Hello。