Глобальные переменные для стандартных модулей node.js? - PullRequest
53 голосов
/ 10 ноября 2010

Я знаю, что глобальные переменные плохие.

Но если я использую модуль узла "util" в 40 файлах в моей среде, не лучше ли просто объявить его как глобальную переменную, такую ​​как:

util = require('util');

в файле index.js вместо записи этой строки в 40 файлах?

Причина Я часто использую одни и те же 5-10 модулей в каждом файле, что сэкономит много времени вместо копирования и вставки.

Разве DRY не хорош в этом случае?

Ответы [ 6 ]

102 голосов
/ 24 ноября 2010

Вы могли бы просто иметь общий модуль.

common.js:

Common = {
  util: require('util'),
  fs:   require('fs'),
  path: require('path')
};

module.exports = Common;

app.js:

var Common = require('./common.js');
console.log(Common.util.inspect(Common));
43 голосов
/ 10 ноября 2010

Каждый модуль должен быть независимым. Требование ничего не стоит в любом случае после первого для каждого модуля.

Что если вы хотите протестировать один модуль в одиночку? У вас будет много проблем, потому что он не распознает некоторые «глобальные» требования, которые есть в вашем приложении.

Да, глобалы плохие, даже в этом случае. Глобалы почти всегда разрушают: тестируемость, инкапсуляция и простота обслуживания.

Обновленный ответ январь 2012 г.

Объект global теперь является глобальным внутри каждого модуля. Поэтому каждый раз, когда вы назначаете глобальную переменную (без области видимости) внутри модуля, она становится частью объекта global этого модуля.

Следовательно, объект global все еще не является глобальным и не может использоваться как таковой.

Обновлено декабрь 2012

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

25 голосов
/ 28 ноября 2010
global.util = require('util');

В документации на узел есть раздел о глобальных объектах .

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

20 голосов
/ 01 февраля 2012

Меня смущают ответы в этой теме.

Я могу это сделать ...

Файл: test.js

global.mytest = {
    x: 3,
    y: function() { console.log('Works.'); }
};

Файл: test2.js

console.log('Does this work?');
mytest.y();

Файл: server.js

require('test.js');
require('test2.js');

И, похоже, это работает как вопрос.Первое требование помещает объект mytest в глобальную область, затем второе требование может получить доступ к этому объекту без каких-либо других определителей.

Я пытался выяснить это (что привело меня к этой теме из поиска Google)и я хотел опубликовать то, что, кажется, работает для меня сейчас.Может быть, что-то изменилось с момента первоначальных ответов.

0 голосов
/ 23 июня 2011

Я успешно использовал объект process для передачи моего объекта конфигурации.Хотя теоретически он страдает теми же проблемами, что и упомянутые выше (инкапсуляция, тестируемость и т. Д.), Он прекрасно работает, когда используются только свойства, не изменяющие состояние (в основном хеш-таблица с примитивами).

0 голосов
/ 10 ноября 2010

Если вы упаковываете свои модули в блоки (например, функции anon), вы можете привязать к локальному имени (через параметр или 'var'), а затем иметь любое произвольное длинное (возможно, помеченное "package") имя, которое вы хотите (если вы дажена данном этапе нужна глобальная).

Например, мои модули часто выглядят примерно так:

;(function ($, $exp, other) {
  $(...)
  other.xyz()
  $exp.MyExportedObject = ...;
})(jQuery, window, some_module.other_expression) // end module

Я использую jQuery с noConflict, это первое, а второе показывает, что вы можете сделатьэто для любого выражения - глобальное, требующее, вычисляемое, встроенное, что угодно ... этот же подход "обтекания" может использоваться для исключения всех (или почти всех) глобалов с "особыми именами" - глобалы должны существовать на некотором уровнеОднако устранение потенциальных конфликтов - очень большая победа.

...