Verschil tussen module.exports en exports in het CommonJs Modulesysteem

Op deze pagina (http://docs.nodejitsu.com/articles/getting-started/what-is-require), staat er dat “Als u het exportobject wilt instellen op een functie of een nieuw object , moet u het object module.exports gebruiken.”

Mijn vraag is waarom.

// right
module.exports = function () {
  console.log("hello world")
}
// wrong
exports = function () {
  console.log("hello world")
}

Ik heb het resultaat gelogd (result=require(example.js)) en de eerste is [Function] de tweede is {}.

Kunt u alstublieft de reden erachter uitleggen? Ik lees het bericht hier: module.exports vs exports in Node.js . Het is nuttig, maar verklaart niet waarom het op die manier is ontworpen. Zal er een probleem zijn als de referentie van export rechtstreeks wordt geretourneerd?


Antwoord 1, autoriteit 100%

module is een eenvoudig JavaScript-object met een eigenschap exports. exports is een gewone JavaScript-variabele die toevallig is ingesteld op module.exports.
Aan het einde van je bestand zal node.js in principe module.exports ‘retourneren’ naar de functie require. Een vereenvoudigde manier om een ​​JS-bestand in Node te bekijken zou deze kunnen zijn:

var module = { exports: {} };
var exports = module.exports;
// your code
return module.exports;

Als je een eigenschap instelt op exports, zoals exports.a = 9;, zal dat ook module.exports.a instellen omdat objecten als referenties in JavaScript worden doorgegeven, wat betekent dat als je meerdere variabelen instelt op hetzelfde object, ze allemaal hetzelfde object zijn; dus dan zijn exports en module.exports hetzelfde object.
Maar als je exports instelt op iets nieuws, wordt het niet langer ingesteld op module.exports, dus exports en module.exports zijn niet langer hetzelfde object.


Antwoord 2, autoriteit 10%

Renee’s antwoord is goed uitgelegd. Aanvulling op het antwoord met een voorbeeld:

Node doet veel dingen met je bestand en een van de belangrijkste is je bestand WRAPPEN. Binnen nodejs wordt de broncode “module.exports” geretourneerd. Laten we een stap terug doen en de verpakking begrijpen. Stel dat u

greet.js

var greet = function () {
   console.log('Hello World');
};
module.exports = greet;

de bovenstaande code is als volgt verpakt als IIFE (Immediately Invoked Function Expression) in de broncode van nodejs:

(function (exports, require, module, __filename, __dirname) { //add by node
      var greet = function () {
         console.log('Hello World');
      };
      module.exports = greet;
}).apply();                                                  //add by node
return module.exports;                                      //add by node

en de bovenstaande functie wordt aangeroepen (.apply()) en module.exports geretourneerd.
Op dit moment wijzen module.exports en exports naar dezelfde referentie.

Stel je nu voor dat je herschrijft
groet.js als

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

de uitvoer zal zijn

[Function]
{}

de reden is: module.exports is een leeg object. We hebben niets ingesteld op module.exports, maar we hebben export = function()…..in new greet.js ingesteld. Dus module.exports is leeg.

Technisch gezien zouden exports en module.exports naar dezelfde referentie moeten verwijzen (dat klopt!!). Maar we gebruiken “=” bij het toewijzen van functie()… aan exports, waardoor een ander object in het geheugen wordt gemaakt. Dus module.exports en exports leveren verschillende resultaten op. Als het op export aankomt, kunnen we het niet negeren.

Stel je nu voor dat je herschrijft (dit heet Mutatie)
greet.js (verwijzend naar het antwoord van Renee) als

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

de uitvoer zal zijn

{ a: [Function] }
{ a: [Function] }

Zoals je kunt zien, verwijzen module.exports en exports naar dezelfde referentie die een functie is. Als u een eigenschap op exports instelt, wordt deze ingesteld op module.exports omdat in JS objecten worden doorgegeven door verwijzing.

De conclusie is om altijd module.exports te gebruiken om verwarring te voorkomen.
Ik hoop dat dit helpt. Veel plezier met coderen 🙂


Antwoord 3, autoriteit 4%

Ook een ding dat kan helpen om te begrijpen:

math.js

this.add = function (a, b) {
    return a + b;
};

client.js

var math = require('./math');
console.log(math.add(2,2); // 4;

Geweldig, in dit geval:

console.log(this === module.exports); // true
console.log(this === exports); // true
console.log(module.exports === exports); // true

Dus standaard is “dit” eigenlijk gelijk aan module.exports.

Als u uw implementatie echter wijzigt in:

math.js

var add = function (a, b) {
    return a + b;
};
module.exports = {
    add: add
};

In dit geval werkt het prima, maar “this” is niet meer gelijk aan module.exports, omdat er een nieuw object is gemaakt.

console.log(this === module.exports); // false
console.log(this === exports); // true
console.log(module.exports === exports); // false

En nu, wat wordt geretourneerd door de eis, is wat is gedefinieerd in module.exports, niet dit of exports, meer.

Een andere manier om dit te doen is:

math.js

module.exports.add = function (a, b) {
    return a + b;
};

Of:

math.js

exports.add = function (a, b) {
    return a + b;
};

Antwoord 4, autoriteit 2%

Rene’s antwoord over de relatie tussen exports en module.exports is vrij duidelijk, het draait allemaal om javascript-referenties. Ik wil alleen dat toevoegen:

We zien dit in veel knooppuntmodules:

var app = exports = module.exports = {};

Dit zorgt ervoor dat zelfs als we module.exports hebben gewijzigd, we exports nog steeds kunnen gebruiken door die twee variabelen naar hetzelfde object te laten verwijzen.


Antwoord 5

mijnTest.js

module.exports.get = function () {};
exports.put = function () {};
console.log(module.exports)
// output: { get: [Function], put: [Function] }

exports en module.exports zijn hetzelfde en verwijzen naar hetzelfde object. U kunt op beide manieren eigendommen toevoegen, afhankelijk van uw gemak.


Antwoord 6

Omdat alle hierboven geposte antwoorden goed zijn uitgelegd, wil ik iets toevoegen waarmee ik vandaag werd geconfronteerd.

Als je iets exporteert met behulp van exports, dan moet je het met variabele gebruiken. Vind ik leuk,

Bestand1.js

exports.a = 5;

In een ander bestand

File2.js

const A = require("./File1.js");
console.log(A.a);

en het gebruik van module.exports

Bestand1.js

module.exports.a = 5;

In File2.js

const A = require("./File1.js");
console.log(A.a);

en standaard module.exports

Bestand1.js

module.exports = 5;

in File2.js

const A = require("./File2.js");
console.log(A);

Antwoord 7

node doet zoiets als dit:

module.exports = exports = {}

module.exports en exports verwijzen naar hetzelfde object.

Dit is alleen voor het gemak gedaan.
dus in plaats van zoiets te schrijven

module.exports.PI = 3.14

we kunnen schrijven

exports.PI = 3.14

het is dus oké om een ​​eigenschap toe te voegen aan exports, maar het toewijzen aan een ander object is niet oké

exports.add = function(){
.
.
} 

^ dit is OK en hetzelfde als module.exports.add = function(){…}

exports = function(){
.
.
} 

^ dit is niet ok en een leeg object wordt geretourneerd omdat module.exports nog steeds verwijst naar {} en exports verwijst naar een ander object.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

12 − one =

Other episodes