NodeJS为js引入了模块化的一些概念,html里面可以引入js或css,甚至css也可以通过@import来引入其他css文件,而JS一直缺少这个机制,这使得JS很难像其他语言如java/python/php那样来编写模块化的应用程序。因此ES6以及NodeJS都对这方面特性做了增强。

NodeJS为每个单独的JS文件生成了默认的Module对象,该对象用来表示文件执行上下文。

我们先来看看module对象(http://www.commonjs.org/specs/modules/1.0/)究竟是什么。

1

2

//index.js

console.log(module);

使用node index.js来运行,结果类似如下:

NodeJS中的module概念以及module.exports和exports的区别_css

其中有一个exports属性,该属性也是一个对象。我们正是通过Module.exports来定义该模块能输出的对象。

那么exports又是什么呢?我们再做个小测试:

1

2

3

4

//index.js

exports.a = 'A';

exports.b = 'B';

console.log(module);

NodeJS中的module概念以及module.exports和exports的区别_快捷方式_02

可见exports应该是module.exports的一个便捷写法的引用,我们设置exports的属性,也改变了module.exports的属性。

但是exports并非一直指向module.exports,如果我们改变了module.exports或者exports所指向的对象,那么exports这个快捷方式将失效。

1

2

3

4

5

//index.js

module.exports = {a: 'A'}; // 注意module.exports不再指向原来的对象

exports.b = 'B'// exports仍然指向原来的对象,但是记住require的时候返回的是module.exports,所以exports将失效

console.log(exports === module.exports);

console.log(module)

NodeJS中的module概念以及module.exports和exports的区别_快捷方式_03

一个小的建议就是两种方式不要混用。

module.exports和exports是导出,导入的时候使用require,代码类似如下:

1

2

//index.js

let test = require('./app')