理解node.js中的module.exports和exports原文链接作为开发者,我们经常会遇到需要使用不熟悉的代码的情况。我在这个过程中遇到了一个问题:我需要花多少时间去理解这些代码以及如何使用它们?一个典型的答案是:让我先开始编码,然后在时间允许的情况下进行深入研究。接下来我们将对node.js中module.exports和exports的用法有更深入的了解。注意:本文介绍了node.js中模块的使用。如果想了解浏览器内部模块的使用,可以参考这篇文章:UnderstandingJavaScriptModules:Bundling&TranspilingWhatisaModule?模块就是将文件中的相关代码封装成一个代码块。创建一个模块可以理解为将所有相关的方法移动到一个文件中。让我们使用node.js应用程序来说明这一点。使用以下两种方法创建一个名为greetings.js的文件://greetings.jssayHelloInEnglish=function(){return"Hello";};sayHelloInSpanish=function(){return"Hola";};ExportingaModuleWhenaddingcommonlogic到greetings.js,封装后的代码可以在其他文件中使用。所以让我们重构greetings.js来做到这一点。为了更好的理解这个过程,我们把它分为3个步骤:1)想象一下greetings.js的第一行有这样一行代码://greetings.jsvarexports=module.exports={};2)问候语。js中的方法赋值给exports对象,供其他文件使用://greetings.js//varexports=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";}};导入我们在main中的模块。js中requiregreetings.js的公共接口。这个过程有以下三个步骤:1)在node.js中使用关键字require导入模块,即获取模块的exports对象。我们可以想象它是这样定义的:varrequire=function(path){//...returnmodule.exports;};2)requiregreetings.jsinmain.js//main.jsvargreetings=require(“./greetings.js”);上面的代码等同于://main.jsvargreetings={sayHelloInEnglish:function(){return"HELLO";},sayHelloInSpanish:function(){return"Hola";}};3)现在我们可以在main.js中使用greetings来访问greetings.js中公开的方法作为它的属性。//main.jsvargreetings=require("./greetings.js");//"你好"greetings.sayHelloInEnglish();//"Hola"greetings.sayHelloInSpanish();SalientPointsrequire返回一个对象,该对象引用了module.exports的值。如果开发者无意或有意将module.exports分配给另一个对象,或者分配不同的数据结构,这将使原始module.exports对象中包含的属性失效。让我们看一个复杂的例子来说明这一点。//greetings.js//varexports=module.exports={};exports.sayHelloInEnglish=function(){return"HELLO";};exports.sayHelloInSpanish=function(){return"Hola";};/**这行代码重新赋值*module.exports*/module.exports="Bonjour";在main.js中需要greetings.js//main.jsvargreetings=require("./greetings.js");这时候,和之前并没有什么变化。我们将greetings.js中公开的方法分配给greetings变量。当我们尝试调用sayHelloInEnglish和sayHelloInSpanish时,结果发现module.exports被重新分配为不同于默认的新数据格式。//main.js//vargreetings=require("./greetings.js");/**TypeError:对象Bonjour没有*方法'sayHelloInEnglish'*/greetings.sayHelloInEnglish();/**TypeError:对象Bonjour没有*方法'sayHelloInSpanish'*/greetings.sayHelloInSpanish();为了清楚的知道这个错误的原因,我们把greetings的结果打印出来://"Bonjour"console.log(greetings);此时,我们尝试按照module.exports中抛出的字符串“Bonjour”来调用sayHelloInEnglish和sayHelloInSpanish方法,换句话说,我们永远不会引用module.exports默认输出对象中的方法。结论导入和导出模块是node.js中普遍存在的任务。我希望exports和module.exports之间的区别更清楚。此外,如果将来您在调用公共方法时遇到错误,我希望您能更好地了解导致这些错误的原因。
