本文转自Node.js module.exports与exports

作者: chemdemo

折腾Node.js有些日子了,下面将陆陆续续记录下使用Node.js的一些细节。

熟悉Node.js的童鞋都知道,Node.js作为服务器端的javascript运行环境,它使用npm作为通用的包管理工具,npm遵循CommonJS规范定义了一套用于Node.js模块的约定,关于npm实现Node.js模块的更多细节请细读深入Node.js的模块机制,这里简单讲下书写Node.js代码时module.exports与exorts的区别。

在浏览器端js里面,为了解决各模块变量冲突等问题,往往借助于js的闭包把所有模块相关的代码都包装在一个匿名函数里。而Node.js编写模块相当的自由,开发者只需要关注require,exports,module等几个变量就足够,而为了保持模块的可读性,很推荐把不同功能的代码块都写成独立模块,减少各模块耦合。开发者可以在“全局”环境下任意使用var申明变量(不用写到闭包里了),通过exports暴露接口给调用者。

我们经常看到类似export.xxx = yyy或者module.exports = xx这样的代码,可实际在通过require函数引入模块时会出现报错的情况,这是什么原因导致的呢?

Node.js在模块编译的过程中会对模块进行包装,最终会返回类似下面的代码:

(function (exports, require, module, __filename, __dirname) {
// module code...
});

其中,module就是这个模块本身,require是对Node.js实现查找模块的模块Module._load实例的引用,__filename和__dirname是Node.js在查找该模块后找到的模块名称和模块绝对路径,这就是官方API里头这两个全局变量的来历。

关于module.exports与exorts的区别,了解了下面几点之后应该就完全明白:

模块内部大概是这样:

exports = module.exports = {};
  • exports是module.exports的一个引用
  • require引用模块后,返回给调用者的是module.exports而不是exports
  • exports.xxx,相当于在导出对象上挂属性,该属性对调用模块直接可见
  • exports =相当于给exports对象重新赋值,调用模块不能访问exports对象及其属性
  • 如果此模块是一个类,就应该直接赋值module.exports,这样调用者就是一个类构造器,可以直接new实例

    客官如果看明白咋回事儿了下面的内容可以忽略:)

假如有模块a.js代码如下:

exports.str = 'a';
exports.fn = function() {};

对a模块的调用:

var a = require('./a');
console.log(a.str);
console.log(a.fn());

这样用是对的,如果改造a如下:

exports.str = 'a';
exports = function fn() {};

在调用a模块时自然没用fn属性了。

再改造下a模块:

exports.str = 'a';
module.exports = function fn() {};

这时a模块其实就是fn函数的引用,也就是说可以require('./a')()这样使用,而同时不再有str属性了。

下面直接导出一个类:

module.exports = function A() {};

调用:

var A = require('./a');
var a = new A();

总结下,有两点:

  1. 对于要导出的属性,可以简单直接挂到exports对象上
  2. 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到module.exports对象上,不要和导出属性值混在一起

    最后,不用再纠结module.exports与exorts什么时候该用哪个了吧~

(转)Node.js module.exports与exports的更多相关文章

  1. node.js module.exports & exports & module.export all in one

    node.js module.exports & exports & module.export all in one cjs const log = console.log; log ...

  2. Node.js & module.exports & exports

    Node.js & module.exports & exports https://www.cnblogs.com/xgqfrms/p/9493550.html exports &a ...

  3. 创建并发布node.js module

      创建node.js module. 创建一个文件夹,用来存放module. Cd到新创建的文件夹,运行npm init,会提示输入package的信息. 可以按照这个视频的来输入.Test com ...

  4. Node.js & module system

    Node.js & module system Node.js v10.9.0 Documentation https://nodejs.org/api/modules.html#module ...

  5. 如何發佈一個完整Node.js Module

    本文會透過以下幾個段落,讓各位一步一步學習如何寫一個自已的Node.js Module並且發佈到npm package上 Node.js Module 結構 我們先建立一個 NodeModuleDem ...

  6. Node.js module.exports和exports的区别

    require 用来加载代码,而 exports 和 module.exports 则用来导出代码,从接触node.js就不会它们两陌生,上代码: foo.js exports.a = functio ...

  7. [ 转]Node.js模块 require和 exports

    什么是模块? node.js通过实现CommonJS的Modules/1.0标准引入了模块(module)概念,模块是Node.js的基本组成部分.一个node.js文件就是一个模块,也就是说文件和模 ...

  8. node.js module初步理解

    在开发一个复杂的应用程序的时候,我们需要把各个功能拆分.封装到不同的文件,在需要的时候引用该文件.没人会写一个几万行代码的文件,这样在可读性.复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组 ...

  9. node.js module初步理解-(转载)

    在开发一个复杂的应用程序的时候,我们需要把各个功能拆分.封装到不同的文件,在需要的时候引用该文件.没人会写一个几万行代码的文件,这样在可读性.复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组 ...

随机推荐

  1. Linux课题实践一

    Linux课题实践一 20135318 刘浩晨 1.1应用安装 (1)掌握软件源的维护方法,配置系统使用软件源镜像  删除过期或者重复的软件包:进入”系统设置“-”软件和更新”-”ubuntu软件“- ...

  2. centos7编译安装zabbix(附带编译安装lnmp)

    先把防火墙和selinux关闭: sytemctl stop firewalld setenforce 0 1.yum安装依赖: yum -y install wget openssl* gcc gc ...

  3. GCP试用到期再申请

    目标 GCP的免费试用到期了.网传可以续用,看了教程,记录下来. 法一 应该可以直接用一个新gmail账号的.这个方法的难点可能在于注册新账号有门槛.我有一个很久以前注册过的,试着找回了密码,登入GC ...

  4. Notepad++找回Plugin Manager{在v7.50后(包括7.50)不带有插件管理器(Plugin Manager)}

    https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2459 64 bit Plugin Manager is now avai ...

  5. loadrunner基础学习笔记五-场景

    场景目标:模拟10家旅行社同时登录.搜索航班.购买机票.查看航班路线并退出 负载测试是指在典型工作条件下测试应用程序,例如:多家旅行社同时在同一个机票预订系统中预订机票 controller提供所有用 ...

  6. text/css什麼意思

    text/css用在style的type屬性中,表示style的標簽里的文本內容要當做層疊樣式表(css)來解析,放在html的頁面內部,是HTML的內部樣式表: text/html用在style的t ...

  7. pgm15

    这部分我们讨论结构学习,也就是 graph 的边我们并不清楚.很自然我们可以用 fully observed 数据来做,但是也可能碰到有 missing data 的情况.一般来说前者是比较常见的.就 ...

  8. Redis无法保存ef复杂对象

    最近项目需要使用redis. 然后我就满怀激情开始处理数据层了.在原来查询数据的基础上,有封装了一个redis缓存层. 结果在redis保存ef对象的时候,发现了一个非常尴尬的问题. model: p ...

  9. Dapper 介绍

    转载:http://***/html/itweb/20130918/125194_125199_125210.htm .NET 轻量级 ORM 框架 - Dapper 介绍 Dapper简单介绍: D ...

  10. 【 Gym - 101138F 】GukiZ Height (数学)

    BUPT2017 wintertraining(15) #4 C Gym - 101138F 题意 初始高度0,目标值h,第i天目标值会下降i,当前高度会改变a[i%n],求高度不小于目标值的最早的时 ...