web-dev-qa-db-fra.com

Comment passer des variables dans les modules NodeJS?

Dans un de mes fichiers JS j'en inclue un autre. Comment puis-je définir des variables dans le module inclus?

Je pensais que faire quelque chose comme ça marcherait

var mymodule = require('mymodule.js');
mymodule.myvariable = 'test';

Et puis dans mon module

this.myvariable === 'test';

Mais cela ne fonctionne pas, c'est undefined. Quelles sont les différentes options pour passer une valeur dans un module? Je pourrais simplement ajouter la variable comme paramètre à chaque fonction que j'appelle dans mymodule, mais ce n'est pas idéal.

Existe-t-il un moyen de le faire sans globaux, afin que je puisse définir les variables indépendamment dans divers modules requis, comme celui-ci?

var mymodule1 = require('mymodule.js');
var mymodule2 = require('mymodule.js');
mymodule1.myvariable = 'test1';
mymodule2.myvariable = 'test2';
11
user779159

NodeJS require() chargera toujours le module une fois, vous devrez donc implémenter la portée dans votre module où différentes instances du module peuvent exister avec leur propre état interne.

Vous pouvez implémenter votre module en tant que classe JS comme:

var MyModule = function(){};

MyModule.prototype.someFunction = function(params){
    this.someVar = params;
}

MyModule.prototype.anotherFunction = function(key, value){
    this[key] = value;
}

module.exports = MyModule;

Puis dans votre code;

var MyModule = require('MyModule');

someModule = new MyModule();

// treat someModule like an object with its getters/setters/functions
17
Noman Ur Rehman

Le problème avec ce que vous faisiez est que vous définissez la variable après l'importation, mais this.myvariable === 'test'; était appelé lors de l'importation du module, avant que votre variable ne soit définie.

Vous pouvez demander à votre module d'exporter une fonction, puis d'appeler la fonction lorsque vous importez, en passant votre variable comme argument.

module.exports = function(myVar) {
  var myModule = {
    // has access to myVar 
    ...
  };

  return myModule; 
};

Lorsque vous importez,

var myModule = require('myModule')(myVar);

Si vous utilisez cette méthode, gardez à l'esprit que vous obtenez une instance différente de votre module partout où vous importez, ce qui n'est peut-être pas ce que vous voulez.

Si vous souhaitez définir les valeurs d'un module depuis l'extérieur du module, une bonne option consiste à demander à votre module d'exporter un objet avec une méthode de définition et de l'utiliser pour définir la valeur de la variable en tant que propriété de l'objet. Cela rend plus clair que vous voulez que cette valeur soit paramétrable, alors que simplement faire myModule.myVar = peut vous semer la confusion plus tard.

module.exports = {
  myVar: null,

  setMyVar: function(myVar) {
    this.myVar = myVar;
  },

  ...

};

Dans ce cas, vous accédez à la même instance du modèle où que vous l'importiez.

Modifier en réponse au commentaire

Dans la première option, vous montrez où vous obtenez une instance différente à chaque fois, comment puis-je exporter plusieurs fonctions qui partagent chacune le même myVar? Si ce module exporte 5 fonctions chacune qui ont besoin de myVar, puis-je le placer au même endroit qu'au moment de l'importation plutôt que de le passer dans chaque fonction?

Je ne sais pas vraiment si je comprends ce que vous décrivez, mais vous pourriez faire quelque chose comme ceci:

module.exports = function(myVar) {
  var modules = {};
  modules.someModule = {...};
  modules.anotherModule = {...};
  ...

  return modules;
};

Chacun de ces sous-modules aurait accès au même myVar. Vous importeriez donc comme ci-dessus et le résultat serait un objet contenant chacun de vos cinq modules en tant que propriétés. Je ne peux pas dire si c'est une bonne idée, cela devient assez compliqué, mais peut-être que cela a du sens pour votre situation.

13
Adam Stone

Devrait fonctionner très bien. Voici un exemple de travail:

index.js

var module = require('./module.js');
module.myvar = 'Hello world';
module.test();

module.js

module.exports = {
    test: function() {
        console.log('var is', this.myvar);
    }
};

Gardez à l'esprit si vous utilisez this dans une fermeture que la portée n'est plus le module lui-même. Cela pourrait donc être votre problème.

Pouvez-vous me montrer la partie du code du module où vous l'utilisez?

2
Wim Mostmans