variables ​​globais node.js?

Eu perguntei aqui: node.js requer inheritance?

e foi dito que eu posso definir variables ​​para o escopo global, deixando de fora o var.

Isso não funciona para mim.

ie:

_ = require('underscore'); 

Não disponibiliza o _ nos arquivos requeridos. Eu posso definir com app.set do app.set e tê-lo disponível em outro lugar embora.

Alguém pode confirmar que isso deveria funcionar? Obrigado.

global._ = require('underscore')

No nó, você pode definir variables ​​globais através do object “global” ou “GLOBAL”:

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

ou mais utilmente …

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

Da fonte do nó, você pode ver que eles são aliados entre si:

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

No código acima, “isto” é o contexto global. Com o sistema de módulo commonJS (cujo nó usa), o object “this” dentro de um módulo (ou seja, “seu código”) NÃO é o contexto global. Para provar isso, veja abaixo onde eu vomito o object “this” e então o object gigante “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: {} } */ 

** Nota: sobre a configuração de “GLOBAL._”, em geral você deve fazer var _ = require('underscore'); . Sim, você faz isso em todos os arquivos que usam sublinhado, assim como em Java você import com.foo.bar; . Isso torna mais fácil descobrir o que seu código está fazendo porque as ligações entre os arquivos são “explícitas”. Ligeiramente irritante, mas uma coisa boa. …. Essa é a pregação.

Existe uma exceção em todas as regras. Eu tive precisamente exatamente uma instância em que precisei definir “GLOBAL._”. Eu estava criando um sistema para definir arquivos “config” que eram basicamente JSON, mas eram “escritos em JS” para permitir um pouco mais de flexibilidade. Esses arquivos de configuração não tinham instruções ‘require’, mas eu queria que eles tivessem access ao sublinhado (o sistema INTEIRO era baseado em modelos de sublinhado e sublinhado), portanto, antes de avaliar o “config”, eu definiria “GLOBAL._”. Então, sim, para todas as regras, há uma exceção em algum lugar. Mas é melhor você ter um bom motivo e não apenas “eu me canso de digitar ‘require’, então eu quero romper com a convenção”.

As outras soluções que usam a palavra-chave GLOBAL são um pesadelo para manter / legibilidade (+ poluição de namespace e bugs) quando o projeto se torna maior. Eu vi esse erro muitas vezes e tive o incômodo de corrigi-lo.

Use um arquivo JS e use as exportações do módulo.

Exemplo:

globals.js

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

Então, se você quiser usá-los, use require.

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

Observe que o uso do GLOBAL está obsoleto:

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

Meu comentário:

Se você sabe o que está fazendo, acho que não há problema em usar o global. Quando eu tenho que precisar de alguma biblioteca toda vez que eu quiser usá-la (e digamos que estou usando em dezenas ou centenas de arquivos) eu acho que isso destrói o ponto principal de muitas bibliotecas que são feitas para serem fáceis e rápido de usar. Por que é chamado _ , não amazingLibraryCalledUnderscore ?

Então, para mim, precisando escrever 30 caracteres de var _ = require('underscore'); é 3000% mais do que o mínimo exigido (1 char). Sim. Estou obcecado em tornar minha vida mais fácil ao escrever o código. Eu simplesmente odeio repetir coisas óbvias. Se eu disse uma vez ao maldito nó o que eu quero dizer com I want you to know _ means I use underscore Eu não quero dizer isso novamente.

Então – eu acredito que quando você controla seu código, você deve tentar torná-lo sexy . Eu acredito que escrever 30 chars a cada vez para fazer uma coisa tão simples é feio!

ps. Para confiar em si mesmo quando você diz que I control my code , você precisa ter experiência de perder esse controle pelo menos uma vez.

Que tal um namespace global como global.MYAPI = {}

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

Editar após o comentário de camilo-martin : Todos os outros cartazes falam sobre o padrão ruim envolvido. Deixando de lado essa discussão, a melhor maneira de ter uma variável definida globalmente (a pergunta do OP) é ​​através dos namespaces.

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

Você pode apenas usar o object global.

 var X = ['a', 'b', 'c']; global.x = X; console.log(x); //['a', 'b', 'c'] 

Eu concordo que usar o namespace global / global para definir qualquer coisa global é uma prática ruim e não usá-la na teoria ( em teoria, sendo a palavra operativa). No entanto (sim, o operativo) eu uso para definir classs de erro personalizadas:

 // Some global/config file that gets called in initialisation global.MyError = [Function of MyError]; 

Sim, tabu aqui, mas se o seu site / projeto usa erros personalizados em todo o lugar, você basicamente precisa defini-lo em todos os lugares, ou pelo menos em algum lugar para:

  1. Defina a class Error em primeiro lugar
  2. No script onde você está jogando
  3. No script onde você está pegando

Definir meus erros personalizados no namespace global me poupa o trabalho de exigir minha biblioteca de erros do cliente. Imagem gerando um erro personalizado em que esse erro personalizado é indefinido.

Além disso, se isso está errado, por favor, deixe-me saber como eu só comecei a fazer isso recentemente