Variable globale dans app.js accessible dans les itinéraires?
91
Comment définir une variable dans app.jset la rendre disponible dans toutes les routes, au moins dans le index.jsfichier situé dans routes. en utilisant le framework express etnode.js
L' objet app.locals a des propriétés qui sont des variables locales dans l'application. Dans votre fichier d'itinéraire, référencez-le avec req.app.locals.
Ronnie Royston
Réponses:
65
Pour créer une variable globale, déclarez-la simplement sans le varmot clé. (En règle générale, ce n'est pas la meilleure pratique, mais dans certains cas, cela peut être utile - faites simplement attention car cela rendra la variable disponible partout.)
//we can now access 'app' without redeclaring it or passing it in.../*
* GET home page.
*/
app.get('/', function(req, res, next){
res.render('index');
});
//...
À titre de note, il est généralement préférable d'être explicite sur le passage des variables et leur instanciation, afin de ne pas annuler accidentellement la référence ailleurs dans l'application, ou quoi que ce soit.
Paul
3
C'est vraiment une mauvaise forme, comme l'a noté Paul. Je suggérerais le modèle d'injection mentionné ci-dessous. Oui, plus de code de plaque chauffante pour ne pas avoir l'air "joli" mais cela garantit que votre code est modulaire ... quelque chose que vous aimerez si ce n'est pas votre dernier projet;)
srquinn
Cela dépend des circonstances IMHO. Oui, les variables globales ne sont généralement pas une bonne pratique (comme je l'ai dit dans ma réponse) et en partant de zéro, je dirais que tout est organisé en modules séparés. Mais si vous intégrez du code existant, il y a souvent d'autres considérations - cela se trouve être une solution (facile, mais dangereuse).
Jesse Fulton
2
Quelqu'un pourrait-il expliquer pourquoi cela fonctionne en référence à la sémantique de Javascript? À quelle portée est- appil associé?
Ali
Je ne pense pas que cette réponse devrait être considérée comme telle correct.
Code Cooker
93
Il est en fait très facile de faire cela en utilisant les méthodes "set" et "get" disponibles sur un objet express.
Exemple comme suit, disons que vous avez une variable appelée config avec vos éléments liés à la configuration que vous souhaitez être disponibles ailleurs:
Définir 'app' global? Oui. Mais cette méthode est la meilleure pour nous sauver des problèmes et du chaos.
diproart
53
pour les retardataires: app.configure est supprimé dans express 4.x
zamil
Nice, req.app.get('name')fonctionne comme un charme. Cette propriété contient une référence à l'instance de l'application Express qui utilise le middleware. expressjs.com/pt-br/api.html#req.app
Lazaro Fernandes Lima Suleiman
58
Une bonne façon de faire est d'utiliser app.localsfourni par Express lui-même.
Voici la documentation.
// In app.js:
app.locals.variable_you_need = 42;
// In index.jsexports.route = function(req, res){
var variable_i_needed = req.app.locals.variable_you_need;
}
J'ai utilisé cette méthode pour localiser les services http et les remplacer facilement dans les tests unitaires.
Alex
28
Pour déclarer une variable globale, vous devez utiliser un objet global . Comme global.yourVariableName. Mais ce n'est pas un vrai moyen. Pour partager des variables entre les modules, essayez d'utiliser un style d'injection comme
Vous travaillez donc avec un ensemble de modules Node, peut-être un framework comme Express.js, et ressentez soudain le besoin de rendre certaines variables globales. Comment rendre les variables globales dans Node.js?
Le conseil le plus courant pour celui-ci est soit de «déclarer la variable sans le mot clé var», soit «d'ajouter la variable à l'objet global» ou «d'ajouter la variable à l'objet GLOBAL». Lequel utilisez-vous?
Tout d'abord, analysons l'objet global. Ouvrez un terminal, démarrez un Node REPL (invite).
Dans Express - en utilisant jshint ou linting, en général - cela devient un problème.
Steven Ventimiglia
5
C'était une question utile, mais pourrait l'être davantage en donnant des exemples de code réels. Même l'article lié ne montre pas réellement d'implémentation. Je soumets donc humblement:
Dans votre app.jsdossier, le haut du fichier:
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 n'aura aucune référence à la app.get()méthode. Laissez-les être définis dans les fichiers d'itinéraires individuels.
routes/index.js:
require('./main');
require('./users');
et enfin, un fichier de routes réelles, routes/main.js:
functionindex (request, response) {
response.render('index', { title: 'Express' });
}
app.get('/',index); // <-- define the routes here now, thanks to the global app variable
Ma méthode préférée est d'utiliser des dépendances circulaires *, que le nœud prend en charge
dans app.js définir var app = module.exports = express();comme votre premier ordre du jour
Désormais, n'importe quel module requis après coup peut var app = require('./app')y accéder
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
routes / 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 independentlyrequire('./user');
require('./blog');
Bon conseil. Je viens de passer de la méthode require ('./ myroutes') (app) à cela et je me suis cogné la tête contre un mur pendant 10 minutes en essayant de comprendre pourquoi aucun de mes itinéraires ne fonctionnait. N'oubliez pas de retirer les spécifications d'itinéraire dans myroutes.js d'un bloc fonctionnel. Doh!
greg
2
Comme d'autres l'ont déjà partagé, app.set('config', config)c'est génial pour cela. Je voulais simplement ajouter quelque chose que je n'ai pas vu dans les réponses existantes qui est assez important. Une instance Node.js est partagée entre toutes les demandes, donc s'il peut être très pratique de partager une partie configou un routerobjet globalement, le stockage des données d'exécution à l'échelle mondiale sera disponible pour les demandes et les utilisateurs . Considérez cet exemple très simple:
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 functionvar foo = function() {
res.send(app.get('message'));
};
setTimeout(foo, 1000);
});
app.listen(3000);
Si vous visitez /baret qu'une autre demande arrive /foo, votre message sera "Welcome to foo!". C'est un exemple idiot, mais il fait passer le message.
J'ai résolu le même problème, mais j'ai dû écrire plus de code. J'ai créé un server.jsfichier qui utilise express pour enregistrer les itinéraires. Il expose une fonction,, registerqui peut être utilisée par d'autres modules pour enregistrer leurs propres routes. Il expose également une fonction,, startServerpour commencer à écouter un port
c'est une chose assez facile, mais les réponses des gens sont à la fois déroutantes et complexes.
laissez-moi vous montrer comment définir une variable globale dans votre expressapplication. Ainsi, vous pouvez y accéder à partir de n'importe quel itinéraire si nécessaire.
Disons que vous voulez définir une variable globale à partir de votre /route principale
router.get('/', (req, res, next) => {
req.app.locals.somethingNew = "Hi setting new global var";
});
Ainsi, vous obtiendrez req.app de toutes les routes. puis vous devrez utiliser le localspour définir les données globales dans. comme ci-dessus, montrez que vous êtes prêt. maintenant
je vais vous montrer comment utiliser ces données
La réponse de John Gordon a été la première des dizaines de réponses à moitié expliquées / documentées que j'ai essayées, à partir de très nombreux sites, qui ont réellement fonctionné. Merci M. Gordon. Désolé, je n'ai pas les points pour cocher votre réponse.
Je voudrais ajouter, pour les autres débutants du partage de fichiers de routage de nœuds, que l'utilisation de la fonction anonyme pour 'index' est ce que l'on verra plus souvent, donc en utilisant l'exemple de John pour le main.js, le fonctionnellement- le code équivalent que l'on trouverait normalement est:
req.app.locals
.Réponses:
Pour créer une variable globale, déclarez-la simplement sans le
var
mot clé. (En règle générale, ce n'est pas la meilleure pratique, mais dans certains cas, cela peut être utile - faites simplement attention car cela rendra la variable disponible partout.)Voici un exemple de visionmedia / screenshot-app
fichier app.js :
/** * Module dependencies. */ var express = require('express') , stylus = require('stylus') , redis = require('redis') , http = require('http'); app = express(); //... require() route files
fichiers routes / 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'); }); //...
la source
app
il associé?correct
.Il est en fait très facile de faire cela en utilisant les méthodes "set" et "get" disponibles sur un objet express.
Exemple comme suit, disons que vous avez une variable appelée config avec vos éléments liés à la configuration que vous souhaitez être disponibles ailleurs:
Dans app.js:
var config = require('./config'); app.configure(function() { ... app.set('config', config); ... }
Dans routes / index.js
exports.index = function(req, res){ var config = req.app.get('config'); // config is now available ... }
la source
req.app.get('name')
fonctionne comme un charme. Cette propriété contient une référence à l'instance de l'application Express qui utilise le middleware. expressjs.com/pt-br/api.html#req.appUne bonne façon de faire est d'utiliser
app.locals
fourni par Express lui-même. Voici la documentation.// 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; }
la source
Pour déclarer une variable globale, vous devez utiliser un objet global . Comme global.yourVariableName. Mais ce n'est pas un vrai moyen. Pour partager des variables entre les modules, essayez d'utiliser un style d'injection comme
someModule.js:
module.exports = function(injectedVariable) { return { somePublicMethod: function() { }, anotherPublicMethod: function() { }, }; };
app.js
var someModule = require('./someModule')(someSharedVariable);
Ou vous pouvez utiliser un objet de substitution pour ce faire. Comme 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');
la source
Voici bien expliquer, en bref:
http://www.hacksparrow.com/global-variables-in-node-js.html
Vous travaillez donc avec un ensemble de modules Node, peut-être un framework comme Express.js, et ressentez soudain le besoin de rendre certaines variables globales. Comment rendre les variables globales dans Node.js?
Le conseil le plus courant pour celui-ci est soit de «déclarer la variable sans le mot clé var», soit «d'ajouter la variable à l'objet global» ou «d'ajouter la variable à l'objet GLOBAL». Lequel utilisez-vous?
Tout d'abord, analysons l'objet global. Ouvrez un terminal, démarrez un Node REPL (invite).
> 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'
la source
le moyen le plus simple est de déclarer une variable globale dans votre app.js, dès le début:
global.mySpecialVariable = "something"
puis dans tous les itinéraires, vous pouvez l'obtenir:
console.log(mySpecialVariable)
la source
C'était une question utile, mais pourrait l'être davantage en donnant des exemples de code réels. Même l'article lié ne montre pas réellement d'implémentation. Je soumets donc humblement:
Dans votre
app.js
dossier, le haut du fichier: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 n'aura aucune référence à la
app.get()
méthode. Laissez-les être définis dans les fichiers d'itinéraires individuels.routes/index.js
:require('./main'); require('./users');
et enfin, un fichier de routes réelles,
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
la source
Ma méthode préférée est d'utiliser des dépendances circulaires *, que le nœud prend en charge
var app = module.exports = express();
comme votre premier ordre du jourvar app = require('./app')
y accéderapp.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
routes / 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');
la source
Comme d'autres l'ont déjà partagé,
app.set('config', config)
c'est génial pour cela. Je voulais simplement ajouter quelque chose que je n'ai pas vu dans les réponses existantes qui est assez important. Une instance Node.js est partagée entre toutes les demandes, donc s'il peut être très pratique de partager une partieconfig
ou unrouter
objet globalement, le stockage des données d'exécution à l'échelle mondiale sera disponible pour les demandes et les utilisateurs . Considérez cet exemple très simple: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);
Si vous visitez
/bar
et qu'une autre demande arrive/foo
, votre message sera "Welcome to foo!". C'est un exemple idiot, mais il fait passer le message.Il y a quelques points intéressants à ce sujet à Pourquoi différentes sessions node.js partagent-elles des variables? .
la source
J'ai résolu le même problème, mais j'ai dû écrire plus de code. J'ai créé un
server.js
fichier qui utilise express pour enregistrer les itinéraires. Il expose une fonction,,register
qui peut être utilisée par d'autres modules pour enregistrer leurs propres routes. Il expose également une fonction,,startServer
pour commencer à écouter un portserver.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 }
Dans un autre module, utilisez ce fichier pour créer une route.
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 }
Dans le fichier principal, amorcez les deux.
app.js require('./server').startServer(7000) require('./web/help').registerHelp()
la source
c'est une chose assez facile, mais les réponses des gens sont à la fois déroutantes et complexes.
laissez-moi vous montrer comment définir une variable globale dans votre
express
application. Ainsi, vous pouvez y accéder à partir de n'importe quel itinéraire si nécessaire.Disons que vous voulez définir une variable globale à partir de votre
/
route principalerouter.get('/', (req, res, next) => { req.app.locals.somethingNew = "Hi setting new global var"; });
Ainsi, vous obtiendrez req.app de toutes les routes. puis vous devrez utiliser le
locals
pour définir les données globales dans. comme ci-dessus, montrez que vous êtes prêt. maintenant je vais vous montrer comment utiliser ces donnéesrouter.get('/register', (req, res, next) => { console.log(req.app.locals.somethingNew); });
Comme ci-dessus, la
register
route que vous accédez aux données a été définie plus tôt.C'est ainsi que vous pouvez faire fonctionner cette chose!
la source
La réponse de John Gordon a été la première des dizaines de réponses à moitié expliquées / documentées que j'ai essayées, à partir de très nombreux sites, qui ont réellement fonctionné. Merci M. Gordon. Désolé, je n'ai pas les points pour cocher votre réponse.
Je voudrais ajouter, pour les autres débutants du partage de fichiers de routage de nœuds, que l'utilisation de la fonction anonyme pour 'index' est ce que l'on verra plus souvent, donc en utilisant l'exemple de John pour le main.js, le fonctionnellement- le code équivalent que l'on trouverait normalement est:
app.get('/',(req, res) { res.render('index', { title: 'Express' }); });
la source
J'ai utilisé app.all
Dans mon cas, j'utilise confit pour la gestion de la configuration,
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(); }); });
Dans les itinéraires, vous faites simplement
req.app.get('config').get('cookie');
la source