глобальные переменные node.js? - PullRequest
200 голосов
/ 27 марта 2011

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

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

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

есть:

_ = require('underscore');

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

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

Ответы [ 6 ]

225 голосов
/ 28 марта 2011

global._ = require('underscore')

215 голосов
/ 06 марта 2012

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

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

или, что более полезно ...

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

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

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

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

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

/* outputs ...

<b>THIS:</b>
{}

<b>GLOBAL:</b>
{ 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._».Я создавал систему для определения «конфигурационных» файлов, которые были в основном JSON, но были «написаны на JS» для большей гибкости.Такие конфигурационные файлы не имели операторов 'require', но я хотел, чтобы у них был доступ к подчеркиванию (система ENTIRE была основана на шаблонах подчеркивания и подчеркивания), поэтому перед оценкой "config" я бы установил "GLOBAL._".Так что да, для каждого правила есть где-то исключение.Но вам лучше иметь чертову вескую причину, а не просто «я устал набирать« требовать », поэтому я хочу порвать с соглашением».

74 голосов
/ 09 сентября 2015

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

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

Пример:

globals.js

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

module.exports = Globals;

Тогда, если вы хотите использовать их, используйте require.

var globals = require('globals'); //<< globals.js path
globals.domain //<< Domain.
12 голосов
/ 04 августа 2014

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

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

Редактировать после комментария Камило-Мартина : Все остальные постеры говорят о плохом паттерне.Таким образом, оставляя это обсуждение в стороне, лучший способ определения глобальной переменной (вопрос OP) - через пространства имен.

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

9 голосов
/ 20 июля 2016

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

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

console.log(x);
//['a', 'b', 'c']
5 голосов
/ 22 июля 2014

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

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

global.MyError = [Function of MyError];

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

  1. Определить класс ошибок в первую очередь
  2. В сценарии, куда вы его бросаете
  3. В сценарии, где вы его ловите

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

Также, если это не так, пожалуйста, дайте мне знать, поскольку я только недавно начал делать это

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