邃晓 node.js 中的 module.exports 与 exports
作为一个开发者,我们经常会碰到须要运用不熟悉的代码的状况。
在这个历程当中碰到一个题目:我须要消费若干时刻去邃晓这些代码,邃晓怎样运用?
一个典范的回复就是:先让我能够最先coding,比及时刻许可再去做深入研究。
接下来我们将对 module.exports 和 exports 在 node.js中的运用有一个更好地相识。
Note: 这篇文章包括了 node 中 module 的运用。假如你想相识浏览器内部 modules 的运用,能够参考这面这篇文章:
Understanding JavaScript Modules: Bundling & Transpiling
What is a Module?
一个模块就是将文件中相干的代码封装为一个代码块。
建立一个module,能够邃晓为将一切相干的要领挪到一个文件中。
我们运用一个node.js的应用程序来申明一下这个看法。
建立一个名叫 greetings.js 的文件,个中包括下面两个要领:
// greetings.js
sayHelloInEnglish = function() {
return "Hello";
};
sayHelloInSpanish = function() {
return "Hola";
};
Exporting a Module
为了 greetings.js 大众逻辑增添的时刻,其封装的代码能够在其他文件中运用。所以我们
重构一下 greetings.js 来到达这个目标。为了更好地邃晓这个历程,我们分为3步:
1) 设想一下有这么一行代码在 greetings.js 的第一行:
// greetings.js
var exports = module.exports = {};
2) 把greetings.js中的要领赋值给exports对象在其他文件中运用:
// greetings.js
// var exports = module.exports = {};
exports.sayHelloInEnglish = function() {
return "HELLO";
};
exports.sayHelloInSpanish = function() {
return "Hola";
};
在上面的代码中,我们能够运用 module.exports 替代 exports到达雷同的效果。
这看起来好像有些疑心,请记着:exports 和 module.exports援用的是统一对象。
3) 此时 module.exports 是如许的:
module.exports = {
sayHelloInEnglish: function() {
return "HELLO";
},
sayHelloInSpanish: function() {
return "Hola";
}
};
Importing a Module
我们在 main.js 中 require greetings.js 的公然接口。这个历程有以下三个步骤:
1)关键词 require 在 node.js 中用于导入模块,即所猎取模块的 exports 对象。
我们能够想到它是这么定义的:
var require = function(path) {
// ...
return module.exports;
};
2) 在 main.js 中 require greetings.js
// main.js
var greetings = require("./greetings.js");
上面的代码等同于:
// main.js
var greetings = {
sayHelloInEnglish: function() {
return "HELLO";
},
sayHelloInSpanish: function() {
return "Hola";
}
};
3) 如今我们能够在 main.js 中运用greetings接见 greetings.js 中公然的要领就像猎取它的属性一样。
// main.js
var greetings = require("./greetings.js");
// "Hello"
greetings.sayHelloInEnglish();
// "Hola"
greetings.sayHelloInSpanish();
Salient Points 重点
require 返回一个 object ,该对象援用了 module.exports 的值。
假如开发者无意或故意的将 module.exports 赋值给别的一个对象,
或许给予差别的数据结构,如许会致使本来的 module.exports 对象
所包括的属性失效。
看一个庞杂的示例去申明这个看法。
// greetings.js
// var exports = module.exports = {};
exports.sayHelloInEnglish = function() {
return "HELLO";
};
exports.sayHelloInSpanish = function() {
return "Hola";
};
/*
* this line of code re-assigns
* module.exports
*/
module.exports = "Bonjour";
在 main.js 中require greetings.js
// main.js
var greetings = require("./greetings.js");
此时,和之前并没有任何变化。我们将greetings.js中公然的要领
赋值给greetings变量。
当我们试图挪用sayHelloInEnglish和sayHelloInSpanish效果显现为
module.exports 从新赋值给一个新的差别于默许值的数据格式。
// main.js
// var greetings = require("./greetings.js");
/*
* TypeError: object Bonjour has no
* method 'sayHelloInEnglish'
*/
greetings.sayHelloInEnglish();
/*
* TypeError: object Bonjour has no
* method 'sayHelloInSpanish'
*/
greetings.sayHelloInSpanish();
为了清楚地晓得这个毛病缘由,我们将greetings的效果打印出来:
// "Bonjour"
console.log(greetings);
在这个点上,我们试着在 module.exports 抛出来的字符串”Bonjour” 去挪用 sayHelloInEnglish 和 sayHelloInSpanish
要领,换句话说,我们永久也不会援用到 module.exports 默许输出object内里的要领。
Conclusion 总结
importing 和 exporting 模块在 node.js 中是一个随处可见的使命。
我愿望 exports 和 module.exports之间的差别越发清楚。
另外,假如未来你碰到挪用大众要领毛病的时刻,我愿望你能够对这些
毛病的缘由有一个更好地邃晓。