Делить переменные между файлами в Node.js? - PullRequest
109 голосов
/ 13 октября 2010

Вот 2 файла:

// main.js
require('./modules');
console.log(name); // prints "foobar"

// module.js
name = "foobar";

Когда у меня нет "var", это работает. Но когда у меня есть:

// module.js
var name = "foobar";

имя будет не определено в main.js.

Я слышал, что глобальные переменные плохие, и вам лучше использовать "var" перед ссылками. Но так ли это, когда глобальные переменные хороши?

Ответы [ 6 ]

161 голосов
/ 13 октября 2010

Глобальные переменные почти никогда не бывают хорошими (возможно, исключение или две там ...).В этом случае, похоже, вы действительно хотите экспортировать свою переменную «name».Например,

// module.js
var name = "foobar";
// export it
exports.name = name;

Затем в main.js ...

//main.js
// get a reference to your required module
var myModule = require('./module');

// name is a member of myModule due to the export above
var name = myModule.name;
24 голосов
/ 14 февраля 2018

Я не могу найти сценарий, в котором глобальный var является лучшим вариантом, конечно, у вас может быть один, но посмотрите на эти примеры, и вы можете найти лучший способ сделать то же самое:

Сценарий 1: Поместите материал в конфигурационные файлы

Вам нужно некоторое значение, которое одинаково для всего приложения, но оно меняется в зависимости от среды (производство, разработка или тестирование), типа почтовой программы, например, вам потребуется:

// File: config/environments/production.json
{
    "mailerType": "SMTP",
    "mailerConfig": {
      "service": "Gmail",
      ....
}

и

// File: config/environments/test.json
{
    "mailerType": "Stub",
    "mailerConfig": {
      "error": false
    }
}

(создать аналогичную конфигурацию и для dev)

Чтобы решить, какая конфигурация будет загружена, создайте основной файл конфигурации (он будет использоваться во всем приложении)

// File: config/config.js
var _ = require('underscore');

module.exports = _.extend(
    require(__dirname + '/../config/environments/' + process.env.NODE_ENV + '.json') || {});

И теперь вы можете получить данные , например:

// File: server.js
...
var config = require('./config/config');
...
mailer.setTransport(nodemailer.createTransport(config.mailerType, config.mailerConfig));

Сценарий 2. Использование файла констант

// File: constants.js
module.exports = {
  appName: 'My neat app',
  currentAPIVersion: 3
};

И используйте это так

// File: config/routes.js

var constants = require('../constants');

module.exports = function(app, passport, auth) {
  var apiroot = '/api/v' + constants.currentAPIVersion;
...
  app.post(apiroot + '/users', users.create);
...

Сценарий 3: использование вспомогательной функции для получения / установки данных

Не большой поклонник этого, но по крайней мере вы можете отследить использование 'name' (приводя пример OP) и поставить валидации на место.

// File: helpers/nameHelper.js

var _name = 'I shall not be null'

exports.getName = function() {
  return _name;
};

exports.setName = function(name) {
  //validate the name...
  _name = name;
};

И используйте это

// File: controllers/users.js

var nameHelper = require('../helpers/nameHelper.js');

exports.create = function(req, res, next) {
  var user = new User();
  user.name = req.body.name || nameHelper.getName();
  ...

Может быть случай использования, когда нет другого решения, кроме глобального var, но обычно вы можете поделиться данными в своем приложении, используя один из этих сценариев, если вы начинаете использовать node.js (как Я был некоторое время назад) попробуй организовать способ обработки данных там, потому что они могут очень быстро запутаться.

11 голосов
/ 21 октября 2017

Если нам нужно совместно использовать несколько переменных, используйте следующий формат

//module.js
   let name='foobar';
   let city='xyz';
   let company='companyName';

   module.exports={
    name,
    city,
    company
  }

Использование

  // main.js
    require('./modules');
    console.log(name); // print 'foobar'
5 голосов
/ 02 июля 2017

Обновление

Сохраните любую переменную, которую хотите использовать как один объект. Затем передайте его загруженному модулю, чтобы он мог обращаться к переменной через ссылку на объект.

// myModule.js
var shared = null;

function init(obj){
    shared = obj;
}

module.exports = {
    init:init
}

.

// main.js
var myModule = require('./myModule.js');
var shares = {value:123};
myModule.init(shares);

Старый ответ

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

//myModule.js
var mainFunction = null; //You can also put function reference in a Object or Array

function functionProxy(func){
    mainFunction = func; //Save the function reference
}

// --- Usage ---
// setTimeout(function(){
//   console.log(mainFunction('myString'));
//   console.log(mainFunction('myNumber'));
// }, 3000);

module.exports = {
    functionProxy:functionProxy
}

.

//main.js
var myModule = require('./myModule.js');
var myString = "heyy";
var myNumber = 12345;

function internalVariable(select){
    if(select=='myString') return myString;
    else if(select=='myNumber') return myNumber;
    else return null;
}

myModule.functionProxy(internalVariable);


// --- If you like to be able to set the variable too ---
// function internalVariable(select, set){
//    if(select=='myString'){
//        if(set!=undefined) myString = set;
//        else return myString;
//    }
//    else if(select=='myNumber'){
//      if(set!=undefined) myNumber = set;
//      else return myNumber;
//    }
//    else return null;
// }

Вы всегда можете получить значение из main.js, даже если значение было изменено.

1 голос
/ 24 февраля 2019

С другим мнением, я думаю, что переменные global могут быть лучшим выбором, если вы собираетесь опубликовать свой код в npm, потому что вы не можете быть уверены, что все пакеты используют один и тот же выпуск вашего кода.Поэтому, если вы используете файл для экспорта объекта singleton, это вызовет проблемы здесь.

Вы можете выбрать global, require.main или любые другие объекты, которые являются общими для файлов.

Скажите, пожалуйста, есть ли лучшие решения.

1 голос
/ 29 июня 2017

переменная, объявленная с ключевым словом var или без него, присоединена к глобальному объекту.Это основа для создания глобальных переменных в Node путем объявления переменных без ключевого слова var.В то время как переменные, объявленные с ключевым словом var, остаются локальными для модуля.

см. Эту статью для дальнейшего понимания - https://www.hacksparrow.com/global-variables-in-node-js.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...