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')}; |
其他有用的知识: