832 votes

le module.les exportations vs exportations en nodeJS

J'ai trouvé la suite du contrat en un nœud du module:

module.exports = exports = nano = function database_module(cfg) {...}

Je me demande quel est la différence entre module.exports et exports et pourquoi les deux sont utilisés ici.

628voto

Srle Points 589

Même question est posée et acceptée il y a longtemps, juste envie de partager mes 2 cents:

Vous pouvez imaginer que, au début de votre fichier il y a quelque chose comme (juste pour l'explication):

var module = new Module(...);
var exports = module.exports;

enter image description here

Donc, quoi que vous fassiez, gardez à l'esprit qu' module.exports et PAS exports sera retourné à partir de votre module lorsque vous exigeant que le module de quelque part d'autre.

Donc, quand vous faites quelque chose comme:

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

Vous ajoutez 2 fonction 'a' et 'b' de l'objet sur lequel le module.les exportations de points, donc trop typeof retour conséquence object : { a: [Function], b: [Function] }

Bien sûr le même résultat que vous obtiendrez si vous utilisez module.exports dans cet exemple, au lieu de exports.

C'est le cas où vous voulez que votre module.les exportations de se comporter comme des conteneur des valeurs exportées. Dans le cas d'lorsque vous souhaitez exporter uniquement la fonction constructeur, ce que vous allez faire? (Rappelez-vous que le module.les exportations sera retourné lorsque vous besoin de quelque chose pas à l'exportation).

module.exports = function Something() {
    console.log('bla bla');
}

Maintenant typeof de retourner le résultat est 'function' et vous pouvez requise, et immédiatement appeler comme:
var x = require('./file1.js')(); parce que vous écraser de retourner le résultat d'une fonction.

Pourquoi, dans ce cas, vous ne pouvez pas utiliser quelque chose comme:

exports = function Something() {
    console.log('bla bla');
}

Car avec cette export de référence n'a pas de "point" plus à l'objet auquel module.exports point, il n'existe donc pas de relation entre exports et module.exports plus. Dans ce cas le module.les exportations est toujours vide d'objet {} qui sera retourné.

Accepté de répondre à partir d'un autre sujet devrait aider aussi: N'JavaScript passer par référence?

457voto

Liam William Points 4668

Paramètre module.exports permet database_module fonction qui doit être appelée comme une fonction d'un required. Simplement paramètre exports ne permettrait pas la fonction à exporté. Le code suivant ne serait pas permettre à l'utilisateur d'appeler la fonction.

Le suivant ne fonctionnera pas.

module.js

exports = nano = function database_module(cfg) {return;}

Console

var func = require('./module.js');
// the following line will fail
func();

Ce qui suit fonctionnera si module.exports est réglé.

module.js

module.exports = exports = nano = function database_module(cfg) {return;}

Console

var func = require('./module.js');
// the following line will **work**
func();

Fondamentalement nodes.js ne pas exporter l'objet qu' exports actuellement références, mais les exportations les propriétés de ce que l' exports à l'origine des références. Bien que Node.js ne exportation de l'objet module.exports références, vous permettant de l'appeler comme une fonction.


2ème moins importante raison

Ils ont mis les deux module.exports et exports pour assurer exports n'est pas le référencement au préalable l'objet exporté. En définissant à la fois vous utilisez exports comme une abréviation, et d'éviter d'éventuels bugs plus tard en bas de la route.

À l'aide de exports.prop = true au lieu de module.exports.prop = true enregistre les caractères et permet d'éviter la confusion.

216voto

Chandu Points 1112

Fondamentalement, la réponse se trouve dans ce qui se passe vraiment quand un module est nécessaire via le 'besoin' instruction.En supposant que c'est la première fois que le module est requis.

Par exemple ,

var x = require('file1.js');

contenu de file1.js;

module.exports = '123'

Lorsque la déclaration ci-dessus est exécuté, un 'Module' objet est créé. Module de fonction constructeur ,

function Module(id, parent) {
    this.id = id;
    this.exports = {};
    this.parent = parent;
    if (parent && parent.children) {
        parent.children.push(this);
    }

    this.filename = null;
    this.loaded = false;
    this.children = [];
}

Comme vous le voyez chaque module objet possède une propriété avec le nom de l '"exportation".C'est ce qui est finalement retourné dans le cadre de l'exiger.

La prochaine étape est de les envelopper le contenu de file1.js dans une fonction anonyme comme ci-dessous :

(function (exports, require, module, __filename, __dirname) { 
    //contents from file1.js
    module.exports = '123;
});

Et cette fonction anonyme est appelée de la manière suivante, le module se réfère ici à l'Objet Module créé précédemment.

(function (exports, require, module, __filename, __dirname) { 
    //contents from file1.js
    module.exports = '123;
}) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");

Comme nous pouvons le voir à l'intérieur de la fonction , les exportations formelles argument fait référence au module.les exportations.Dans son essence un confort pour le module de programmeur.

Cependant, cette commodité doivent être exercés avec soin. En tout cas, si vous essayez d'affecter un nouvel objet pour les exportations de nous assurer de le faire de cette façon.

exports = module.exports = {};

Si nous le faisons de la manière suivante mauvais sens, module.exports sera toujours pointer vers l'objet créé dans le cadre de l'instance du module.

exports = {};

Par conséquent rien ajouter à ce qui précède, les exportations de l'objet n'aura pas d'effet sur le module.les exportations de l'objet, et rien ne sera exporté ou renvoyé dans le cadre de l'exiger.

102voto

cameron Points 618

D'abord,module.exports=exports , et l' require fonction retourne l'objet module.exports se réfère.

si nous ajouter une propriété de l'objet, disons exports.a=1, alors le module.les exportations et les exportations de toujours se référer au même objet. Donc, si nous appelons besoin et assigner le module à une variable, la variable a un bien et sa valeur est 1;

Mais si nous écraser l'un d'entre eux, par exemple, exports=function(){}, alors qu'ils sont différents maintenant: les exportations se réfère à un objet et à le module.les exportations se référer à l'objet d'origine. Et si nous avons besoin d'un fichier, il ne sera pas de retour le nouvel objet, depuis le module.les exportations n'est pas référence au nouvel objet.

Pour moi, je vais continuer à ajouter de nouveaux biens, ou de la remplacer tous les deux à un nouvel objet. Juste remplacer l'un n'est pas droit. Et gardez à l'esprit que module.exports est le vrai patron.

14voto

Lyman Lai Points 51

Je viens de faire quelques test, il s'avère que, à l'intérieur de nodejs du module code, il devrait ressembler à ça:

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

donc:

1:

exports = function(){}; // this will not work! as it make the exports to some other pointer
module.exports = function(){}; // it works! cause finally nodejs make the module.exports to export.

2:

exports.abc = function(){}; // works!
exports.efg = function(){}; // works!

3: mais, dans ce cas

module.exports = function(){}; // from now on we have to using module.exports to attach more stuff to exports.
module.exports.a = 'value a'; // works
exports.b = 'value b'; // the b will nerver be seen cause of the first line of code we have do it before (or later)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X