경로에서 액세스 할 수있는 app.js의 전역 변수?


91

변수를에서 설정하고 app.js모든 경로에서 최소한 경로에있는 index.js파일 에서 사용할 수있게하려면 어떻게해야합니까 ? 익스프레스 프레임 워크 사용 및node.js


1
app.locals의 목적은 애플리케이션 내 로컬 변수 특성을 갖는다. 경로 파일에서 req.app.locals.
Ronnie Royston

답변:


66

전역 변수를 만들려면 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

파일 경로 /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
참고로, 일반적으로 변수를 전달하고 인스턴스화하는 것에 대해 명시 적으로 지정하는 것이 더 낫기 때문에 실수로 앱의 다른 곳에서 참조를 무효화하거나 무엇을 가지고 있는지 확인하십시오.
Paul

3
Paul이 지적했듯이 이것은 정말 나쁜 형태입니다. 아래에 언급 된 주입 패턴을 제안합니다. 예, 더 많은 보일러 플레이트 코드가 "예쁘게"보이지는 않지만 코드가 모듈 식인지 확인합니다 ... 마지막 프로젝트가 아니라면 좋아할 것입니다;)
srquinn

IMHO 상황에 따라 다릅니다. 예, 전역 vars는 일반적으로 좋은 습관이 아니며 (내 대답에서 언급했듯이) 처음부터 시작할 때 모든 것을 별도의 모듈로 구성한다고 말하고 싶습니다. 그러나 기존 코드와 통합하는 경우 다른 고려 사항이 종종 있습니다. 이것은 하나의 (쉽지만 위험한) 솔루션 일뿐입니다.
Jesse Fulton

2
누군가 이것이 Javascript의 의미론과 관련하여 왜 작동하는지 설명 할 수 있습니까? 어떤 범위에 app연결됩니까?
알리

나는이 대답이 correct하나로 표시되어야한다고 생각하지 않습니다 .
Code Cooker

94

실제로 Express 객체에서 사용할 수있는 "set"및 "get"메소드를 사용하여이 작업을 수행하는 것은 매우 쉽습니다.

다음과 같이 예를 들어, 다른 위치에서 사용하려는 구성 관련 항목과 함께 config라는 변수가 있다고 가정합니다.

app.js에서 :

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

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

route / index.js에서

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

'앱'을 전역으로 설정 하시겠습니까? 예. 그러나이 방법은 문제와 혼란에서 우리를 구하는 데 가장 좋습니다.
diproart 2014

53
늦은 사용자 : app.configure가 express 4.x에서 제거됨
zamil

니스, req.app.get('name')매력처럼 작동합니다. 이 속성은 미들웨어를 사용하는 Express 애플리케이션의 인스턴스에 대한 참조를 보유합니다. expressjs.com/pt-br/api.html#req.app
라자로 페르난데스 리마 술레이

58

이를위한 깔끔한 방법은 app.localsExpress 자체에서 제공하는 사용 입니다. 다음 은 문서입니다.

// 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
이 방법을 사용하여 http 서비스를 찾고 단위 테스트에서 쉽게 재정의했습니다.
Alex

28

전역 변수를 선언하려면 전역 개체를 사용해야 합니다. 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');

7

간단히 설명하면 다음과 같습니다.

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

따라서 Express.js와 같은 프레임 워크와 같은 일련의 Node 모듈로 작업하고 있는데 갑자기 일부 변수를 전역으로 만들어야 할 필요성을 느낍니다. Node.js에서 변수를 전역으로 만드는 방법은 무엇입니까?

이것에 대한 가장 일반적인 조언은 "var 키워드없이 변수를 선언"하거나 "글로벌 객체에 변수를 추가"또는 "GLOBAL 객체에 변수를 추가"하는 것입니다. 어느 것을 사용합니까?

먼저 전역 객체를 분석해 보겠습니다. 터미널을 열고 노드 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'

Express에서-jshint 또는 linting을 사용할 때 일반적으로 이것이 문제가됩니다.
Steven Ventimiglia

7

가장 쉬운 방법은 초기에 app.js에서 전역 변수를 선언하는 것입니다.

global.mySpecialVariable = "something"

그런 다음 모든 경로에서 얻을 수 있습니다.

console.log(mySpecialVariable)

1
Express에서-jshint 또는 linting을 사용할 때 일반적으로 이것이 문제가됩니다.
Steven Ventimiglia

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:

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

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

4

내가 선호하는 방법은 순환 종속성 *을 사용하는 것입니다.

  • 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


route / 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');

좋은 팁. 방금 require ( './ myroutes') (app) 메서드에서이 작업을 수행하고 내 경로가 작동하지 않는 이유를 파악하기 위해 10 분 동안 벽에 머리를 부딪 혔습니다. 함수 블록에서 myroutes.js의 경로 사양을 가져 오는 것을 잊지 마십시오. 도!
그렉

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 function
    var foo = function() {
        res.send(app.get('message'));
    };
    setTimeout(foo, 1000);
});

app.listen(3000);

을 (를) 방문 /bar하고 다른 요청이 /foo이면 메시지는 "Welcome to foo!"가됩니다. 이것은 어리석은 예이지만 요점을 이해합니다.

다른 node.js 세션이 변수를 공유하는 이유 에 대해 흥미로운 점이 있습니다 . .


1

같은 문제를 해결했지만 더 많은 코드를 작성해야했습니다. server.jsExpress를 사용하여 경로를 등록 하는 파일을 만들었습니다 . 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()

1

이것은 매우 쉬운 일이지만 사람들의 대답은 동시에 혼란스럽고 복잡합니다.

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경로 에서 액세스하는 데이터가 이전에 설정되었습니다.

이것이이 일을 작동시킬 수있는 방법입니다!


0

John Gordon의 답변은 실제로 효과가있는 많은 사이트에서 시도한 반 설명 / 문서화 된 수십 개의 답변 중 첫 번째 답변이었습니다. 고든 씨 감사합니다. 죄송합니다. 답변을 강조 할 포인트가 없습니다.

다른 초보자를 위해 node-route-file-splitting에 대해 추가하고 싶습니다 .'index '에 대한 익명 함수의 사용은 더 자주 보게 될 것이므로 기능적으로는 main.js에 대한 John의 예제를 사용합니다. 일반적으로 찾을 수있는 동등한 코드는 다음과 같습니다.

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

0

나는 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');

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.