Quel est l'objectif de Node.js module.exports et comment l'utilisez-vous?
Il semble que je ne trouve aucune information à ce sujet, mais cela semble être une partie assez importante de Node.js car je le vois souvent dans le code source.
Selon la documentation Node.js :
module
Une référence au courant
module
. En particuliermodule.exports
est identique à l'objet exporté. Voirsrc/node.js
pour plus d'informations.
Mais cela n'aide pas vraiment.
Que fait exactement module.exports
et que serait un exemple simple?
module.exports
est l'objet renvoyé à la suite d'un appel require
.
La variable exports
est initialement définie sur ce même objet (c’est-à-dire un "alias" abrégé). Ainsi, dans le code du module, vous écririez généralement quelque chose comme ceci:
var myFunc1 = function() { ... };
var myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;
exporter (ou "exposer") les fonctions étendues en interne myFunc1
et myFunc2
.
Et dans le code d'appel que vous utiliseriez:
var m = require('./mymodule');
m.myFunc1();
où la dernière ligne montre comment le résultat de require
est (généralement) juste un objet simple dont les propriétés peuvent être consultées.
NB: si vous écrasez exports
, il ne fera plus référence à module.exports
. Donc, si vous souhaitez affecter un nouvel objet (ou une référence de fonction) à exports
, vous devez également affecter ce nouvel objet à module.exports
Il convient de noter que le nom ajouté à l'objet exports
ne doit pas nécessairement être identique au nom de portée interne du module pour la valeur que vous ajoutez, de sorte que vous pourriez avoir:
var myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required
suivi par:
var m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName
Cela a déjà été répondu, mais je voulais ajouter quelques précisions ...
Vous pouvez utiliser à la fois exports
et module.exports
pour importer du code dans votre application comme ceci:
var mycode = require('./path/to/mycode');
Le cas d'utilisation de base que vous verrez (par exemple dans l'exemple de code ExpressJS) est que vous définissez les propriétés de l'objet exports
dans un fichier .js que vous importez ensuite à l'aide de require()
.
Donc, dans un exemple de comptage simple, vous pourriez avoir:
(counter.js):
var count = 1;
exports.increment = function() {
count++;
};
exports.getCount = function() {
return count;
};
... puis dans votre application (web.js ou tout autre fichier .js):
var counting = require('./counter.js');
console.log(counting.getCount()); // 1
counting.increment();
console.log(counting.getCount()); // 2
En termes simples, vous pouvez considérer les fichiers requis comme des fonctions renvoyant un seul objet et vous pouvez ajouter des propriétés (chaînes, nombres, tableaux, fonctions, etc.) à l'objet renvoyé en les définissant sur exports
.
Parfois, vous voudrez que l'objet renvoyé d'un appel require()
soit une fonction que vous puissiez appeler, plutôt qu'un simple objet avec des propriétés. Dans ce cas, vous devez également définir module.exports
, comme ceci:
(sayhello.js):
module.exports = exports = function() {
console.log("Hello World!");
};
(app.js):
var sayHello = require('./sayhello.js');
sayHello(); // "Hello World!"
La différence entre exports et module.exports est mieux expliquée dans cette réponse ici .
Notez que le mécanisme du module NodeJS est basé sur CommonJS modules pris en charge dans de nombreuses autres implémentations telles que RequireJS, mais aussi SproutCore, CouchDB, Wakanda, OrientDB, ArangoDB, RingoJS, TeaJS, SilkJS, curl.js, ou même Adobe Photoshop ( via PSLib ) . Vous pouvez trouver la liste complète des implémentations connues ici .
À moins que votre module n'utilise des fonctionnalités ou des modules spécifiques à un nœud, je vous encourage vivement à utiliser exports
au lieu de module.exports
qui ne fait pas partie du standard CommonJS et n'est généralement pas pris en charge par d'autres implémentations.
Une autre fonctionnalité spécifique à NodeJS est lorsque vous affectez une référence à un nouvel objet à exports
au lieu de lui ajouter simplement des propriétés et des méthodes, comme dans le dernier exemple fourni par Jed Watson dans ce fil. Personnellement, je découragerais cette pratique car cela brise le support de référence circulaire du mécanisme des modules CommonJS. Il n'est alors pas supporté par toutes les implémentations et Jed example devrait alors être écrit de cette façon (ou une similaire) pour fournir un module plus universel:
(sayhello.js):
exports.run = function() {
console.log("Hello World!");
}
(app.js):
var sayHello = require('./sayhello');
sayHello.run(); // "Hello World!"
Ou en utilisant les fonctionnalités ES6
(sayhello.js):
Object.assign(exports, {
// Put all your public API here
sayhello() {
console.log("Hello World!");
}
});
(app.js):
const { sayHello } = require('./sayhello');
sayHello(); // "Hello World!"
PS: Il semble qu'Appcelerator implémente également les modules CommonJS, mais sans le support de référence circulaire (voir: Modules Appcelerator et CommonJS (mise en cache et références circulaires) )
Quelques éléments à prendre en compte si vous affectez une référence à un nouvel objet à exports
et/ou modules.exports
:
exports
ou module.exports
d'origine sont bien sûr perdues car l'objet exporté référencera désormais un autre nouveauCelui-ci est évident, mais si vous ajoutez une méthode exportée au début d'un module existant, assurez-vous que l'objet exporté natif ne fait pas référence à un autre objet à la fin
exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported object
module.exports.method3 = function () {}; // exposed with method1 & method2
var otherAPI = {
// some properties and/or methods
}
exports = otherAPI; // replace the original API (works also with module.exports)
exports
ou module.exports
fait référence à une nouvelle valeur, elles ne font plus référence au même objet.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 () {};
exports
et module.exports
, il est difficile de dire quelle API est exposée (cela ressemble à module.exports
gagne)// 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() {};
la propriété module.exports ou l'objet exports permettent à un module de sélectionner ce qui doit être partagé avec l'application
J'ai une vidéo sur module_export disponible ici
Lorsque vous divisez le code de programme en plusieurs fichiers, module.exports
est utilisé pour publier des variables et des fonctions pour l'utilisateur d'un module. L’appel require()
de votre fichier source est remplacé par le module.exports
correspondant chargé à partir du module.
Rappelez-vous lorsque vous écrivez des modules
module.exports
est également disponible au format exports
. Mais lorsque vous retournez une fonction unique, utilisez toujours module.exports
.le lien de référence est comme ceci:
exports = module.exports = function(){
//....
}
les propriétés de exports
ou module.exports
, telles que des fonctions ou des variables, seront exposées à l'extérieur
vous devez faire plus attention: ne exportez pas override
.
pourquoi ?
comme les exportations ne font que contenir la référence de module.exports, vous pouvez ajouter les propriétés aux exportations, mais si vous remplacez les exportations, le lien de référence sera rompu.
bon exemple :
exports.name = 'william';
exports.getName = function(){
console.log(this.name);
}
mauvais exemple:
exports = 'william';
exports = function(){
//...
}
Si vous voulez seulement exposer une seule fonction ou variable, comme ceci:
// test.js
var name = 'william';
module.exports = function(){
console.log(name);
}
// index.js
var test = require('./test');
test();
ce module n'expose qu'une fonction et la propriété de name est privée pour l'extérieur.
Lorsque vous téléchargez et installez le fichier node.js, il existe des modules par défaut ou existants dans node.js, tels quehttp, sysetc.
Comme ils sont déjà dans node.js, lorsque nous voulons utiliser ces modules, nous faisons essentiellement comme import modules, mais pourquoi? car ils sont déjà présents dans le fichier node.js. Importer, c'est comme les prendre à partir de node.js et les insérer dans votre programme. Et puis les utiliser.
Alors queExportsest exactement le contraire, vous créez le module que vous voulez, disons le module addition.js et en le mettant dans le node.js, vous le faites en l'exportant.
Avant d’écrire quoi que ce soit ici, rappelez-vous, module.exports.additionTwo est identique à exports.additionTwo
Hein, c'est la raison, nous aimons
exports.additionTwo = function(x)
{return x+2;};
Attention au chemin
Disons que vous avez créé un module addition.js,
exports.additionTwo = function(x){
return x + 2;
};
Lorsque vous exécutez ceci sur votre invite de commande NODE.JS:
node
var run = require('addition.js');
Ce sera une erreur de dire
Erreur: impossible de trouver le module addition.js
Cela est dû au fait que le processus node.js ne peut pas ajouter.js car nous n’avons pas mentionné le chemin. Donc, nous pouvons définir le chemin en utilisant NODE_PATH
set NODE_PATH = path/to/your/additon.js
Maintenant, cela devrait fonctionner sans erreur !!
Une dernière chose, vous pouvez également exécuter le fichier addition.js en ne définissant pas NODE_PATH, à nouveau dans votre invite de commande nodejs:
node
var run = require('./addition.js');
Puisque nous fournissons le chemin ici en disant qu'il se trouve dans le répertoire en cours ./
, cela devrait également fonctionner avec succès.
Un module encapsule le code associé dans une seule unité de code. Lors de la création d'un module, cela peut être interprété comme le déplacement de toutes les fonctions associées dans un fichier.
Supposons qu'il existe un fichier Hello.js qui inclut deux fonctions
sayHelloInEnglish = function() {
return "Hello";
};
sayHelloInSpanish = function() {
return "Hola";
};
Nous écrivons une fonction seulement lorsque l'utilité du code est plus d'un appel.
Supposons que nous voulions augmenter l’utilité de la fonction dans un fichier différent, par exemple World.js. Dans ce cas, l’exportation d’un fichier entrait en image et pouvait être obtenue avec module.exports.
Vous pouvez simplement exporter la fonction à l'aide du code indiqué ci-dessous
var anyVariable={
sayHelloInEnglish = function() {
return "Hello";
};
sayHelloInSpanish = function() {
return "Hola";
};
}
module.export=anyVariable;
Maintenant, il vous suffit de demander le nom du fichier dans World.js pour pouvoir utiliser ces fonctions.
var world= require("./hello.js");
L'intention est:
La programmation modulaire est une technique de conception logicielle qui met l’accent sur séparer les fonctionnalités d'un programme en indépendantes, modules interchangeables, de sorte que chacun contienne tout le nécessaire pour n'exécuter qu'un aspect de la fonctionnalité désirée.
J'imagine qu'il devient difficile d'écrire un gros programme sans code modulaire/réutilisable. Dans nodejs, nous pouvons créer des programmes modulaires en utilisant module.exports
pour définir ce que nous exposons et composer notre programme avec require
.
Essayez cet exemple:
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;
programme.js
const log = require('./stdoutLog.js')
log('hello world!');
exécuter
$ node program.js
bonjour le monde!
Essayez maintenant de permuter ./stdoutLog.js pour ./fileLog.js.
Quel est le but d'un système de modules?
Il accomplit les choses suivantes:
Les modules facilitent la recherche de certaines parties du code, ce qui rend notre code plus facile à gérer.
Comment ça marche?
NodejS
utilise le système de module CommomJS qui fonctionne de la manière suivante:
module.export
require('file')
test1.js
const test2 = require('./test2'); // returns the module.exports object of a file
test2.Func1(); // logs func1
test2.Func2(); // logs func2
test2.js
module.exports.Func1 = () => {console.log('func1')};
exports.Func2 = () => {console.log('func2')};
require()
est appelé sur le même module, il est extrait du cache.require()
.