Node.js module.exports的用途是什么,如何使用它?

我似乎找不到任何相关信息,但它似乎是Node.js的重要组成部分,正如我在源代码中经常看到的那样。

根据Node.js文档 :

模组

对当前module引用。 特别是module.exports与导出对象相同。 有关更多信息,请参见src/node.js

但这并没有真正的帮助。

module.exports到底是做什么的,一个简单的例子是什么?


#1楼

这已经得到回答,但是我想补充一些澄清...

您可以使用这两个exportsmodule.exports导入代码到你的应用程序是这样的:

var mycode = require('./path/to/mycode');

您将看到的基本用例(例如,在ExpressJS示例代码中)是在.js文件中的exports对象上设置属性,然后使用require()进行导入

因此,在一个简单的计数示例中,您可以拥有:

(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

简而言之,您可以将所需的文件视为返回单个对象的函数,并且可以通过在exports上设置它们来为返回的对象添加属性(字符串,数字,数组,函数,任何东西)。

有时,您希望从require()调用返回的对象成为可以调用的函数,而不仅仅是具有属性的对象。 在这种情况下,您还需要设置module.exports ,如下所示:

(sayhello.js):

module.exports = exports = function() {console.log("Hello World!");
};

(app.js):

var sayHello = require('./sayhello.js');
sayHello(); // "Hello World!"

在此答案中,可以更好地解释export和module.exports之间的区别。


#2楼

请注意,NodeJS模块机制基于CommonJS模块,该模块在RequireJS等许多其他实现中也受支持,还包括SproutCoreCouchDBWakandaOrientDBArangoDBRingoJSTeaJSSilkJScurl.js甚至Adobe Photoshop (通过PSLib) )。 您可以在此处找到已知实现的完整列表。

除非你的模块使用节点特定功能或模块,我强烈建议您使用再exports ,而不是module.exports 这不是CommonJS的标准的一部分 ,然后大多没有其他实现的支持。

NodeJS的另一项特定功能是,当您分配对要exports的新对象的引用时,不像Jed Watson在此线程中提供的最后一个示例那样向其添加属性和方法。 我个人不赞成这种做法,因为这破坏了CommonJS模块机制的循环引用支持 。 然后,并非所有实现都支持它,然后应以这种方式(或类似方式)编写Jed示例,以提供一个更通用的模块:

(sayhello.js):

exports.run = function() {console.log("Hello World!");
}

(app.js):

var sayHello = require('./sayhello');
sayHello.run(); // "Hello World!"

或使用ES6功能

(sayhello.js):

Object.assign(exports, {// Put all your public API heresayhello() {console.log("Hello World!");}
});

(app.js):

const { sayHello } = require('./sayhello');
sayHello(); // "Hello World!"

PS:看来Appcelerator也实现了CommonJS模块,但是没有循环引用支持(请参阅: Appcelerator和CommonJS模块(缓存和循环引用) )


#3楼

有的几件事情,如果你分配给新的对象的引用你必须要小心exports和/或modules.exports

1.先前附加到原始exportsmodule.exports所有属性/方法都将丢失,因为导出的对象现在将引用另一个新对象

这很明显,但是如果您在现有模块的开头添加导出的方法,请确保本机导出的对象在末尾没有引用另一个对象

exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported objectmodule.exports.method3 = function () {}; // exposed with method1 & method2var otherAPI = {// some properties and/or methods
}exports = otherAPI; // replace the original API (works also with module.exports)

2.如果exportsmodule.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.棘手的结果。 如果更改,参照上述两个exportsmodule.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() {};

#4楼

module.exports属性或exports对象允许模块选择应与应用程序共享的内容

我在此处有关于module_export的视频


#5楼

引用链接是这样的:

exports = module.exports = function(){//....
}

的属性exportsmodule.exports ,如函数或变量,将被暴露在外

需要注意的一点:不要override出口。

为什么呢?

因为导出仅是module.exports的引用,所以可以将属性添加到导出中,但是如果覆盖导出,则引用链接将断开。

好例子 :

exports.name = 'william';exports.getName = function(){console.log(this.name);
}

不好的例子:

exports = 'william';exports = function(){//...
}

如果您只想公开一个函数或变量,例如:

// test.js
var name = 'william';module.exports = function(){console.log(name);
}   // index.js
var test = require('./test');
test();

此模块仅公开一个功能,并且name的属性是外部专有的。


#6楼

将程序代码划分为多个文件时, module.exports用于将变量和函数发布给模块的使用者。 源文件中的require()调用将替换为相应的module.exports从模块中加载。

在编写模块时记住

  • 模块加载被缓存,只有初始调用评估JavaScript。
  • 可以在模块内使用局部变量和函数,而不需要导出所有内容。
  • module.exports对象也可用作exports简写。 但是,当返回唯一函数时,请始终使用module.exports

根据: “模块第2部分-编写模块” 。


#7楼

模块将相关代码封装到单个代码单元中。 创建模块时,这可以解释为将所有相关功能移动到文件中。

假设有一个文件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;

现在,您只需要在World.js中输入文件名即可使用这些功能

var world= require("./hello.js");

#8楼

当您下载并安装诸如http,sys等的node.js时,node.js中有一些默认或现有的模块。

因为它们已经在node.js中,所以当我们想使用这些模块时,我们基本上喜欢导入模块 ,但是为什么呢? 因为它们已经存在于node.js中。 导入就像将它们从node.js中取出并放入程序中一样。 然后使用它们。

尽管Exports恰好相反,但是您正在创建所需的模块,比如说模块additioning.js并将该模块放入node.js,则可以通过导出来完成。

之前,我在这里写东西,记住,module.exports.additionTwo是一样exports.additionTwo

嗯,这就是原因,我们确实喜欢

exports.additionTwo = function(x)
{return x+2;};

小心路径

假设您已经创建了一个additional.js模块,

exports.additionTwo = function(x){
return x + 2;
};

在NODE.JS命令提示符下运行此命令时:

node
var run = require('addition.js');

这会出错说

错误:找不到模块additional.js

这是因为由于我们未提及路径,所以node.js进程无法执行additional.js。 因此,我们可以使用NODE_PATH设置路径

set NODE_PATH = path/to/your/additon.js

现在,这应该可以成功运行,没有任何错误!!

还有一件事,您还可以通过不设置NODE_PATH来运行additional.js文件,回到您的nodejs命令提示符:

node
var run = require('./addition.js');

因为我们在这里通过说路径位于当前目录中来提供路径./这也应该成功运行。


#9楼

目的是:

模块化编程是一种软件设计技术,它强调将程序的功能分成独立的,可互换的模块,以便每个模块都包含执行所需功能的一个方面所必需的所有内容。

维基百科

我想如果没有模块化/可重用的代码就很难编写大型程序。 在nodejs中,我们可以使用module.exports创建模块化程序,该程序定义了我们公开的内容以及使用require组成程序。

试试这个例子:

fileLog.js

function log(string) { require('fs').appendFileSync('log.txt',string); }module.exports = log;

stdoutLog.js

function log(string) { console.log(string); }module.exports = log;

程式

const log = require('./stdoutLog.js')log('hello world!');

执行

$节点program.js

你好,世界!

现在尝试将./stdoutLog.js交换为./fileLog.js


#10楼

模块系统的目的是什么?

它完成以下任务:

  1. 防止文件膨胀到很大的尺寸。 在开发过程中,通常很难处理包含5000行代码的文件。
  2. 加强关注点分离。 将我们的代码分成多个文件,使我们可以为每个文件使用适当的文件名。 这样,我们可以轻松地确定每个模块的功能以及在哪里找到它(假设我们已经制定了逻辑目录结构,这仍然是您的责任)。

拥有模块可以更轻松地查找代码的某些部分,从而使我们的代码更具可维护性。

它是如何工作的?

NodejS使用以下列方式工作的CommomJS模块系统:

  1. 如果文件要导出内容,则必须使用module.export语法对其进行声明。
  2. 如果文件要导入某些内容,则必须使用require('file')语法对其进行声明

例:

test1.js

const test2 = require('./test2');    // returns the module.exports object of a filetest2.Func1(); // logs func1
test2.Func2(); // logs func2

test2.js

module.exports.Func1 = () => {console.log('func1')};exports.Func2 = () => {console.log('func2')};

其他有用的事情要知道:

  1. 模块正在被缓存 。 当您在2个不同的文件中加载同一模块时,该模块仅需加载一次。 第二次在同一模块上调用require()时,将其从缓存中拉出。
  2. 模块以同步方式加载 。 此行为是必需的,如果它是异步的,我们将无法立即访问从require()检索到的对象。

#11楼

module.exports是由于require调用而实际返回的对象。

最初, exports变量设置为相同的对象(即,它是“ alias”的简写),因此在模块代码中,您通常会编写如下代码:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;

导出(或“暴露”)内部作用域函数myFunc1myFunc2

在调用代码中,您将使用:

const m = require('./mymodule');
m.myFunc1();

最后一行显示require的结果(通常)只是一个可以访问其属性的普通对象。

注意:如果您覆盖exports则它将不再引用module.exports 。 因此,如果您希望为exports分配一个新对象(或函数引用),则还应该将该新对象分配给module.exports


值得注意的是,添加到exports对象的名称不必与要添加的值的模块内部作用域名称相同,因此您可以:

let myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required

其次是:

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName

#12楼

let test = function() {return "Hello world"
};
exports.test = test;

Node.js module.exports的用途是什么,如何使用它?相关推荐

  1. Node.js module.exports与导出

    by lazlojuly 通过lazlojuly Node.js module.exports与导出 (Node.js module.exports vs. exports) 它们是什么,如何使用它们 ...

  2. node.js中exports与module.exports的区别分析

    前言 关于Node.js中的exports和module.exports,很多时候都比较容易让人混淆,弄不清楚两者间的区别.那么我们就从头开始理清这两者之间的关系. 来源 在开发Node.js应用的时 ...

  3. Node.js中exports、module.exports、require之间的关系

    Node中的js文件 Node中的每个JS文件都是一个单独的模块,模块中包含的核心变量:exports.module.exports.require nodejs中module文档 // 插入图片 E ...

  4. node.js中exports与module.exports的区别

    CommonJS Node应用是由模块组成的,采用的是CommonJS模块规范. 根据规范一个文件就是一个模块,有自己单独的作用域,在一个文件中定义的变量,函数,类都是私有的,对其他的文件不可见. 根 ...

  5. Node.js 中 exports 和 module.exports 的区别

    每一个模块中都有一个 module 对象, module 对象中有一个 exports 对象 我们可以把需要导出的成员都放到 module.exports 这个接口对象中,也就是 module.exp ...

  6. [Node.js] Module.Require机制研究

    最近开始用Node.js写Server端的脚本,由于原来一直在做的.Net中开发理念的影响,在设计上和代码实现上尽可能地进行封装. Node.js中跟.Net中对象最相近的就是Module(模块)了, ...

  7. Node.js中exports和moudle.exports

    在Node.js模块化中,首先了解模块化作用域. 和函数作用域类似,在自定义模块中,定义的变量.方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域. 可以防止 全局作用域的变量 ...

  8. (node中)module.exports 和exports的区别

    (node中使用)module.exports 和exports的区别是什么? 用一句话来说明就是,require只会去引用module.exports这个对象的导出,不会引用exports对象的,而 ...

  9. Node.js: exports 和 module.exports 的区别

    我理解的exports 和 module.exports 的区别,欢迎大家吐槽~ 为了更好的理解 exports 和 module.exports 的关系,我们先来补点 js 基础.示例: app.j ...

最新文章

  1. struts2从action向jsp传参数
  2. OpenCV的HOG+SVM训练程序注意事项
  3. Python中json模块,字典和字符串相互转换
  4. Element UI——数字输入框解决方案
  5. 【SDL】SDL学习笔记一 SDL的子系统的初始化和退出
  6. VigiBase中搜索和眼病相关的统计数据
  7. 单目可见光静默活体检测 Binary or Auxiliary Supervision论文解读
  8. 4.01~ios开发常用的宏
  9. python装饰器测试_python 装饰器
  10. LDA-math-MCMC 和 Gibbs Sampling (我爱NLP)
  11. MySQL转账储存过程_实用的银行转账存储过程和流水号生成存储过程
  12. CentOS 5 全功能WWW服务器搭建全教程 V3.0 【转】
  13. chromium的下载和编译(流程详解)
  14. 终于明白了AOP中的方面是什么意思
  15. 直播平台源码开发关于发送短信验证码设置
  16. quoted string not properly terminated错误提示
  17. 你还为给自己的IT团队起名字,写口号烦恼吗?(较为流行的团队名称)
  18. 海思3559A的一些工具探索尝试
  19. 2017年9月10日训练日记
  20. 今天一起来探讨下 欧盟TPD

热门文章

  1. Exchange 2010 PowerShell
  2. 封装BackgroundWorker控件(提供源代码下载,F5即可见效果)
  3. hdu 2255+hdu 3395
  4. Windows程序员进阶应该看的那些书
  5. Pcap封包维护工具
  6. 这些测试细节,你注意到了吗?
  7. iOS中 点击按钮无响应
  8. mysql metadata lock(二)
  9. POJ 2891 Strange Way to Express Integers ★ (扩展欧几里德解同余式组)
  10. Elasticsearch笔记三之版本控制和插件