Est-il possible de passer des arguments lors du chargement d'un module en utilisant require?
J'ai le module login.js qui fournit la fonctionnalité de connexion. Cela nécessite une connexion à la base de données et je souhaite que la même connexion à la base de données soit utilisée dans tous mes modules. Maintenant, j'exporte une fonction login.setDatabase (...) qui me permet de spécifier une connexion à une base de données, et cela fonctionne très bien. Mais je préfère passer la base de données et toute autre exigence lorsque je charge le module.
var db = ...
var login = require("./login.js")(db);
Je suis assez nouveau avec NodeJS et je développe généralement en utilisant Java et Spring Framework, donc oui ... c'est une injection de constructeur :) Est-il possible de faire quelque chose comme le code que j'ai fourni ci-dessus?
app
objet aux modules requis.Réponses:
Sur la base de vos commentaires dans cette réponse , je fais ce que vous essayez de faire comme ceci:
Je structure à peu près tous mes modules comme ça. Semble bien fonctionner pour moi.
la source
app
argument est-il nécessaire ou puis-je l'omettre? Mon module n'utilisera pas explicitement cet argument d'application, mais je ne sais pas s'il est requis par node.js pour quelque chose interne. Si c'est ok, ma déclaration de module ressemblerait à ceci:module.exports = function (db) {
require(mymodule)(myargs)
vous donnerait un module avec lequel travailler. Cependant, si vous le référencez ailleurs à partir d'un autre module ?? dans le système de base, il semble y avoir un cache impliqué, mais dans ce système, le cache renverrait la méthode du générateur nu lors des appels suivants àrequire()
, et si vous vous passiez des arguments,require()(someargs)
vous récupéreriez un module différent ... peut-être que je manque quelque chosevar module;
dehors de la fonction d'exportation, puis dès que vous entrez dans le, vous voudrez vérifier simodule
est déjà défini, et si c'est le cas, renvoyez-le simplement (et sinon, initialisez-le). Cela a-t-il du sens?Je ne sais pas si cela sera toujours utile aux gens, mais avec ES6, j'ai un moyen de le faire que je trouve propre et utile.
Et puis vous obtenez votre comportement attendu.
la source
Oui. Dans votre
login
module, exportez simplement une seule fonction qui prenddb
comme argument. Par exemple:la source
module.exports = function(app,db) { ... } module.exports.auth = function(req,res) { ... authentication stuff }
il appelle la fonction "anonyme" et définit les variablesapp
etdb
, mais, en faisant cela, mon application ne trouvera pas laauth
fonction. Qu'est-ce que je fais mal? Si je supprime la fonction anonyme, laauth
fonction redevient accessible.exports
c'est un objet. Vous pouvez lui attribuer des propriétés (exportations multiples) ou lui attribuer une valeur. Il semble que vous ayez affecté des exportations à une fonction, mais que vous ayez ensuite attribué auth en tant que propriété de la fonction que vous avez affectée aux exportations. Vous devrez donc fairevar auth = require("./login.js").auth
ce qui n'est peut-être pas ce que vous vouliez. Si vous souhaitez utiliser le modèle de la question d'origine, il est probablement préférable de vous en tenir à une seule valeur d'exportation. Si cela n'a toujours pas de sens, je vous recommanderais de publier un résumé à mon avis.auth
tant que propriété de l'exports
objet, puis plus tard dans le module que vous avez attribuéexports
à une fonction (remplaçant ainsi l'affectation précédente). Si vous inversez l'ordre de l'affectation, vous devriez pouvoir accéder à laauth
fonction comme prévu. Encore une fois, c'est difficile à dire sans voir le code.var login = require('login')
etvar login = require('login')(app)
, mais il y a une énorme différence, il n'y a pas de magie dans la fonction anonyme renvoyée, c'est juste une autre fonction / objet. Au lieu d'avoir amodule.exports.auth
, la fonction anomymous renvoie maintenant la fonction auth (entre autres), iereturn { auth: authFunction, login: loginFunction}
. Alors maintenant, ça marche. Merci.