What is the purpose of Node.js module.exports and how do you use it?
node.js module.exports的目的是什么?如何使用它?
我似乎找不到关于这个的任何信息,但它似乎是node.js的一个相当重要的部分,正如我在源代码中经常看到的那样。
根据node.js文档:
module
A reference to the current
module . In particularmodule.exports 
is the same as the exports object. See
src/node.js for more information.
但这真的没有帮助。
1 2 3 4  | var myFunc1 = function() { ... }; var myFunc2 = function() { ... }; exports.myFunc1 = myFunc1; exports.myFunc2 = myFunc2;  | 
要导出(或"公开")内部范围的函数
在呼叫代码中,您将使用:
1 2  | var m = require('./mymodule'); m.myFunc1();  | 
最后一行显示了
注:如果覆盖
值得注意的是,添加到
1 2 3  | var myVeryLongInternalName = function() { ... }; exports.shortName = myVeryLongInternalName; // add other objects, functions, as required  | 
然后:
1 2  | var m = require('./mymodule'); m.shortName(); // invokes module.myVeryLongInternalName  | 
这已经得到了答复,但我想补充一些说明…
您可以使用
您将看到的基本用例(例如,在ExpressJS示例代码中)是在.js文件中设置
因此,在一个简单的计数示例中,您可以有:
(计数器。JS):
1 2 3 4 5 6 7 8 9  | var count = 1; exports.increment = function() { count++; }; exports.getCount = function() { return count; };  | 
…然后在您的应用程序中(web.js或任何其他.js文件):
1 2 3 4 5  | var counting = require('./counter.js'); console.log(counting.getCount()); // 1 counting.increment(); console.log(counting.getCount()); // 2  | 
简单来说,您可以将所需文件视为返回单个对象的函数,并且可以通过在
有时,您希望从
(您好,JS):
1 2 3  | module.exports = exports = function() { console.log("Hello World!"); };  | 
(APP.JS):
1 2  | var sayHello = require('./sayhello.js'); sayHello(); //"Hello World!"  | 
导出和module.exports之间的区别在这里的回答中解释得更好。
请注意,nodejs模块机制基于commonjs模块,在许多其他实现(如requirejs)中都支持commonjs模块,但也支持sproutcore、couchdb、wakanda、orientdb、arangodb、ringojs、teajs、silkjs、curl.js,甚至是adobe photoshop(通过pslib)。您可以在这里找到已知实现的完整列表。
除非您的模块使用特定于节点的特性或模块,否则我强烈建议您使用
另一个nodejs特定的特性是,当您将一个对新对象的引用分配给
(您好,JS):
1 2 3  | exports.run = function() { console.log("Hello World!"); }  | 
(APP.JS):
1 2  | var sayHello = require('./sayhello'); sayHello.run(); //"Hello World!"  | 
或使用ES6功能
(您好,JS):
1 2 3 4 5 6  | Object.assign(exports, { // Put all your public API here sayhello() { console.log("Hello World!"); } });  | 
(APP.JS):
1 2  | const { sayHello } = require('./sayhello'); sayHello(); //"Hello World!"  | 
PS:看起来Appcelerator也实现了CommonJS模块,但是没有循环引用支持(参见:Appcelerator和CommonJS模块(缓存和循环引用))。
如果将新对象的引用指定给
这一点很明显,但是如果您在现有模块的开头添加了一个导出方法,请确保本机导出的对象没有引用末尾的另一个对象。
1 2 3 4 5 6 7 8 9 10  | 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。如果其中一个
1 2 3 4 5  | 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 () {};  | 
三。棘手的后果。如果同时更改对
1 2 3 4 5 6  | // 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对象允许模块选择应该与应用程序共享的内容

我这里有一个关于模块输出的视频
在将程序代码划分为多个文件时,
编写模块时请记住
- 模块加载被缓存,只有初始调用才评估javascript。
 - 可以在模块内使用局部变量和函数,而不是所有的东西都需要导出。
 module.exports 对象也可用作exports 的简写。但在返回唯一函数时,始终使用module.exports 。
根据:"模块第2部分-编写模块"。
参考链接如下:
1 2 3  | exports = module.exports = function(){ //.... }  | 
有件事你必须更加注意:不要出口。
为什么?
因为只导出module.exports的引用,所以可以将属性添加到导出中,但如果覆盖导出,则引用链接将断开。
很好的例子:
1 2 3 4 5  | exports.name = 'william'; exports.getName = function(){ console.log(this.name); }  | 
坏榜样:
1 2 3 4 5  | exports = 'william'; exports = function(){ //... }  | 
如果只想公开一个函数或变量,如下所示:
1 2 3 4 5 6 7 8 9 10  | // test.js var name = 'william'; module.exports = function(){ console.log(name); } // index.js var test = require('./test'); test();  | 
此模块只公开了一个函数,name属性对于外部是私有的。
当您下载和安装node.js(如http、sys等)时,node.js中有一些默认的或现有的模块。
因为它们已经在node.js中,当我们想要使用这些模块时,我们基本上喜欢导入模块,但是为什么呢?因为它们已经存在于node.js中。导入就像从node.js中获取它们并将它们放入程序中一样。然后使用它们。
虽然exports正好相反,但您正在创建所需的模块,比如module addition.js并将该模块放入node.js中,您可以通过导出该模块来实现。
在这里写任何东西之前,请记住,module.exports.additiontwo与exports.additiontwo相同
嗯,所以这就是我们喜欢的原因
1 2  | exports.additionTwo = function(x) {return x+2;};  | 
小心这条路
假设您已经创建了addition.js模块,
1 2 3  | exports.additionTwo = function(x){ return x + 2; };  | 
在node.js命令提示符上运行此命令时:
1 2  | node var run = require('addition.js');  | 
这是错误的说法
Error: Cannot find module addition.js
这是因为node.js进程无法执行addition.js,因为我们没有提到路径。因此,我们可以通过使用节点路径来设置路径
1  | set NODE_PATH = path/to/your/additon.js  | 
现在,应该可以成功运行了,没有任何错误!!
另外,您还可以通过不设置节点路径来运行addition.js文件,返回node js命令提示:
1 2  | node var run = require('./addition.js');  | 
因为我们在这里提供的路径是说它在当前目录
一个模块将相关的代码封装成一个单独的代码单元。创建模块时,这可以解释为将所有相关函数移动到文件中。
假设有一个文件hello.js,其中包含两个函数
1 2 3 4 5 6  | sayHelloInEnglish = function() { return"Hello"; }; sayHelloInSpanish = function() { return"Hola"; };  | 
我们只在代码的实用程序不止一个调用时才编写函数。
假设我们想将函数的效用增加到一个不同的文件,比如world.js,在这种情况下,导出一个文件会进入图片,可以通过module.exports获得。
您可以通过下面给出的代码导出这两个函数
1 2 3 4 5 6 7 8 9  | var anyVariable={ sayHelloInEnglish = function() { return"Hello"; }; sayHelloInSpanish = function() { return"Hola"; }; } module.export=anyVariable;  | 
现在您只需要在world.js中输入文件名即可使用这些函数
1  | var world= require("./hello.js");  | 
目的是:
Modular programming is a software design technique that emphasizes
separating the functionality of a program into independent,
interchangeable modules, such that each contains everything necessary
to execute only one aspect of the desired functionality.
维基百科
我认为如果没有模块化/可重用的代码,编写大型程序会变得困难。在nodejs中,我们可以使用
Try this example:
FielLog.JS
1 2 3  | function log(string) { require('fs').appendFileSync('log.txt',string); } module.exports = log;  | 
StdOutLog.js
1 2 3  | function log(string) { console.log(string); } module.exports = log;  | 
JS程序
1 2 3  | const log = require('./stdoutLog.js') log('hello world!');  | 
执行
$ node program.js
hello world!
现在尝试将/stdologjs替换为/filelog.js。
What is the purpose of a module system?
它完成以下任务:
拥有模块可以更容易地找到代码的某些部分,从而使代码更易于维护。
How does it work?
例子:
Test1.JS
1 2 3 4  | const test2 = require('./test2');    // returns the module.exports object of a file test2.Func1(); // logs func1 test2.Func2(); // logs func2  | 
测试2.js
1 2 3  | module.exports.Func1 = () => {console.log('func1')}; exports.Func2 = () => {console.log('func2')};  | 
其他有用的知识: