Глобальная переменная в app.js доступна в маршрутах?
91
Как мне установить переменную app.jsи сделать так, чтобы она была доступна во всех маршрутах, по крайней мере в index.jsфайле, расположенном в routes. используя экспресс-фреймворк иnode.js
Объект app.locals имеет свойства, которые являются локальными переменными в приложении. В файле маршрута укажите на него ссылку req.app.locals.
Ронни Ройстон
Ответы:
65
Чтобы создать глобальную переменную, просто объявите ее без varключевого слова. (Вообще говоря, это не лучшая практика, но в некоторых случаях она может быть полезна - просто будьте осторожны, так как это сделает переменную доступной везде.)
//we can now access 'app' without redeclaring it or passing it in.../*
* GET home page.
*/
app.get('/', function(req, res, next){
res.render('index');
});
//...
В качестве примечания, как правило, лучше явно указывать на передачу переменных и их создание, чтобы случайно не обнулить ссылку где-нибудь еще в приложении или что-то еще.
Пол
3
Как заметил Пол, это действительно дурной тон. Я бы предложил схему инъекции, упомянутую ниже. Да, больше кода шаблона, чтобы он не выглядел «красиво», но он гарантирует, что ваш код является модульным ... что-то вам понравится, если это не ваш последний проект;)
srquinn
ИМХО, это зависит от обстоятельств. Да, глобальные вары, как правило, не являются хорошей практикой (как я сказал в своем ответе), и, начиная с нуля, я бы сказал, что организовывать все в отдельные модули. Но если вы интегрируетесь с существующим кодом, часто возникают другие соображения - это просто одно (простое, но опасное) решение.
Джесси Фултон,
2
Может ли кто-нибудь объяснить, почему это работает со ссылкой на семантику Javascript? С какой областью appсвязана?
Али
Я не думаю, что этот ответ следует отметить как correctтаковой.
Code Cooker,
93
На самом деле это очень легко сделать, используя методы «set» и «get», доступные для экспресс-объекта.
Пример, приведенный ниже, скажем, у вас есть переменная с именем config с вашими настройками, которые вы хотите сделать доступными в других местах:
Установить глобальное приложение? Да. Но этот метод лучше всего избавит нас от проблем и хаоса.
diproart
53
для опоздавших: app.configure удален в экспресс 4.x
zamil
Красиво, req.app.get('name')работает как шарм. Это свойство содержит ссылку на экземпляр приложения Express, использующего промежуточное ПО. expressjs.com/pt-br/api.html#req.app
Ласаро Фернандес Лима Сулейман
58
Удобный способ сделать это - использовать app.localsсам Express.
Вот документация.
// 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;
}
Я использовал этот метод, чтобы найти службы http и легко переопределить их в модульных тестах.
Alex
28
Чтобы объявить глобальную переменную, вам нужно использовать глобальный объект. Как global.yourVariableName. Но это неверный путь. Чтобы разделить переменные между модулями, попробуйте использовать стиль инъекции, например
Итак, вы работаете с набором модулей Node, возможно, с фреймворком вроде Express.js, и внезапно чувствуете необходимость сделать некоторые переменные глобальными. Как сделать переменные глобальными в Node.js?
Самый распространенный совет - либо «объявить переменную без ключевого слова var», либо «добавить переменную к глобальному объекту», либо «добавить переменную к глобальному объекту». Какой ты используешь?
Прежде всего, давайте проанализируем глобальный объект. Откройте терминал, запустите Node REPL (приглашение).
В Express - при использовании jshint или линтинга вообще - это становится проблемой.
Стивен Вентимилья
5
Это был полезный вопрос, но его можно было бы улучшить, если бы приводились реальные примеры кода. Даже в связанной статье фактически не показана реализация. Поэтому я смиренно утверждаю:
В вашем app.jsфайле верхняя часть файла:
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 не будет иметь каких - либо ссылок на app.get()метод. Оставьте их определять в отдельных файлах маршрутов.
routes/index.js:
require('./main');
require('./users');
и, наконец, фактический файл маршрутов 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
Я предпочитаю использовать круговые зависимости *, которые узел поддерживает
в app.js определите var app = module.exports = express();как ваше первое дело
Теперь любой модуль, необходимый постфактум, может var app = require('./app')получить к нему доступ
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
маршруты / 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');
Отличный совет. Я просто перешел от метода require ('./ myroutes') (app) к этому и в течение 10 минут бился головой о стену, пытаясь понять, почему ни один из моих маршрутов не сработал. Не забудьте взять спецификации маршрута в myroutes.js из функционального блока. Дох!
greg
2
Как уже поделились другие, app.set('config', config)отлично подходит для этого. Я просто хотел добавить кое-что, чего я не видел в существующих ответах, что очень важно. Экземпляр Node.js используется для всех запросов, поэтому, хотя может быть очень практичным делиться некоторыми configили routerобъектами глобально, глобальное хранение данных времени выполнения будет доступно для запросов и пользователей . Рассмотрим этот очень простой пример:
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);
Если вы зайдете /barи получите другой запрос /foo, ваше сообщение будет «Добро пожаловать в foo!». Это глупый пример, но он передает суть.
Я решил ту же проблему, но мне пришлось написать больше кода. Я создал server.jsфайл, в котором для регистрации маршрутов используется экспресс. Он предоставляет функцию, registerкоторая может использоваться другими модулями для регистрации своих собственных маршрутов. Он также предоставляет функцию startServer, чтобы начать прослушивание порта
Ответ Джона Гордона был первым из десятков полуобъясненных / задокументированных ответов, которые я попробовал на многих, многих сайтах, которые действительно сработали. Спасибо, мистер Гордон. Извините, у меня нет очков, чтобы отметить ваш ответ.
Я хотел бы добавить, для других новичков в разделении файла-маршрута-узла, что использование анонимной функции для 'индекса' - это то, что можно будет увидеть чаще, поэтому, используя пример Джона для main.js, функционально - эквивалентный код, который обычно можно найти:
это довольно простая вещь, но ответы людей сбивают с толку и в то же время сложны.
позвольте мне показать вам, как вы можете установить глобальную переменную в вашем express приложении. Таким образом, вы можете получить к нему доступ с любого маршрута по мере необходимости.
Допустим, вы хотите установить глобальную переменную из своего основного /маршрута.
router.get('/', (req, res, next) => {
req.app.locals.somethingNew = "Hi setting new global var";
});
Таким образом, вы получите req.app со всех маршрутов. а затем вам нужно будет использовать localsдля установки глобальных данных. как показано выше, вы все настроены. сейчас
я покажу вам, как использовать эти данные
req.app.locals
.Ответы:
Чтобы создать глобальную переменную, просто объявите ее без
var
ключевого слова. (Вообще говоря, это не лучшая практика, но в некоторых случаях она может быть полезна - просто будьте осторожны, так как это сделает переменную доступной везде.)Вот пример из Visionmedia / screenshot-app
файл app.js :
/** * Module dependencies. */ var express = require('express') , stylus = require('stylus') , redis = require('redis') , http = require('http'); app = express(); //... require() route files
файл 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'); }); //...
источник
app
связана?correct
таковой.На самом деле это очень легко сделать, используя методы «set» и «get», доступные для экспресс-объекта.
Пример, приведенный ниже, скажем, у вас есть переменная с именем config с вашими настройками, которые вы хотите сделать доступными в других местах:
В app.js:
var config = require('./config'); app.configure(function() { ... app.set('config', config); ... }
В routes / index.js
exports.index = function(req, res){ var config = req.app.get('config'); // config is now available ... }
источник
req.app.get('name')
работает как шарм. Это свойство содержит ссылку на экземпляр приложения Express, использующего промежуточное ПО. expressjs.com/pt-br/api.html#req.appУдобный способ сделать это - использовать
app.locals
сам Express. Вот документация.// 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; }
источник
Чтобы объявить глобальную переменную, вам нужно использовать глобальный объект. Как global.yourVariableName. Но это неверный путь. Чтобы разделить переменные между модулями, попробуйте использовать стиль инъекции, например
someModule.js:
module.exports = function(injectedVariable) { return { somePublicMethod: function() { }, anotherPublicMethod: function() { }, }; };
app.js
var someModule = require('./someModule')(someSharedVariable);
Или вы можете использовать для этого суррогатный объект. Нравится хаб .
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');
источник
Вот краткое объяснение:
http://www.hacksparrow.com/global-variables-in-node-js.html
Итак, вы работаете с набором модулей Node, возможно, с фреймворком вроде Express.js, и внезапно чувствуете необходимость сделать некоторые переменные глобальными. Как сделать переменные глобальными в Node.js?
Самый распространенный совет - либо «объявить переменную без ключевого слова var», либо «добавить переменную к глобальному объекту», либо «добавить переменную к глобальному объекту». Какой ты используешь?
Прежде всего, давайте проанализируем глобальный объект. Откройте терминал, запустите Node REPL (приглашение).
> 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'
источник
Самый простой способ - заранее объявить глобальную переменную в app.js:
global.mySpecialVariable = "something"
то по любым маршрутам его можно получить:
console.log(mySpecialVariable)
источник
Это был полезный вопрос, но его можно было бы улучшить, если бы приводились реальные примеры кода. Даже в связанной статье фактически не показана реализация. Поэтому я смиренно утверждаю:
В вашем
app.js
файле верхняя часть файла: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 не будет иметь каких - либо ссылок на
app.get()
метод. Оставьте их определять в отдельных файлах маршрутов.routes/index.js
:require('./main'); require('./users');
и, наконец, фактический файл маршрутов
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
источник
Я предпочитаю использовать круговые зависимости *, которые узел поддерживает
var app = module.exports = express();
как ваше первое делоvar app = require('./app')
получить к нему доступ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
маршруты / 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');
источник
Как уже поделились другие,
app.set('config', config)
отлично подходит для этого. Я просто хотел добавить кое-что, чего я не видел в существующих ответах, что очень важно. Экземпляр Node.js используется для всех запросов, поэтому, хотя может быть очень практичным делиться некоторымиconfig
илиrouter
объектами глобально, глобальное хранение данных времени выполнения будет доступно для запросов и пользователей . Рассмотрим этот очень простой пример: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);
Если вы зайдете
/bar
и получите другой запрос/foo
, ваше сообщение будет «Добро пожаловать в foo!». Это глупый пример, но он передает суть.Есть несколько интересных моментов по этому поводу в Почему разные сеансы node.js используют общие переменные? .
источник
Я решил ту же проблему, но мне пришлось написать больше кода. Я создал
server.js
файл, в котором для регистрации маршрутов используется экспресс. Он предоставляет функцию,register
которая может использоваться другими модулями для регистрации своих собственных маршрутов. Он также предоставляет функциюstartServer
, чтобы начать прослушивание порта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 }
В другом модуле используйте этот файл для создания маршрута.
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 }
В основном файле загрузите оба файла.
app.js require('./server').startServer(7000) require('./web/help').registerHelp()
источник
Ответ Джона Гордона был первым из десятков полуобъясненных / задокументированных ответов, которые я попробовал на многих, многих сайтах, которые действительно сработали. Спасибо, мистер Гордон. Извините, у меня нет очков, чтобы отметить ваш ответ.
Я хотел бы добавить, для других новичков в разделении файла-маршрута-узла, что использование анонимной функции для 'индекса' - это то, что можно будет увидеть чаще, поэтому, используя пример Джона для main.js, функционально - эквивалентный код, который обычно можно найти:
app.get('/',(req, res) { res.render('index', { title: 'Express' }); });
источник
Я использовал app.all
В моем случае я использую confit для управления конфигурацией,
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(); }); });
В маршрутах вы просто делаете
req.app.get('config').get('cookie');
источник
это довольно простая вещь, но ответы людей сбивают с толку и в то же время сложны.
позвольте мне показать вам, как вы можете установить глобальную переменную в вашем
express
приложении. Таким образом, вы можете получить к нему доступ с любого маршрута по мере необходимости.Допустим, вы хотите установить глобальную переменную из своего основного
/
маршрута.router.get('/', (req, res, next) => { req.app.locals.somethingNew = "Hi setting new global var"; });
Таким образом, вы получите req.app со всех маршрутов. а затем вам нужно будет использовать
locals
для установки глобальных данных. как показано выше, вы все настроены. сейчас я покажу вам, как использовать эти данныеrouter.get('/register', (req, res, next) => { console.log(req.app.locals.somethingNew); });
Как указано выше из
register
маршрута, к которому вы обращаетесь, данные были установлены ранее.Вот как можно заставить эту штуку работать!
источник