¿Cómo configuro una variable app.jsy la tengo disponible en todas las rutas, al menos en el index.jsarchivo ubicado en las rutas? utilizando el marco express ynode.js
El objeto app.locals tiene propiedades que son variables locales dentro de la aplicación. En su archivo de ruta, haga referencia a él con req.app.locals.
Ronnie Royston
Respuestas:
65
Para hacer una variable global, simplemente declare sin la varpalabra clave. (En términos generales, esta no es la mejor práctica, pero en algunos casos puede ser útil; solo tenga cuidado, ya que hará que la variable esté disponible en todas partes).
//we can now access 'app' without redeclaring it or passing it in.../*
* GET home page.
*/
app.get('/', function(req, res, next){
res.render('index');
});
//...
Como nota, generalmente es mejor ser explícito acerca de pasar variables e instanciarlas, para que no anule accidentalmente la referencia en otro lugar de la aplicación, o lo que sea.
Paul
3
Esta es realmente mala forma, como señaló Paul. Sugeriría el patrón de inyección mencionado a continuación. Sí, más código de placa de caldera para que no se vea "bonito" pero garantiza que su código sea modular ... algo que le gustará si este no es su último proyecto;)
srquinn
Depende de las circunstancias en mi humilde opinión. Sí, las vars globales generalmente no son una buena práctica (como dije en mi respuesta) y, al comenzar desde cero, diría que organice todo en módulos separados. Pero si se está integrando con código existente, a menudo hay otras consideraciones: esta es una solución (fácil, pero peligrosa).
Jesse Fulton
2
¿Alguien podría explicar por qué esto funciona en referencia a la semántica de Javascript? ¿A qué alcance appse asocia?
Ali
No creo que esta respuesta deba marcar como correctuna.
Code Cooker
93
En realidad, es muy fácil hacer esto usando los métodos "set" y "get" disponibles en un objeto express.
Ejemplo de la siguiente manera, digamos que tiene una variable llamada config con las cosas relacionadas con su configuración que desea que estén disponibles en otros lugares:
¿Establecer 'aplicación' global? Si. Pero este método es el mejor para salvarnos de los problemas y el caos.
diproart
53
para los que llegan tarde: app.configure se elimina en Express 4.x
zamil
Agradable, req.app.get('name')funciona a las mil maravillas. Esta propiedad contiene una referencia a la instancia de la aplicación Express que usa el middleware. expressjs.com/pt-br/api.html#req.app
Lazaro Fernandes Lima Suleiman
57
Una forma ordenada de hacer esto es utilizando el app.localspropio Express.
Aquí está la documentación.
// 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;
}
Usé este método para ubicar servicios http y anular fácilmente en pruebas unitarias.
Alex
28
Para declarar una variable global, debe utilizar un objeto global . Como global.yourVariableName. Pero no es una verdadera forma. Para compartir variables entre módulos, intente usar un estilo de inyección como
Entonces, está trabajando con un conjunto de módulos de nodo, tal vez un marco como Express.js, y de repente siente la necesidad de hacer que algunas variables sean globales. ¿Cómo se hacen las variables globales en Node.js?
El consejo más común para este es "declarar la variable sin la palabra clave var" o "agregar la variable al objeto global" o "agregar la variable al objeto GLOBAL". Cual usas?
En primer lugar, analicemos el objeto global. Abra una terminal, inicie un REPL de nodo (indicador).
En Express, cuando se usa jshint o linting, en general, esto se convierte en un problema.
Steven Ventimiglia
5
Esta fue una pregunta útil, pero podría ser más importante si proporciona ejemplos de código reales. Incluso el artículo vinculado no muestra realmente una implementación. Por tanto, humildemente me someto:
En su app.jsarchivo, la parte superior del archivo:
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 no tendrá ninguna referencia al app.get()método. Deje que se definan en los archivos de rutas individuales.
routes/index.js:
require('./main');
require('./users');
y, por último, un archivo de rutas reales, 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
Mi forma preferida es usar dependencias circulares *, que el nodo admite
en app.js define var app = module.exports = express();como su primera orden del día
Ahora cualquier módulo requerido después del hecho puede var app = require('./app')acceder a él.
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
rutas / 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');
Buen consejo. Acabo de pasar del método require ('./ myroutes') (app) a hacer esto y golpeé mi cabeza contra una pared durante 10 minutos tratando de averiguar por qué ninguna de mis rutas funcionó. No olvide sacar las especificaciones de ruta en myroutes.js de un bloque de funciones. Doh!
Greg
2
Como otros ya han compartido, app.set('config', config)es genial para esto. Solo quería agregar algo que no vi en las respuestas existentes que es bastante importante. Una instancia de Node.js se comparte en todas las solicitudes, por lo que, si bien puede ser muy práctico compartir algunos configu routerobjetos de forma global, el almacenamiento de datos en tiempo de ejecución de forma global estará disponible para todas las solicitudes y usuarios . Considere este ejemplo muy 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 visita /bary recibe otra solicitud /foo, su mensaje será "¡Bienvenido a foo!". Este es un ejemplo tonto, pero transmite el mensaje.
Resolví el mismo problema, pero tuve que escribir más código. Creé un server.jsarchivo, que usa express para registrar rutas. Expone una función, registerque puede ser utilizada por otros módulos para registrar sus propias rutas. También expone una función startServer, para empezar a escuchar un puerto
La respuesta de John Gordon fue la primera de docenas de respuestas a medio explicar / documentadas que probé, en muchos, muchos sitios, que realmente funcionaron. Gracias, señor Gordon. Lo siento, no tengo los puntos para mejorar tu respuesta.
Me gustaría agregar, para otros novatos en node-route-file-splitting, que el uso de la función anónima para 'índice' es lo que uno verá más a menudo, por lo que usando el ejemplo de John para main.js, el funcionalmente- el código equivalente que uno encontraría normalmente es:
esto es bastante fácil, pero las respuestas de las personas son confusas y complejas al mismo tiempo.
déjame mostrarte cómo puedes establecer una variable global en tu expressaplicación. Para que pueda acceder a él desde cualquier ruta según sea necesario.
Digamos que desea establecer una variable global de su /ruta principal
router.get('/', (req, res, next) => {
req.app.locals.somethingNew = "Hi setting new global var";
});
Entonces obtendrás req.app de todas las rutas. y luego tendrá que usar localspara establecer datos globales en. como arriba muestra que estás listo. ahora
te mostraré cómo usar esos datos
req.app.locals
.Respuestas:
Para hacer una variable global, simplemente declare sin la
var
palabra clave. (En términos generales, esta no es la mejor práctica, pero en algunos casos puede ser útil; solo tenga cuidado, ya que hará que la variable esté disponible en todas partes).Aquí hay un ejemplo de visionmedia / screenshot-app
archivo app.js :
/** * Module dependencies. */ var express = require('express') , stylus = require('stylus') , redis = require('redis') , http = require('http'); app = express(); //... require() route files
rutas de archivo / 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'); }); //...
fuente
app
se asocia?correct
una.En realidad, es muy fácil hacer esto usando los métodos "set" y "get" disponibles en un objeto express.
Ejemplo de la siguiente manera, digamos que tiene una variable llamada config con las cosas relacionadas con su configuración que desea que estén disponibles en otros lugares:
En app.js:
var config = require('./config'); app.configure(function() { ... app.set('config', config); ... }
En rutas / index.js
exports.index = function(req, res){ var config = req.app.get('config'); // config is now available ... }
fuente
req.app.get('name')
funciona a las mil maravillas. Esta propiedad contiene una referencia a la instancia de la aplicación Express que usa el middleware. expressjs.com/pt-br/api.html#req.appUna forma ordenada de hacer esto es utilizando el
app.locals
propio Express. Aquí está la documentación.// 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; }
fuente
Para declarar una variable global, debe utilizar un objeto global . Como global.yourVariableName. Pero no es una verdadera forma. Para compartir variables entre módulos, intente usar un estilo de inyección como
someModule.js:
module.exports = function(injectedVariable) { return { somePublicMethod: function() { }, anotherPublicMethod: function() { }, }; };
app.js
var someModule = require('./someModule')(someSharedVariable);
O puede usar un objeto sustituto para hacer eso. Como 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');
fuente
A continuación se explican bien, en resumen:
http://www.hacksparrow.com/global-variables-in-node-js.html
Entonces, está trabajando con un conjunto de módulos de nodo, tal vez un marco como Express.js, y de repente siente la necesidad de hacer que algunas variables sean globales. ¿Cómo se hacen las variables globales en Node.js?
El consejo más común para este es "declarar la variable sin la palabra clave var" o "agregar la variable al objeto global" o "agregar la variable al objeto GLOBAL". Cual usas?
En primer lugar, analicemos el objeto global. Abra una terminal, inicie un REPL de nodo (indicador).
> 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'
fuente
la forma más fácil es declarar una variable global en su app.js, desde el principio:
global.mySpecialVariable = "something"
entonces en cualquier ruta puedes conseguirlo:
console.log(mySpecialVariable)
fuente
Esta fue una pregunta útil, pero podría ser más importante si proporciona ejemplos de código reales. Incluso el artículo vinculado no muestra realmente una implementación. Por tanto, humildemente me someto:
En su
app.js
archivo, la parte superior del archivo: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 no tendrá ninguna referencia al
app.get()
método. Deje que se definan en los archivos de rutas individuales.routes/index.js
:require('./main'); require('./users');
y, por último, un archivo de rutas reales,
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
fuente
Mi forma preferida es usar dependencias circulares *, que el nodo admite
var app = module.exports = express();
como su primera orden del díavar app = require('./app')
acceder a él.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
rutas / 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');
fuente
Como otros ya han compartido,
app.set('config', config)
es genial para esto. Solo quería agregar algo que no vi en las respuestas existentes que es bastante importante. Una instancia de Node.js se comparte en todas las solicitudes, por lo que, si bien puede ser muy práctico compartir algunosconfig
urouter
objetos de forma global, el almacenamiento de datos en tiempo de ejecución de forma global estará disponible para todas las solicitudes y usuarios . Considere este ejemplo muy 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 visita
/bar
y recibe otra solicitud/foo
, su mensaje será "¡Bienvenido a foo!". Este es un ejemplo tonto, pero transmite el mensaje.Hay algunos puntos interesantes sobre esto en ¿Por qué las diferentes sesiones de node.js comparten variables? .
fuente
Resolví el mismo problema, pero tuve que escribir más código. Creé un
server.js
archivo, que usa express para registrar rutas. Expone una función,register
que puede ser utilizada por otros módulos para registrar sus propias rutas. También expone una funciónstartServer
, para empezar a escuchar un puertoserver.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 }
En otro módulo, use este archivo para crear una ruta.
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 }
En el archivo principal, arranque ambos.
app.js require('./server').startServer(7000) require('./web/help').registerHelp()
fuente
La respuesta de John Gordon fue la primera de docenas de respuestas a medio explicar / documentadas que probé, en muchos, muchos sitios, que realmente funcionaron. Gracias, señor Gordon. Lo siento, no tengo los puntos para mejorar tu respuesta.
Me gustaría agregar, para otros novatos en node-route-file-splitting, que el uso de la función anónima para 'índice' es lo que uno verá más a menudo, por lo que usando el ejemplo de John para main.js, el funcionalmente- el código equivalente que uno encontraría normalmente es:
app.get('/',(req, res) { res.render('index', { title: 'Express' }); });
fuente
Solía app.all
En mi caso, estoy usando confit para la gestión de la configuración,
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(); }); });
En rutas, simplemente haces
req.app.get('config').get('cookie');
fuente
esto es bastante fácil, pero las respuestas de las personas son confusas y complejas al mismo tiempo.
déjame mostrarte cómo puedes establecer una variable global en tu
express
aplicación. Para que pueda acceder a él desde cualquier ruta según sea necesario.Digamos que desea establecer una variable global de su
/
ruta principalrouter.get('/', (req, res, next) => { req.app.locals.somethingNew = "Hi setting new global var"; });
Entonces obtendrás req.app de todas las rutas. y luego tendrá que usar
locals
para establecer datos globales en. como arriba muestra que estás listo. ahora te mostraré cómo usar esos datosrouter.get('/register', (req, res, next) => { console.log(req.app.locals.somethingNew); });
Como arriba, desde la
register
ruta a la que está accediendo, los datos se establecieron anteriormente.¡Así es como puedes hacer que esto funcione!
fuente