ルートでアクセス可能なapp.jsのグローバル変数?


91

変数をに設定してapp.js、少なくともルートにあるindex.jsファイルですべてのルートで使用できるようにするにはどうすればよいですか。Expressフレームワークを使用してnode.js


1
app.localsのオブジェクトは、アプリケーション内のローカル変数である特性を持っています。ルートファイルで、を使用して参照しreq.app.localsます。
ロニーロイストン2018

回答:


65

グローバル変数を作成するには、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');
});

//...

6
注意として、一般的には、変数の受け渡しとインスタンス化について明示することをお勧めします。そうすれば、アプリ内の別の場所で参照を誤って無効にしたり、何を持っているかを確認できなくなります。
ポール

3
パウロが指摘したように、これは本当に悪い形です。下記の注入パターンをお勧めします。はい、ボイラープレートコードを増やして「きれい」に見えないようにしますが、コードがモジュール式であることを保証します...これが最後のプロジェクトでない場合は好きになるでしょう;)
srquinn 2013年

それは私見の状況に依存します。はい、グローバル変数は一般的に良い習慣ではありません(私の答えで述べたように)。最初から始めるときは、すべてを別々のモジュールに編成すると思います。ただし、既存のコードと統合する場合は、他の考慮事項がよくあります。これはたまたま1つの(簡単ですが危険な)解決策です。
ジェシーフルトン

2
誰かがJavascriptのセマンティクスを参照してこれが機能する理由を説明できますか?どのスコープappに関連付けられますか?
アリ

私はこの答えがcorrect1つとしてマークされるべきではないと思います。
コードクッカー

92

Expressオブジェクトで使用可能な「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'をグローバルに設定しますか?はい。しかし、この方法は、問題や混乱から私たちを救うのに最適です。
diproart 2014

53
後発者の場合:
app.configure

ニース、req.app.get('name')チャームのように機能します。このプロパティは、ミドルウェアを使用しているExpressアプリケーションのインスタンスへの参照を保持します。expressjs.com/pt-br/api.html#req.app
Lazaro Fernandes Lima Suleiman

57

これを行うための適切な方法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;
}

1
このメソッドを使用してhttpサービスを見つけ、単体テストで簡単にオーバーライドしました。
アレックス

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.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を使用する場合、一般に、これが問題になります。
StevenVentimiglia19年

6

最も簡単な方法は、早い段階でapp.jsでグローバル変数を宣言することです。

global.mySpecialVariable = "something"

その後、どのルートでもそれを得ることができます:

console.log(mySpecialVariable)

1
Expressでは、jshintまたはlintingを使用する場合、一般に、これが問題になります。
StevenVentimiglia19年

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.jsvar 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');

素晴らしいヒント。require( './ myroutes')(app)メソッドからこれを実行するように移動し、10分間壁に頭をぶつけて、ルートが機能しなかった理由を突き止めました。myroutes.jsのルート仕様を関数ブロックから削除することを忘れないでください。ドー!
greg 2016年

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 tofoo!」になります。これはばかげた例ですが、要点はわかります。

これについていくつかの興味深い点があります。なぜ異なる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()

0

ジョン・ゴードンの答えは、私が試した数十の半分説明された/文書化された答えの最初のものであり、実際に機能した多くのサイトからのものでした。ゴードンさん、ありがとうございました。申し訳ありませんが、あなたの答えをアップティックするポイントがありません。

node-route-file-splittingの他の初心者のために、「index」に無名関数を使用することがより頻繁に見られることを追加したいので、main.jsのJohnの例を使用して機能的に-通常見つかる同等のコードは次のとおりです。

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

0

app.allを使用しました

app.all()メソッドは、特定のパスプレフィックスまたは任意の一致の「グローバル」ロジックをマッピングするのに役立ちます。

私の場合、構成管理にコンフィを使用していますが、

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


0

これは非常に簡単なことですが、人々の答えは混乱を招き、同時に複雑です。

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、データにアクセスしているルートからは以前に設定されています。

これがあなたがこのことを機能させる方法です!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.