Как передать переменные в модули NodeJS?

в одном из моих файлов JS я включаю другой. Как установить переменные в включенном модуле?

Я думал, что делать что-то подобное будет работать

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

а потом в mymodule

this.myvariable === 'test';

но это не работает, это undefined. Каковы различные варианты передачи значения в модуль? Я мог бы просто добавить переменную в качестве параметра к каждой функции, которую я вызываю в mymodule, но это не идеально.

есть ли способ сделать это без глобалов, чтобы я мог устанавливать переменные независимо в различных требуемых модулях, например?

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

3 ответов


NodeJS require() всегда будет загружать модуль один раз, поэтому вам нужно будет реализовать область в вашем модуле, где различные экземпляры модуля могут существовать со своим собственным внутренним состоянием.

вы можете реализовать свой модуль как класс JS, например:

var MyModule = function(){};

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

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

module.exports = MyModule;

тогда в вашем коде;

var MyModule = require('MyModule');

someModule = new MyModule();

// treat someModule like an object with its getters/setters/functions

проблема с тем, что вы делали, заключается в том, что вы устанавливаете переменную после импорта, но this.myvariable === 'test'; вызывался при импорте модуля до того, как была установлена переменная.

вы можете экспортировать функцию своего модуля, а затем вызывать функцию при импорте, передавая переменную в качестве аргумента.

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

  return myModule; 
};

при импорте,

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

если вы используете этот метод, имейте в виду, что вы получите свой экземпляр своего модуля, где вы импорт, который может быть не тем, что вы хотите.

если вы хотите установить значения модуля извне модуля, хорошим вариантом является экспорт вашего модуля объектом с помощью метода setter и использование этого для установки значения переменной как свойства объекта. Это делает более ясным, что вы хотите, чтобы это значение было установлено, тогда как просто делать myModule.myVar = может настроить вас на путаницу позже.

module.exports = {
  myVar: null,

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

  ...

};

в этом случае вы получаете доступ к тому же экземпляру модели куда бы вы его ни импортировали.

редактировать в ответ на комментарий

в первом варианте вы показываете, где вы получаете другой экземпляр каждый время, как я могу экспортировать несколько функций, каждая из которых одинакова аргумент myVar? Если этот модуль экспортирует 5 функций, каждая из которых нуждается в myVar, могу ли я установите его в одном месте, как во время импорта, а не передавать его в каждая функция?

не совсем уверен, что понимаю, что вы описываете, но вы могли бы сделать что-то вроде этого:

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

  return modules;
};

каждый из этих модулей будет иметь доступ к одному и тому же myVar. Таким образом, вы импортируете, как указано выше, и результатом будет объект, содержащий каждый из ваших пяти модулей в качестве свойств. Я не могу сказать, хорошая ли это идея, она становится довольно запутанной, но, возможно, это имеет смысл для вашей ситуации.


должно работать нормально. Вот рабочий пример:

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

модуль.js

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

имейте в виду, если вы используете this в закрытии, что область больше не является самим модулем. Так что это может быть твоей проблемой.

можете ли вы показать мне фрагмент кода, где вы используете этот модуль?