Node.js глобальные переменные?

Я спросил здесь: node.js требуют наследования?

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

Это не работает для меня.

т

_ = require('underscore');

Не делает _ доступным для требуемых файлов. Я могу установить с помощью выражения app.set и использовать его в другом месте.

Может кто-нибудь подтвердить, что это должно работать? Спасибо.

Ответ 1

global._ = require('underscore')

Ответ 2

В node вы можете установить глобальные переменные через объект "global" или "GLOBAL":

GLOBAL._ = require('underscore'); // but you "shouldn't" do this! (see note below)

или более полезно...

GLOBAL.window = GLOBAL;  // like in the browser

Из источника node вы можете видеть, что они псевдонимы друг другу:

node-v0.6.6/src/node.js:
28:     global = this;
128:    global.GLOBAL = global;

В приведенном выше коде "this" используется глобальный контекст. В модульной системе commonJS (которая используется node) объект "this" внутри модуля (т.е. "Ваш код" ) НЕ является глобальным контекстом. Для доказательства этого, см. Ниже, где я выворачиваю объект "this", а затем гигантский объект "GLOBAL".

console.log("\nTHIS:");
console.log(this);
console.log("\nGLOBAL:");
console.log(global);

/* outputs ...

THIS:
{}

GLOBAL:
{ ArrayBuffer: [Function: ArrayBuffer],
  Int8Array: { [Function] BYTES_PER_ELEMENT: 1 },
  Uint8Array: { [Function] BYTES_PER_ELEMENT: 1 },
  Int16Array: { [Function] BYTES_PER_ELEMENT: 2 },
  Uint16Array: { [Function] BYTES_PER_ELEMENT: 2 },
  Int32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Uint32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Float32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Float64Array: { [Function] BYTES_PER_ELEMENT: 8 },
  DataView: [Function: DataView],
  global: [Circular],
  process: 
   { EventEmitter: [Function: EventEmitter],
     title: 'node',
     assert: [Function],
     version: 'v0.6.5',
     _tickCallback: [Function],
     moduleLoadList: 
      [ 'Binding evals',
        'Binding natives',
        'NativeModule events',
        'NativeModule buffer',
        'Binding buffer',
        'NativeModule assert',
        'NativeModule util',
        'NativeModule path',
        'NativeModule module',
        'NativeModule fs',
        'Binding fs',
        'Binding constants',
        'NativeModule stream',
        'NativeModule console',
        'Binding tty_wrap',
        'NativeModule tty',
        'NativeModule net',
        'NativeModule timers',
        'Binding timer_wrap',
        'NativeModule _linklist' ],
     versions: 
      { node: '0.6.5',
        v8: '3.6.6.11',
        ares: '1.7.5-DEV',
        uv: '0.6',
        openssl: '0.9.8n' },
     nextTick: [Function],
     stdout: [Getter],
     arch: 'x64',
     stderr: [Getter],
     platform: 'darwin',
     argv: [ 'node', '/workspace/zd/zgap/darwin-js/index.js' ],
     stdin: [Getter],
     env: 
      { TERM_PROGRAM: 'iTerm.app',
        'COM_GOOGLE_CHROME_FRAMEWORK_SERVICE_PROCESS/USERS/DDOPSON/LIBRARY/APPLICATION_SUPPORT/GOOGLE/CHROME_SOCKET': '/tmp/launch-nNl1vo/ServiceProcessSocket',
        TERM: 'xterm',
        SHELL: '/bin/bash',
        TMPDIR: '/var/folders/2h/2hQmtmXlFT4yVGtr5DBpdl9LAiQ/-Tmp-/',
        Apple_PubSub_Socket_Render: '/tmp/launch-9Ga0PT/Render',
        USER: 'ddopson',
        COMMAND_MODE: 'unix2003',
        SSH_AUTH_SOCK: '/tmp/launch-sD905b/Listeners',
        __CF_USER_TEXT_ENCODING: '0x12D732E7:0:0',
        PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:~/bin:/usr/X11/bin',
        PWD: '/workspace/zd/zgap/darwin-js',
        LANG: 'en_US.UTF-8',
        ITERM_PROFILE: 'Default',
        SHLVL: '1',
        COLORFGBG: '7;0',
        HOME: '/Users/ddopson',
        ITERM_SESSION_ID: 'w0t0p0',
        LOGNAME: 'ddopson',
        DISPLAY: '/tmp/launch-l9RQXI/org.x:0',
        OLDPWD: '/workspace/zd/zgap/darwin-js/external',
        _: './index.js' },
     openStdin: [Function],
     exit: [Function],
     pid: 10321,
     features: 
      { debug: false,
        uv: true,
        ipv6: true,
        tls_npn: false,
        tls_sni: true,
        tls: true },
     kill: [Function],
     execPath: '/usr/local/bin/node',
     addListener: [Function],
     _needTickCallback: [Function],
     on: [Function],
     removeListener: [Function],
     reallyExit: [Function],
     chdir: [Function],
     debug: [Function],
     error: [Function],
     cwd: [Function],
     watchFile: [Function],
     umask: [Function],
     getuid: [Function],
     unwatchFile: [Function],
     mixin: [Function],
     setuid: [Function],
     setgid: [Function],
     createChildProcess: [Function],
     getgid: [Function],
     inherits: [Function],
     _kill: [Function],
     _byteLength: [Function],
     mainModule: 
      { id: '.',
        exports: {},
        parent: null,
        filename: '/workspace/zd/zgap/darwin-js/index.js',
        loaded: false,
        exited: false,
        children: [],
        paths: [Object] },
     _debugProcess: [Function],
     dlopen: [Function],
     uptime: [Function],
     memoryUsage: [Function],
     uvCounters: [Function],
     binding: [Function] },
  GLOBAL: [Circular],
  root: [Circular],
  Buffer: 
   { [Function: Buffer]
     poolSize: 8192,
     isBuffer: [Function: isBuffer],
     byteLength: [Function],
     _charsWritten: 8 },
  setTimeout: [Function],
  setInterval: [Function],
  clearTimeout: [Function],
  clearInterval: [Function],
  console: [Getter],
  window: [Circular],
  navigator: {} }
*/

