Globale Variable in app.js in Routen zugänglich?


88

Wie setze ich eine Variable in app.jsund habe sie in allen Routen verfügbar, zumindest in der index.jsDatei in Routen. unter Verwendung des Express-Frameworks undnode.js


1
Das Objekt app.locals verfügt über Eigenschaften, die lokale Variablen innerhalb der Anwendung sind. Verweisen Sie in Ihrer Routendatei auf req.app.locals.
Ronnie Royston

Antworten:


62

Um eine globale Variable zu erstellen, deklarieren Sie sie einfach ohne das varSchlüsselwort. (Im Allgemeinen ist dies keine bewährte Methode, aber in einigen Fällen kann es nützlich sein - seien Sie vorsichtig, da die Variable dadurch überall verfügbar wird.)

Hier ist ein Beispiel aus der Visionmedia / Screenshot-App

Datei app.js :

/**
 * Module dependencies.
 */

var express = require('express')
  , stylus = require('stylus')
  , redis = require('redis')
  , http = require('http');

app = express();

//... require() route files

Datei route / main.js

//we can now access 'app' without redeclaring it or passing it in...

/*
 * GET home page.
 */

app.get('/', function(req, res, next){
  res.render('index');
});

//...

6
Als Hinweis ist es im Allgemeinen besser, explizit Variablen weiterzugeben und zu instanziieren, damit Sie den Ref nicht versehentlich an einer anderen Stelle in der App auf Null setzen oder was Sie haben.
Paul

3
Das ist wirklich eine schlechte Form, wie Paul bemerkte. Ich würde das unten erwähnte Injektionsmuster vorschlagen. Ja, mehr Kesselplattencode, damit er nicht "hübsch" aussieht, aber er stellt sicher, dass Ihr Code modular aufgebaut ist ... etwas, das Ihnen gefällt, wenn dies nicht Ihr letztes Projekt ist;)
srquinn

Es hängt meiner Meinung nach von den Umständen ab. Ja, globale Variablen sind im Allgemeinen keine gute Praxis (wie ich in meiner Antwort angegeben habe), und wenn ich von vorne anfange, würde ich sagen, alles in separate Module zu organisieren. Wenn Sie jedoch in vorhandenen Code integrieren, gibt es häufig andere Überlegungen - dies ist nur eine (einfache, aber gefährliche) Lösung.
Jesse Fulton

2
Könnte jemand erklären, warum dies in Bezug auf die Semantik von Javascript funktioniert? Mit welchem ​​Bereich wird appverbunden?
Ali

Ich denke nicht, dass diese Antwort als correcteine markiert werden sollte .
Code Cooker

91

Es ist tatsächlich sehr einfach, dies mit den Methoden "set" und "get" zu tun, die für ein Express-Objekt verfügbar sind.

Beispiel wie folgt: Angenommen, Sie haben eine Variable namens config mit Ihren konfigurationsbezogenen Elementen, die an anderen Stellen verfügbar sein sollen:

In app.js:

var config = require('./config');

