Вопрос:
В одном из моих JS файлов я включаю еще один. Как установить переменные во включенном модуле?
Я думал, что что-то вроде этого будет работать
var mymodule = require(‘mymodule.js’); mymodule.myvariable = ‘test’;
И затем в mymodule
this.myvariable === ‘test’;
Но это не работает, оно undefined. Каковы различные варианты передачи значения в модуль? Я мог бы просто добавить переменную в качестве параметра для каждой функции, которую я вызываю в mymodule, но это не идеально.
Есть ли способ сделать это без globals, так что я могу самостоятельно устанавливать переменные в разных требуемых модулях?
var mymodule1 = require(‘mymodule.js’); var mymodule2 = require(‘mymodule.js’); mymodule1.myvariable = ‘test1’; mymodule2.myvariable = ‘test2’; Лучший ответ:
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 Ответ №1
Проблема с тем, что вы делали, заключается в том, что вы задали переменную после импорта, но 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. Таким образом, вы должны импортировать как указано выше, и результатом будет объект, содержащий каждый из ваших пяти модулей в качестве свойств. Я не могу сказать, хорошая ли это идея, она становится довольно запутанной, но, возможно, это имеет смысл для вашей ситуации.
Ответ №2
Должно работать нормально. Вот рабочий пример:
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); } };
Имейте в виду, если вы используете this в закрытии, что область действия больше не является самим модулем. Так что это может быть вашей проблемой.
Можете ли вы показать мне часть кода модуля, в которой вы используете это?