理解 module.exports和node.js的exports

https://www.sitepoint.com/understanding-module-exports-exports-node-js/

What is a Module

什么是模块

A module encapsulates related code into a single unit of code. When creating a module, this can be interpreted as moving all related functions into a file. Let’s illustrate this point with an example involving an application built with Node.js. Imagine that we created a file called greetings.js and it contains the following two functions:

模块是把一些代码封装在一起的玩意儿。当创建一个模块的时候,这个可以被理解为把很多相关的函数放到一个文件里面。我们来看一个例子,假设我们创建了一个文件叫做greetings.js 包含如下两个函数

// greetings.js
sayHelloInEnglish = function() {
  return "Hello";
};

sayHelloInSpanish = function() {
  return "Hola";
};

Exporting a Module

导出模块

The utility of greetings.js increases when its encapsulated code can be utilized in other files. So let’s refactor greetings.js to achieve this goal. To comprehend what is actually happening, we can follow a three-step process:
使用 greetings.js 提高党这个封装的代码能够被文件调用。我们用下面三个方式

1) Imagine that this line of code exists as the first line of code in greetings.js:

// greetings.js
var exports = module.exports = {};

2) Assign any expression in greetings.js that we want to become available in other files to the exports object:
在greetings.js 中我们希望能够在别的文件中使用,导出对象

// greetings.js
// var exports = module.exports = {};

exports.sayHelloInEnglish = function() {
  return "HELLO";
};

exports.sayHelloInSpanish = function() {
  return "Hola";
};

In the code above, we could have replaced exports with module.exports and achieved the same result. If this seems confusing, remember that exports and module.exports reference the same object.
在这个代码中,我们用exports替换了module.exports。

3) This is the current value of module.exports:

module.exports = {
  sayHelloInEnglish: function() {
    return "HELLO";
  },

sayHelloInSpanish: function() {
    return "Hola";
  }
};

Importing a Module

导入模块
Let’s import the publicly available methods of greetings.js to a new file called main.js. This process can be described in three steps:
这个是重要的导入一个greetings.js 叫做main.js. 分三步来做

1) The keyword require is used in Node.js to import modules. Imagine that this is how require is defined:

var require = function(path) {

// ...

return module.exports;
};

看到没,虽然用require 但是指上是module.exports

2) Let’s require greetings.js in main.js:
我们require一下greeting.js

// main.js
var greetings = require("./greetings.js");

The above code is equivalent to this:
和下面等价

// main.js
var greetings = {
  sayHelloInEnglish: function() {
    return "HELLO";
  },

sayHelloInSpanish: function() {
    return "Hola";
  }
};

3) We can now access the publicly available methods of greetings.js as a property of our greetings variable in main.js.
我们可以访问greetings.js

// main.js
var greetings = require("./greetings.js");

// "Hello"
greetings.sayHelloInEnglish();

// "Hola" 
greetings.sayHelloInSpanish();

Important Points

重点
The keyword require returns an object, which references the value of module.exports for a given file. If a developer unintentionally or intentionally re-assigns module.exports to a different object or different data structure, then any properties added to the original module.exports object will be unaccessible.
关键字require返回一个对象,这个指向module.exports对一个指定的文件,如果开发者再次指向module.export 到一个不同的对象或者数据结构,那么任何添加到module.exports 的对象就不能被访问到

An example will help elaborate this point:

// greetings.js
// var exports = module.exports = {};

exports.sayHelloInEnglish = function() {
  return "HELLO";
};

exports.sayHelloInSpanish = function() {
  return "Hola";
};

/* 

this line of code re-assigns  

module.exports
*/
module.exports = "Bonjour";

Now let’s require greetings.js in main.js:
然后我们require一下

// main.js
var greetings = require("./greetings.js");

At this moment, nothing is different than before. We assign the variable greetings to any code that is publicly available in greetings.js.
没有和之前的不同

The consequence of re-assigning module.exports to a data structure other than its default value is revealed when we attempt to invoke sayHelloInEnglish and sayHelloInSpanish:
我们重新绑定了module.exports到一个变量

// main.js
// var greetings = require("./greetings.js");

/*

TypeError: object Bonjour has no 

method 'sayHelloInEnglish'
*/
greetings.sayHelloInEnglish();
/* 

TypeError: object Bonjour has no 

method 'sayHelloInSpanish'
*/
greetings.sayHelloInSpanish();

Now let’s require greetings.js in main.js:

// main.js
var greetings = require("./greetings.js");

At this moment, nothing is different than before. We assign the variable greetings to any code that is publicly available in greetings.js.

The consequence of re-assigning module.exports to a data structure other than its default value is revealed when we attempt to invoke sayHelloInEnglish and sayHelloInSpanish:

// main.js
// var greetings = require("./greetings.js");

/*

TypeError: object Bonjour has no 

method 'sayHelloInEnglish'
*/
greetings.sayHelloInEnglish();
/* 

TypeError: object Bonjour has no 

method 'sayHelloInSpanish'
*/
greetings.sayHelloInSpanish();

To understand why these errors are occuring, let’s log the value of greetings to a console:

// "Bonjour"
console.log(greetings);

At this point, we are trying to access the methods sayHelloInEnglish and sayHelloInSpanish on the string “Bonjour.” module.exports, in other words, is no longer referencing the default object that contain those methods.

Conclusion

Importing and exporting modules is a ubiqutous task in Node.js. I hope that the difference between exports and module.exports is clearer. Moreover, if you ever encounter an error in accessing publicly available methods in the future, then I hope that you have a better understanding of why those errors may occur.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值