Глобальная переменная в app.js доступна в маршрутах?

Как мне установить переменную в app.js и он будет доступен на всех маршрутах, по крайней мере в index.js файл находится в маршрутах. using the express framework and node.js

14 ответов

Решение

Чтобы создать глобальную переменную, просто объявите ее без var ключевое слово. (Вообще говоря, это не лучшая практика, но в некоторых случаях это может быть полезно - просто будьте осторожны, поскольку это сделает переменную доступной везде.)

Вот пример из https://github.com/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

файл маршруты /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');
});

//...

На самом деле это очень легко сделать, используя методы "set" и "get", доступные для экспресс-объекта.

Например, скажем, у вас есть переменная с именем config с вашими настройками, которые вы хотите быть доступными в других местах:

В app.js:

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

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

В маршрутах /index.js

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

Оптимальный способ сделать это - использовать 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');

Самый простой способ - объявить глобальную переменную в вашем app.js, на раннем этапе:

global.mySpecialVariable = "something"

тогда по любым маршрутам вы можете получить это:

console.log(mySpecialVariable)

Вот объясни хорошо, вкратце:

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

Итак, вы работаете с набором модулей Node, может быть, с фреймворком, подобным Express.js, и вдруг почувствуете необходимость сделать некоторые переменные глобальными. Как сделать переменные глобальными в Node.js?

Наиболее распространенный совет для этого - либо "объявить переменную без ключевого слова var", либо "добавить переменную в глобальный объект", либо "добавить переменную в объект GLOBAL". Какой из них вы используете?

Прежде всего, давайте проанализируем глобальный объект. Откройте терминал, запустите 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 файл, верх файла:

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

Это довольно простая вещь, но ответы людей сбивают с толку и в то же время сложны.

позвольте мне показать вам, как вы можете установить глобальную переменную в вашем 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 маршрут, по которому вы получаете доступ к данным, был установлен ранее.

Вот как можно заставить эту штуку работать!

Мой предпочтительный способ - использовать циклические зависимости *, которые поддерживает узел

  • в 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 independently
require('./user');
require('./blog');
      const app = require('express')(); 
app.set('globalvar', "xyz");
app.get('globalvar');

Как уже поделились другие, 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 совместно используют переменные?,

Я использовал app.all

Метод 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');

Я решил ту же проблему, но мне пришлось написать больше кода. Я создал 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' });
});
Другие вопросы по тегам