Подтвердить что ты не робот

Глобальные переменные для стандартных модулей node.js?

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

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

util = require('util');

в файле index.js вместо того, чтобы писать эту строку в 40 файлах?

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

В этом случае нет DRY?

4b9b3361

Ответ 1

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

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

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

Обновленный ответ Январь 2012

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

Объект global поэтому не является глобальным и не может использоваться как таковой.

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

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

Ответ 2

У вас может быть только общий модуль.

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));

Ответ 3

global.util = require('util');

Здесь содержится раздел о глобальных объектах в node документации.

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

Ответ 4

Я смущен ответами в этой теме.

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

Файл: 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), и я хотел опубликовать то, что, похоже, работает для меня сейчас. Возможно, с момента первоначальных ответов ситуация изменилась.

Ответ 5

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

Ответ 6

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

Например, мои модули часто похожи на:

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

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