** Примечание: относительно установки "GLOBAL._" , в общем случае вы должны просто сделать var _ = require('underscore');. Да, вы делаете это в каждом файле, который использует подчеркивание, так же, как в Java вы делаете import com.foo.bar;. Это упрощает определение того, что делает ваш код, потому что ссылки между файлами являются "явными". Мягко раздражает, но хорошо..... Это проповедь.

Существует исключение для каждого правила. У меня был точно точно один экземпляр, где мне нужно было установить "GLOBAL._" . Я создавал систему для определения файлов "config", которые были в основном JSON, но были "написаны в JS", чтобы немного повысить гибкость. В таких конфигурационных файлах не было инструкций "require", но я хотел, чтобы они имели доступ к подчеркиванию (система ENTIRE была основана на шаблонах подчеркивания и подчеркивания), поэтому перед оценкой "config" я бы установил "GLOBAL._" . Так что да, для каждого правила есть где-то исключение. Но у вас есть хорошая причина, а не просто "я устал от ввода" требовать ", поэтому я хочу нарушить соглашение".

Ответ 3

Пожалуйста, рассмотрите этот ответ

Другие решения, которые используют ключевое слово GLOBAL, являются кошмаром для поддержания/удобочитаемости (+ загрязнение пространства имен и ошибок), когда проект становится больше. Я много раз видела эту ошибку и испытывала трудности с ее фиксацией.

Правильное решение:

Используйте JS файл, затем используйте экспорт модулей.

Пример:

globals.js

var Globals = {
    'domain':'www.MrGlobal.com';
}

module.exports = Globals;

Затем, если вы хотите использовать их, используйте require.

var globals = require('globals'); //<< globals.js path
globals.domain //<< Domain.

Ответ 4

global._ = require('underscore');

Обратите внимание, что использование GLOBAL устарело:

(node:59502) DeprecationWarning: 'GLOBAL' is deprecated, use 'global'

Мой комментарий:

Если вы знаете, что делаете, я думаю, что это ОК, чтобы использовать глобальный. Когда мне придется требовать библиотеку каждый раз, когда я захочу ее использовать (и, допустим, я использую ее в десятках или сотнях файлов), я думаю, что она разрушает основную часть множества библиотек, которые сделаны легко и быстро. Почему это называется _, а не amazingLibraryCalledUnderscore?

Итак, для меня нужно написать 30 символов var _ = require('underscore'); 3000% больше необходимого минимального (1 char). Да. Я одержим облегчением моей жизни при написании кода. Я просто ненавижу повторять очевидные вещи. Если я когда-то сказал черт возьми node, что я имею в виду под I want you to know _ means I use underscore, я не хочу повторять это снова.

Итак - я верю, что когда вы контролируете свой код, вы должны попытаться сделать его сексуальным. Я считаю, что писать 30 символов каждый раз, чтобы сделать так просто, чертовски уродливо!

пс. доверять себе, когда вы говорите I control my code, вам нужно иметь опыт потери этого элемента управления хотя бы один раз.

Ответ 5

Как насчет глобального пространства имен, такого как global.MYAPI = {}

global.MYAPI._ = require('underscore')

Редактировать после комментария Camilo-martin. Все остальные плакаты говорят о плохом шаблоне. Поэтому, оставляя это обсуждение в стороне, лучший способ иметь переменную, определенную глобально (вопрос OP), осуществляется через пространства имен.

@tip: http://thanpol.as/javascript/development-using-namespaces/

Ответ 6

Вы можете просто использовать глобальный объект.

var X = ['a', 'b', 'c'];
global.x = X;

console.log(x);
//['a', 'b', 'c']

Ответ 7

Я согласен с тем, что использование пространства имен global/GLOBAL для установления чего-либо глобального является плохой практикой и вообще не использует его в теории (теоретически являясь оперативным словом). Однако (да, оперативник) я использую его для установки пользовательских классов ошибок:

// Some global/config file that gets called in initialisation

global.MyError = [Function of MyError];

Да, табу здесь, но если ваш сайт/проект использует собственные ошибки по всему месту, вам в основном нужно определить его везде или по крайней мере где-нибудь:

  • Определите класс Error в первую очередь
  • В script, где вы его бросаете
  • В script, где вы его ловите

Определение моих пользовательских ошибок в глобальном пространстве имен избавляет меня от необходимости требовать мою библиотеку ошибок клиента. Imaging выбрасывает пользовательскую ошибку, если таковая ошибка undefined.

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