web-dev-qa-db-fra.com

variables globales node.js?

J'ai demandé ici: node.js nécessite un héritage?

et a été dit que je peux définir des variables à la portée globale en laissant de côté le var.

Cela ne fonctionne pas pour moi.

c'est à dire:

_ = require('underscore');

Ne rend pas le _ disponible sur les fichiers requis. Je peux régler avec le app.set de express et le laisser disponible ailleurs.

Quelqu'un peut-il confirmer que cela est censé fonctionner? Merci.

202
Harry

global._ = require('underscore')

227
masylum

Dans nœud, vous pouvez définir des variables globales via l'objet "global" ou "GLOBAL":

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

ou plus utilement ...

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

A partir de la source du noeud, vous pouvez voir que ceux-ci ont des alias entre eux:

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

Dans le code ci-dessus, "ceci" est le contexte global. Avec le système de module commonJS (quel nœud utilise), l'objet "this" à l'intérieur d'un module (c'est-à-dire "votre code") N'EST PAS le contexte global. Pour preuve, voir ci-dessous où je crache l'objet "ceci" puis l'objet géant "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: {} }
*/

** Remarque: en ce qui concerne le réglage "GLOBAL._", en général, vous devriez simplement faire var _ = require('underscore');. Oui, vous faites cela dans chaque fichier qui utilise un trait de soulignement, comme vous le faites dans Java import com.foo.bar;. Cela facilite la compréhension de ce que fait votre code car les liens entre les fichiers sont "explicites". Légèrement ennuyeux, mais une bonne chose. .... C'est la prédication.

Il y a une exception à chaque règle. J'ai eu exactement une seule instance où je devais définir "GLOBAL._". Je créais un système de définition de fichiers "config" qui étaient essentiellement JSON, mais "écrits en JS" pour permettre un peu plus de flexibilité. Ces fichiers de configuration ne comportaient pas d'instructions 'require', mais je voulais qu'ils aient accès au soulignement (le système ENTIER était basé sur les modèles de soulignement et de soulignement), donc avant d'évaluer la "config", je mettrais "GLOBAL._". Donc oui, pour chaque règle, il y a une exception quelque part. Mais vous feriez mieux d’avoir une bonne raison et pas seulement "je me lasse de taper" nécessite ", alors je veux rompre avec les conventions".

215
Dave Dopson

Les autres solutions qui utilisent le mot clé GLOBAL sont un cauchemar à maintenir/lisibilité (+ pollution de l'espace de noms et bugs) lorsque le projet devient plus grand. J'ai vu cette erreur plusieurs fois et j'ai eu le souci de la réparer.

Utilisez un fichier JS, puis utilisez les exportations de module.

Exemple:

globals.js

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

module.exports = Globals;

Ensuite, si vous souhaitez les utiliser, utilisez require.

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

Qu'en est-il d'un espace de noms global comme global.MYAPI = {}

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

Éditer après le commentaire de camilo-martin : Toutes les autres affiches parlent de la mauvaise tendance en cause. Donc, en laissant cette discussion de côté, le meilleur moyen de définir une variable de manière globale (la question de OP) consiste à utiliser des espaces de noms.

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

12
Igor Parra

Vous pouvez simplement utiliser l'objet global.

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

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

Je conviens que l'utilisation de l'espace de noms global/GLOBAL pour définir un élément global est une mauvaise pratique et ne l'utilise pas du tout en théorie (en théorie étant le mot clé). Cependant (oui, l'opérateur), je l'utilise pour définir des classes d'erreur personnalisées:

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

global.MyError = [Function of MyError];

Oui, tabou ici, mais si votre site/projet utilise des erreurs personnalisées partout dans le lieu, vous devrez en principe le définir partout, ou au moins quelque part pour:

  1. Définir la classe d'erreur en premier lieu
  2. Dans le script où vous le lancez
  3. Dans le script où vous l'attrapez

Définir mes erreurs personnalisées dans l’espace de noms global m’évite d’avoir besoin de ma bibliothèque d’erreurs client. Création d'image générant une erreur personnalisée alors que cette erreur personnalisée n'est pas définie.

Aussi, si cela ne va pas, faites-le moi savoir car je viens juste de commencer à le faire récemment

5
DrunkenBeetle