Node中的模块
在Node中,很大的一个组成部分就是模块,其中有Node中的core模块,有从npm上下载的第三方模块以及我们自己写的模块。
NodeJS在模块化方面使用的是exports和require来导入和导出。
这里我写了几个小例子来和大家分享一下exports的几种简单方法。文件目录大概是这样

1.直接导出
./modules/hello1.js1
2
3module.exports = function(){
console.log('hello world 1')
};
这是一种很简单的到处方法,module.expots可以理解成是一个空对象({}),而导出的方法就是直接用自己写好的function或者
object来替换这个对象。
./app.js1
2var hello1 = require('./modules/hello1');
hello1();
2.作为exports的一个属性导出
./modules/hello2.js1
2
3
4
5var hello = function(){
console.log('hello world 2');
};
module.exports.hello = hello;
为module.exports增加一个名为hello的属性
./app.js1
2var hello2 = require('./modules/hello2');
hello2.hello();
3. 用一个实例来替换module.exports
./modules/hello3.js1
2
3
4
5
6
7
8var hello3 = function(){
this.word = 'hello world 3';
this.hello = function(){
console.log(this.word)
}
};
module.exports = new hello3();
这里可以看到,首先我们写一个构造函数用来生成实例,然后把一个新生成的实例赋给module.exports,就像这样:
./app.js1
2var hello3a = require('./modules/hello3');
hello3a.hello();
但是,如果我们改变hello3a的属性会怎么样呢?按理说实例都是各自独立的,hello3a的属性改变了应该不会影响其他的实例啊,
让我们来做个实验吧
- ./app.js为什么啊?!我不是只改变了hello3a的word属性吗,为什么hello3b也会受到影响?!
1
2
3
4
5
6
7
8
9
10
11var hello3a = require('./modules/hello3');
hello3a.hello();
//这里word属性已经改变了
hello3a.word = 'Good bye';
var hello3b = require('./modules/hello3');
hello3b.hello();
//输出是这样的
//hello world 3
//Good bye
其实,module.exports是有缓存机制的,只要一个模块生成了一次,之后所有对这个模块的require都会判断是否存在这个模块的缓存,
如果有,就会返回这份缓存。也就是说,不管一个模块被require多少次,其实都是require的同一个模块。那么上面的例子我该怎么让这两个实例
真正的做到独立存在呢?
4. 导出一个构造函数
./modules/hello4.js1
2
3
4
5
6
7
8var HelloCreator = function(){
this.word = 'hello world 4';
this.hello = function(){
console.log(this.word);
}
};
module.exports = HelloCreator;
其实很简单,只要导出那个构造函数就行了,谁需要实例就去自己new吧
./app.js1
2
3
4
5
6
7
8var Hello = require('./modules/hello4');
var hello4a = new Hello();
hello4a.word = 'Good bye';
hello4a.hello();
var hello4b = new Hello();
hello4b.hello();
当然了,我们不能直接使用这个模块,因为它仅仅只是个构造函数,所以只要new一下就可以了。
5. 只把想要暴露的方法和属性暴露出去
./modules/hello5.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var word = 'Hello world 5';
var word2 = 'Good bye';
var hello = function(){
console.log(word);
};
var bye = function(){
console.log(word2);
};
module.exports = {
hello: hello,
bye: bye
};
在这个例子里,我们只把hello和bye这两个方法暴露给外界,对于其他的属性和方法,外界是无法访问到的。这样做在某种意义上保证了隐秘数据不会被外界
访问到,而且还增加了模块的可控性。
./app.js1
2
3var hello5 = require('./modules/hello5');
hello5.hello();
hello5.bye();
总结
定义模块和获得模块的方法有很多,以上只是列举了几种比较常见的,希望能对新入坑的小伙伴们有所帮助。其实我认为没有哪种方法是绝对好或者绝对不好的
具体使用哪种方法写模块或者导出模块还是要看具体的业务需求。