app.configure(function() {
  ...
  app.set('config', config); 
  ...
}

In routen / index.js

exports.index = function(req, res){
  var config = req.app.get('config');
  // config is now available
  ...
}

'App' global einstellen? Ja. Aber diese Methode ist am besten geeignet, um uns vor Problemen und Chaos zu bewahren.
Diproart

51
für späte Ankömmlinge: app.configure wird in Express 4.x entfernt
zamil

Schön, req.app.get('name')wirkt wie ein Zauber. Diese Eigenschaft enthält einen Verweis auf die Instanz der Express-Anwendung, die die Middleware verwendet. expressjs.com/pt-br/api.html#req.app
Lazaro Fernandes Lima Suleiman

56

Eine gute Möglichkeit, dies zu tun, ist die Verwendung app.localsdurch Express selbst. Hier ist die Dokumentation.

// In app.js:
app.locals.variable_you_need = 42;

// In index.js
exports.route = function(req, res){
    var variable_i_needed = req.app.locals.variable_you_need;
}

1
Ich habe diese Methode verwendet, um http-Dienste zu finden und in Komponententests leicht zu überschreiben.
Alex

28

Um eine globale Variable zu deklarieren, müssen Sie ein globales Objekt verwenden. Wie global.yourVariableName. Aber es ist kein wahrer Weg. Um Variablen zwischen Modulen zu teilen, versuchen Sie, einen Injektionsstil wie zu verwenden

someModule.js:

module.exports = function(injectedVariable) {
    return {
        somePublicMethod: function() {
        },
        anotherPublicMethod: function() {
        },
    };
};

app.js.

var someModule = require('./someModule')(someSharedVariable);

Oder Sie können ein Ersatzobjekt verwenden, um dies zu tun. Wie Hub .

someModule.js:

var hub = require('hub');

module.somePublicMethod = function() {
    // We can use hub.db here
};

module.anotherPublicMethod = function() {
};

app.js.

var hub = require('hub');
hub.db = dbConnection;
var someModule = require('./someModule');

7

Hier kurz erklärt:

http://www.hacksparrow.com/global-variables-in-node-js.html

Sie arbeiten also mit einer Reihe von Knotenmodulen, möglicherweise einem Framework wie Express.js, und haben plötzlich das Bedürfnis, einige Variablen global zu machen. Wie macht man Variablen in Node.js global?

Der häufigste Ratschlag hierfür ist, entweder "die Variable ohne das Schlüsselwort var zu deklarieren" oder "die Variable zum globalen Objekt hinzuzufügen" oder "die Variable zum GLOBAL-Objekt hinzuzufügen". Welches benutzt du?

Lassen Sie uns zunächst das globale Objekt analysieren. Öffnen Sie ein Terminal und starten Sie einen Node REPL (Eingabeaufforderung).

> global.name
undefined
> global.name = 'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> delete global.name
true
> GLOBAL.name
undefined
> name = 'El Capitan'
'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> var name = 'Sparrow'
undefined
> global.name
'Sparrow'

In Express wird dies - bei Verwendung von Jshint oder Flusen im Allgemeinen - zu einem Problem.
Steven Ventimiglia

6

Am einfachsten ist es, frühzeitig eine globale Variable in Ihrer app.js zu deklarieren:

global.mySpecialVariable = "something"

dann können Sie es auf allen Routen bekommen:

console.log(mySpecialVariable)

1
In Express wird dies - bei Verwendung von Jshint oder Flusen im Allgemeinen - zu einem Problem.
Steven Ventimiglia

5

Dies war eine hilfreiche Frage, könnte aber noch wichtiger sein, indem tatsächliche Codebeispiele angegeben werden. Auch der verlinkte Artikel zeigt eigentlich keine Implementierung. Ich reiche daher demütig ein:

In Ihrer app.jsDatei oben in der Datei:

var express = require('express')
, http = require('http')
, path = require('path');

app = express(); //IMPORTANT!  define the global app variable prior to requiring routes!

var routes = require('./routes');

app.js hat keinen Verweis auf die app.get()Methode. Lassen Sie diese in den einzelnen Routendateien definiert werden.

routes/index.js::

require('./main');
require('./users');

und schließlich eine aktuelle Routendatei routes/main.js:

function index (request, response) {
    response.render('index', { title: 'Express' });
}

app.get('/',index); // <-- define the routes here now, thanks to the global app variable

4

Meine bevorzugte Methode ist die Verwendung von zirkulären Abhängigkeiten *, die der Knoten unterstützt

  • in app.js definieren Sie var app = module.exports = express();als Ihre erste Aufgabe
  • Jetzt kann jedes Modul, das nachträglich benötigt wird, var app = require('./app')darauf zugreifen


app.js.

var express   = require('express');
var app = module.exports = express(); //now app.js can be required to bring app into any file

//some app/middleware, config, setup, etc, including app.use(app.router)

require('./routes'); //module.exports must be defined before this line


routen / index.js

var app = require('./app');

app.get('/', function(req, res, next) {
  res.render('index');
});

//require in some other route files...each of which requires app independently
require('./user');
require('./blog');

Toller Tipp. Ich bin gerade von der Methode require ('./ myroutes') (app) zu dieser Methode übergegangen und habe meinen Kopf 10 Minuten lang gegen eine Wand geschlagen, um herauszufinden, warum keine meiner Routen funktioniert hat. Vergessen Sie nicht, die Routenspezifikationen in myroutes.js aus einem Funktionsblock zu entfernen. Doh!
Greg

2

Wie andere bereits geteilt haben, app.set('config', config)ist das großartig. Ich wollte nur etwas hinzufügen, das ich in vorhandenen Antworten nicht gesehen habe, was ziemlich wichtig ist. Eine Node.js-Instanz wird für alle Anforderungen gemeinsam genutzt. Obwohl es sehr praktisch sein kann, einige configoder routerObjekte global freizugeben, ist das globale Speichern von Laufzeitdaten für alle Anforderungen und Benutzer verfügbar . Betrachten Sie dieses sehr einfache Beispiel:

var express = require('express');
var app = express();

app.get('/foo', function(req, res) {
    app.set('message', "Welcome to foo!");
    res.send(app.get('message'));
});

app.get('/bar', function(req, res) {
    app.set('message', "Welcome to bar!");

    // some long running async function
    var foo = function() {
        res.send(app.get('message'));
    };
    setTimeout(foo, 1000);
});

app.listen(3000);

Wenn Sie uns besuchen /barund eine andere Anfrage eingeht /foo, lautet Ihre Nachricht "Willkommen bei foo!". Dies ist ein dummes Beispiel, aber es bringt den Punkt auf den Punkt.

Es gibt einige interessante Punkte dazu unter Warum teilen verschiedene node.js-Sitzungen Variablen? .


1

Ich habe das gleiche Problem gelöst, musste aber mehr Code schreiben. Ich habe eine server.jsDatei erstellt, die Express verwendet, um Routen zu registrieren. Es stellt eine Funktion zur Verfügung, registermit der andere Module ihre eigenen Routen registrieren können. Es stellt auch eine Funktion startServerzur Verfügung, mit der Sie einen Port abhören können

server.js

const express = require('express');
const app = express();

const register = (path,method,callback) => methodCalled(path, method, callback)

const methodCalled = (path, method, cb) => {
  switch (method) {
    case 'get':
      app.get(path, (req, res) => cb(req, res))
      break;
    ...
    ...  
    default:
      console.log("there has been an error");
  }
}

const startServer = (port) => app.listen(port, () => {console.log(`successfully started at ${port}`)})

module.exports = {
  register,
  startServer
}

Verwenden Sie diese Datei in einem anderen Modul, um eine Route zu erstellen.

help.js

const app = require('../server');

const registerHelp = () => {
  app.register('/help','get',(req, res) => {
    res.send("This is the help section")
  }),
  app.register('/help','post',(req, res) => {
    res.send("This is the help section")
  })}

module.exports = {
  registerHelp
}

Booten Sie in der Hauptdatei beide.

app.js

require('./server').startServer(7000)
require('./web/help').registerHelp()

0

John Gordons Antwort war die erste von Dutzenden von halb erklärten / dokumentierten Antworten, die ich von vielen, vielen Websites aus versuchte und die tatsächlich funktionierten. Vielen Dank, Herr Gordon. Entschuldigung, ich habe nicht die Punkte, um Ihre Antwort zu verbessern.

Ich möchte für andere Neulinge bei der Aufteilung von Knoten-Routen-Dateien hinzufügen, dass die Verwendung der anonymen Funktion für 'Index' das ist, was man öfter sehen wird. Verwenden Sie also Johns Beispiel für die Datei main.js. äquivalenter Code, den man normalerweise finden würde, ist:

app.get('/',(req, res) {
    res.render('index', { title: 'Express' });
});

0

Ich habe app.all verwendet

Die Methode app.all () ist nützlich, um "globale" Logik für bestimmte Pfadpräfixe oder beliebige Übereinstimmungen zuzuordnen.

In meinem Fall verwende ich Confit für das Konfigurationsmanagement.

app.all('*', function (req, res, next) {
    confit(basedir).create(function (err, config) {
        if (err) {
            throw new Error('Failed to load configuration ', err);
        }
        app.set('config', config);
        next();
    });
});

Auf Routen tun Sie es einfach req.app.get('config').get('cookie');


-1

Das ist ziemlich einfach, aber die Antworten der Leute sind gleichzeitig verwirrend und komplex.

Lassen Sie mich Ihnen zeigen, wie Sie globale Variablen in Ihrer expressApp festlegen können . So können Sie bei Bedarf von jeder Route darauf zugreifen.

Angenommen, Sie möchten eine globale Variable aus Ihrer /Hauptroute festlegen

router.get('/', (req, res, next) => {

  req.app.locals.somethingNew = "Hi setting new global var";
});

Sie erhalten also req.app von allen Routen. und dann müssen Sie das verwenden locals, um globale Daten festzulegen. Wie oben zeigen Sie, dass Sie fertig sind. Jetzt werde ich Ihnen zeigen, wie Sie diese Daten verwenden

router.get('/register', (req, res, next) => {

  console.log(req.app.locals.somethingNew);
});

Wie oben von der registerRoute, auf die Sie zugreifen, wurden die Daten früher festgelegt.

So können Sie dieses Ding zum Laufen bringen!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.