Node.js module.exports的目的是什么?你如何使用它?
Node.js module.exports的目的是什么?你如何使用它?
我似乎无法find任何有关这方面的信息,但它似乎是Node.js的一个相当重要的部分,因为我经常在源代码中看到它。
根据Node.js文档 :
模
对当前
module
引用。 特别是module.exports
和exports对象是一样的。 有关更多信息,请参阅src/node.js
但是这并没有真正的帮助。
module.exports
做了什么,一个简单的例子是什么?
module.exports
是作为require
调用的结果实际返回的对象。
exports
variables最初设置为同一个对象(即它是一个简写“别名”),所以在模块代码中,您通常会这样写:
var myFunc1 = function() { ... }; var myFunc2 = function() { ... }; exports.myFunc1 = myFunc1; exports.myFunc2 = myFunc2;
导出(或“公开”)内部作用域函数myFunc1
和myFunc2
。
在调用代码中,您可以使用:
var m = require('mymodule'); m.myFunc1();
最后一行显示了require
的结果是如何(通常)只是一个普通对象的属性可以被访问。
注意:如果你覆盖exports
那么它将不再引用module.exports
。 所以,如果你想分配一个新的对象(或一个函数引用) exports
那么你也应该分配新的对象到module.exports
值得注意的是,添加到exports
对象的名称不必与您要添加的值的模块内部作用域名称相同,因此您可以:
var myVeryLongInternalName = function() { ... }; exports.shortName = myVeryLongInternalName; // add other objects, functions, as required
其次是:
var m = require('mymodule'); m.shortName(); // invokes module.myVeryLongInternalName
这已经得到了答复,但我想补充一些澄清…
您可以使用exports
和module.exports
将代码导入到您的应用程序中,如下所示:
var mycode = require('./path/to/mycode');
您将看到的基本用例(例如,在ExpressJS示例代码中)是,您可以使用require()
导入.js文件中的exports
对象的属性。
所以在一个简单的计数例子中,你可以有:
(counter.js):
var count = 1; exports.increment = function() { count++; }; exports.getCount = function() { return count; };
然后在你的应用程序(web.js,或者其他任何.js文件)中:
var counting = require('./counter.js'); console.log(counting.getCount()); // 1 counting.increment(); console.log(counting.getCount()); // 2
简而言之,您可以将所需的文件视为返回单个对象的函数,您可以将属性(string,数字,数组,函数,任何内容)添加到通过设置exports
返回的对象中。
有时你会希望从require()
调用返回的对象是一个可以调用的函数,而不仅仅是一个具有属性的对象。 在这种情况下,您还需要设置module.exports
,如下所示:
(sayhello.js):
module.exports = exports = function() { console.log("Hello World!"); };
(app.js):
var sayHello = require('./sayhello.js'); sayHello(); // "Hello World!"
出口和module.exports之间的区别在这里的答案更好地解释。
请注意,NodeJS模块机制基于CommonJS模块,这些模块在RequireJS , SproutCore , CouchDB , Wakanda , OrientDB , ArangoDB , RingoJS , TeaJS , SilkJS , curl.js甚至Adobe Photoshop (通过PSLib )。 您可以在这里find已知实现的完整列表。
除非你的模块使用节点特定的function或模块,否则我强烈build议你使用module.exports
,而不是使用module.exports
,它不是CommonJS标准的一部分 ,然后大部分不被其他实现支持。
另一个NodeJS特有的function是当你分配一个引用到一个新的对象来exports
而不是像在Jed Watson在这个线程中提供的最后一个例子那样只是添加属性和方法。 我个人不鼓励这种做法,因为这打破了CommonJS模块机制的循环引用支持 。 那么所有的实现都不支持Jed例子,然后用这种方式(或类似的方法)来编写Jed例子来提供一个更通用的模块:
(sayhello.js):
exports.run = function() { console.log("Hello World!"); }
(app.js):
var sayHello = require('./sayhello'); sayHello.run(); // "Hello World!"
或者使用ES6function
(sayhello.js):
Object.assign(exports, { // Put all your public API here sayhello() { console.log("Hello World!"); } });
(app.js):
const { sayHello } = require('./sayhello'); sayHello(); // "Hello World!"
PS:看起来Appcelerator也实现了CommonJS模块,但是没有循环引用支持(参见: Appcelerator和CommonJS模块(caching和循环引用) )
如果将一个新对象的引用分配给exports
和/或modules.exports
则必须注意几件事情:
1.以前连接到原始exports
或module.exports
所有属性/方法当然会丢失,因为导出的对象现在将引用另一个新的
这一点很明显,但是如果您在现有模块的开头添加一个导出的方法,请确保本地导出的对象不在最后引用另一个对象
exports.method1 = function () {}; // exposed to the original exported object exports.method2 = function () {}; // exposed to the original exported object module.exports.method3 = function () {}; // exposed with method1 & method2 var otherAPI = { // some properties and/or methods } exports = otherAPI; // replace the original API (works also with module.exports)
2.如果exports
或module.exports
中的一个引用新值,则不会再引用同一个对象
exports = function AConstructor() {}; // override the original exported object exports.method2 = function () {}; // exposed to the new exported object // method added to the original exports object which not exposed any more module.exports.method3 = function () {};
3.棘手的后果。 如果你改变了对module.exports
和module.exports
的引用,很难说哪个API被暴露(看起来像module.exports
获胜)
// override the original exported object module.exports = function AConstructor() {}; // try to override the original exported object // but module.exports will be exposed instead exports = function AnotherConstructor() {};
module.exports属性或exports对象允许模块select应该与应用程序共享的内容
我在这里有一个关于module_export的video
将程序代码分割为多个文件时,使用module.exports
将variables和函数发布到模块的使用者。 源文件中的require()
调用被从模块加载的相应的module.exports
replace。
记得在编写模块时
- 模块加载caching,只有初始调用评估JavaScript。
- 可以在模块中使用本地variables和函数,而不是所有的东西都需要导出。
-
module.exports
对象也可用作exports
速记。 但是当返回唯一的函数时,总是使用module.exports
。
根据: “模块第2部分 – 编写模块” 。
参考链接是这样的:
exports = module.exports = function(){ //.... }
exports
或module.exports
的属性,如函数或variables,将暴露在外面
有一点你必须多加注意:不要override
出口。
为什么?
因为导出只是module.exports的引用,所以可以将属性添加到导出,但是如果覆盖导出,则引用链接将被打破。
很好的例子:
exports.name = 'william'; exports.getName = function(){ console.log(this.name); }
不好的例子:
exports = 'william'; exports = function(){ //... }
如果你只想暴露一个函数或variables,像这样:
// test.js var name = 'william'; module.exports = function(){ console.log(name); } // index.js var test = require('./test'); test();
这个模块只暴露了一个function,名称的属性是私人的。
在下载和安装node.js(如http,sys等)时,node.js中有一些默认或现有模块。
既然他们已经在node.js中,当我们想要使用这些模块时,我们基本上就像导入模块一样 ,但为什么呢? 因为它们已经存在于node.js中 导入就像从node.js中取出它们并把它们放到你的程序中。 然后使用它们。
而出口正好相反,你正在创build你想要的模块,让我们说模块addition.js和把模块放入node.js,你通过导出它。
在我写任何东西之前,请记住, module.exports.additionTwo和exports.additionTwo是一样的
呵呵,所以这就是我们喜欢的原因
exports.additionTwo = function(x) {return x+2;};
小心path
比方说,你已经创build了一个addition.js模块,
exports.additionTwo = function(x){ return x + 2; };
当你在NODE.JS命令提示符下运行这个命令时:
node var run = require('addition.js');
这将错误地说
错误:无法find模块addition.js
这是因为我们没有提到path,所以node.js进程无法执行addition.js。 所以,我们可以使用NODE_PATH来设置path
set NODE_PATH = path/to/your/additon.js
现在,这应该成功运行没有任何错误!
还有一件事,您也可以通过不设置NODE_PATH来运行addition.js文件,返回到您的nodejs命令提示符:
node var run = require('./addition.js');
由于我们通过在当前目录中提供path来提供这个path./
也应该成功运行。
一个模块将相关代码封装到一个单一的代码单元中。 当创build一个模块时,这可以解释为将所有相关的函数移动到一个文件中。
假设有一个包含两个函数的文件Hello.js
sayHelloInEnglish = function() { return "Hello"; }; sayHelloInSpanish = function() { return "Hola"; };
我们只在代码的工具不止一个调用时才写一个函数。
假设我们要将函数的实用程序增加到不同的文件中,比如说World.js,在这种情况下,导出一个文件进入到可以通过module.exports获取的图片。
您可以通过下面给出的代码来导出这两个函数
var anyVariable={ sayHelloInEnglish = function() { return "Hello"; }; sayHelloInSpanish = function() { return "Hola"; }; } module.export=anyVariable;
现在,您只需要将文件名称inputWorld.js即可使用这些函数
var world= require("./hello.js");