2012-10-31 3 views
77

Est-il possible de passer des arguments lors du chargement d'un module en utilisant require?Passage des arguments à require (lors du chargement du module)

J'ai un module, login.js qui fournit une fonctionnalité de connexion. Il 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 ça marche très bien. Mais je préfère passer la base de données et toutes les autres exigences lorsque je charge le module.

var db = ... 
var login = require("./login.js")(db); 

Je suis assez nouveau avec NodeJS et développent généralement en utilisant Java et le framework Spring, donc oui ... ceci est une injection de constructeur :) Est-il possible de faire quelque chose comme le code que je fournis ci-dessus?

+0

Je vous recommande également regarder les réponses à la question [ce] (http://stackoverflow.com/questions/13080771/node-js-passing-variables). Comme indiqué dans ma réponse, un idiome commun est de passer l'objet 'app' aux modules requis. –

+0

Au lieu de faire passer tout cet argument pour db, vous pouvez utiliser une implémentation [singleton] (http://www.dofactory.com/javascript/singleton-design-pattern) et appeler db.getInstance() si nécessaire. – wulfgarpro

Répondre

168

Sur la base de vos commentaires dans this answer, je fais ce que vous essayez de faire comme ceci:

module.exports = function (app, db) { 
    var module = {}; 

    module.auth = function (req, res) { 
     // This will be available 'outside'. 
     // Authy stuff that can be used outside... 
    }; 

    // Other stuff... 
    module.pickle = function(cucumber, herbs, vinegar) { 
     // This will be available 'outside'. 
     // Pickling stuff... 
    }; 

    function jarThemPickles(pickle, jar) { 
     // This will be NOT available 'outside'. 
     // Pickling stuff... 

     return pickleJar; 
    }; 

    return module; 
}; 

Je la structure à peu près tous mes modules comme ça. Semble fonctionner bien pour moi.

+0

Nice. Je ne sais pas vraiment quelle réponse je devrais accepter :) Ceci est pour moi aussi valable que l'autre réponse ci-dessus ... merci. –

+66

Cela ne me dérange pas - Je suis juste content d'avoir finalement pu parler de cornichons sur StackOverflow. : P – floatingLomas

+2

Cela doit être marqué comme la bonne réponse –

27

Oui. Dans votre module login, exportez simplement une seule fonction qui prend comme argument l'db. Par exemple:

module.exports = function(db) { 
    ... 
}; 
+1

J'ai essayé cela. Dans login.js 'module.exports = function (app, db) { ...} module.exports.auth = function (req, res) { ... trucs d'authentification }' Il appelle la fonction "anonyme" et définit les variables "app" et "db", mais, en faisant cela, mon application ne trouvera pas la fonction 'auth'. Qu'est-ce que je fais mal? Si je supprime la fonction anonyme, la fonction 'auth' redevient accessible. –

+0

Comme tout en javascript, 'exports' est un objet. Vous pouvez lui affecter des propriétés (exportations multiples) ou vous pouvez l'affecter à une valeur. Il semble que vous ayez affecté des exportations à une fonction, mais que vous ayez assigné auth comme propriété de la fonction que vous avez affectée aux exportations. Donc, vous auriez besoin de faire 'var auth = require (" ./ login.js "). Auth' qui n'est peut-être pas ce que vous vouliez. Si vous souhaitez utiliser le motif de la question d'origine, il est probablement préférable de s'en tenir à une seule valeur d'exportation. Si cela n'a toujours pas de sens, je vous recommande de poster un aperçu pour moi de regarder. –

+1

Après avoir relu ceci, il semblerait que vous ayez assigné 'auth' comme propriété de l'objet' exports', et plus tard dans le module vous avez assigné 'exports' à une fonction (remplaçant ainsi l'affectation précédente). Si vous inversez l'ordre de l'assignation, vous devriez pouvoir accéder à la fonction 'auth' comme vous vous en doutez. Encore une fois c'est difficile à dire sans vraiment voir le code. –

-1

Une autre façon d'aborder les choses est de définir les méthodes d'abord, puis les mettre à la disposition ci-dessous par « exportations ». (Module.exports et les exportations se réfèrent au même objet)

function kamehameha(name,fame){ 


} 

function bigbangkamehameha(name){ 

} 



exports.kamehameha=kamehameha; 
exports.bigbang=bigbangkamehameha; //bigbang refers to bigbangkamehameha 
9

Je ne suis pas sûr si cela sera toujours utile aux gens, mais avec ES6 j'ai un moyen de le faire que je trouve propre et utile.

class MyClass { 
    constructor (arg1, arg2, arg3) 
    myFunction1() {...} 
    myFunction2() {...} 
    myFunction3() {...} 
} 

module.exports = (arg1, arg2, arg3) => { return new MyClass(arg1,arg2,arg3) } 

Et puis vous obtenez votre comportement attendu.

var MyClass = require('/MyClass.js')(arg1, arg2, arg3) 
Questions connexes