当文件需要一个没有任何输出的模块时,对Node.js的行为感到困惑

我对Node.js的require()函数和module.exports的function和特性有了一个总体和高层次的理解。 但是,有一些行为对我来说没有意义。

比方说,我有两个非常简单的单行文件a.jsb.js

a.js

 require('./b.js'); 

b.js

 console.log("testing"); 

如果我在terminal中运行node a.js ,这是什么logging:

 $ node a.js testing. 

这意味着只需要一个文件/模块,请求文件的内容就会暴露给发出请求的文件(对吧?)


现在我修改a.js到这个:

 require('./b.js'); testFunc(1, 2); 

和b.js到这个:

 var testFunc = function(a, b) { var result = a + b; return result; } 

并再次运行terminal中的node a.js

 $ node a.js /demo/a.js:3 testFunc(1, 2); ^ ReferenceError: testFunc is not defined ...... 

那么这里发生了什么? 显然,在第一个例子中,通过要求b.jsa.js可以访问a.js中的内容。 然而,在第二个例子中, b.js定义的函数b.js不可访问,如ReferenceError: testFunc is not defined 。 这里有什么窍门?

是否因为require()只运行所需的脚本,而不实际将其内容暴露给请求文件? 因此,为了使用其他模块的内容,必须使用module.exports来暴露该模块。

你的理解是有缺陷的。

“文件的内容暴露给发出请求的文件”一般不会,只有module.exports是暴露的。

节点模块在自己的范围内运行,以便模块中的任何代码都不能在其外部访问。

模块包装文档

 (function (exports, require, module, __filename, __dirname) { // Your module code actually lives in here }); 

您将看到控制台日志,因为所有控制台消息都指向相同的输出,在本例中是terminal。

这与console.log()消息在浏览器中的工作方式类似。 即使下面的代码在iframe运行,并且与主页面分离, iframe和主窗口中的控制台消息都将被引导至开发工具控制台。

 console.log("whoa"); 

在你的第一个案例中,没有任何东西暴露给a.js 在nodejs中,您必须将导出的值明确地存储到variables中。

也就是说,当你需要一个模块时,最高范围正在被执行,以便创build将被导出的内容。 这就是为什么你看到console.log正在执行。

如果你想从b.js导出一些东西,你必须这样做:

 module.exports = { testFunc: testFunc } 

而在a.js

 var b = require('./b.js') b.testFunc(1, 2) 

换句话说,与许多语言不同,当需要一个模块时。 没有符号被附加到全局范围,所以没有明确定义testFunc到模块testFunc ,nodejs永远不会知道testFunc是什么。

在这篇文章中可以find一个很好的答案。

当你在Node JS中需要一个脚本(在这个例子中是b.js )时,除非它被导出,否则它不能对代码做任何事情 – 除非你问脚本需要执行一个动作。

例如:

a.js

 'use strict'; let b = require('./b.js'); let result = b.testFunc(1, 4); console.log(result); 

b.js

 'use strict'; module.exports.testFunc = function(a, b) { let result = a + b; return result; } console.log(this.testFunc(5,5));