我们知道Node.js的实现让js也可以成为后端开发语言,
但在早先Node.js开发过程中,它的作者发现在js中并没有像其他后端语言一样有包引入和模块系统的机制。
这就意味着js的所有变量,函数都在全局中定义。这样不但会污染全局变量,更会导致暴露函数内部细节等问题。
CommonJS组织也意识到了同样的问题,于是 CommonJS组织创造了一套js模块系统的规范。我们现在所说的CommonJS指的就是这个规范。
Tips: CommonJS 是一个有志于构建 JavaScript 生态圈的组织。它有一个 邮件列表,很多开发者参与其中。 整个社区致力于提高 JavaScript 程序的可移植性和可交换性,无论是在服务端还是浏览器端。
来看一个CommonJS的例子:(index.js和moduleA.js在同级目录中)
index.js
let a = require('./moduleA');
console.log(a);
console.log(a.xxx);
moduleA.js
exports.xxx = {
name: 'moduleA'
}
执行node index.js
返回
{ xxx: { name: 'moduleA' } }
{ name: 'moduleA' }
在上面这里例子里可以发现,require和exports是相对应的。
另外你或许知道还有一个module.exports
它和exports有相同的作用,
但两者有细微的差距。
例子:
index.js
let a = require('./moduleA');
console.log(a);
console.log(a.xxx);
moduleA.js
exports = { //这里省去.xxx
name: 'moduleA'
}
这次会输出
{}
undefined
这是为什么?
本质上一个文件就是一个module,
当我们require一个文件的时候,
真正对应去找的是module.export
moduleA.js 其实等价于
module.exports = {}
exports = { //这里省去.xxx
name: 'moduleA'
}
1.module.exports 初始值为一个空对象 {}
2.exports 是指向的 module.exports 的引用
(在上面这里例子中,exports这个指针被重新赋值成了一个新的对象。)
3.require() 返回的是 module.exports 而不是 exports
(在上面这个例子中module.export没有被赋予任何值)
更多资料:
1.关于module.exports 和 exports
2.阮一峰 - CommonJS概念和语法
3.玉伯 - 从 CommonJS 到 Sea.js