web-dev-qa-db-ja.com

Node.jsのファイル間で変数を共有しますか?

以下に2つのファイルを示します。

// main.js
require('./modules');
console.log(name); // prints "foobar"

// module.js
name = "foobar";

「var」がない場合は動作します。しかし、私が持っているとき:

// module.js
var name = "foobar";

名前はmain.jsで未定義になります。

グローバル変数が悪いので、参照の前に「var」を使用した方がよいと聞きました。しかし、これはグローバル変数が良い場合ですか?

112

グローバル変数はalmost決して良いことではありません(おそらく1つまたは2つの例外があります...)。この場合、「名前」変数をエクスポートしたいだけのように見えます。例えば。、

// module.js
var name = "foobar";
// export it
exports.name = name;

次に、main.jsで...

//main.js
// get a reference to your required module
var myModule = require('./module');

// name is a member of myModule due to the export above
var name = myModule.name;
166
jmar777

グローバルなvarが最良のオプションであるシナリオを見つけることはできません。もちろん、あなたはそれを持つことができますが、これらの例を見て、同じことを達成するためのより良い方法を見つけるかもしれません。

シナリオ1:設定ファイルに内容を入れる

アプリケーション全体で同じ値が必要ですが、環境(実稼働環境、開発環境、テスト環境)、メーラータイプなどに応じて変化します。

// File: config/environments/production.json
{
    "mailerType": "SMTP",
    "mailerConfig": {
      "service": "Gmail",
      ....
}

そして

// File: config/environments/test.json
{
    "mailerType": "Stub",
    "mailerConfig": {
      "error": false
    }
}

(devにも同様の設定を行います)

ロードする構成を決定するには、メイン構成ファイルを作成します(これはアプリケーション全体で使用されます)

// File: config/config.js
var _ = require('underscore');

module.exports = _.extend(
    require(__dirname + '/../config/environments/' + process.env.NODE_ENV + '.json') || {});

そしてこれでデータを取得できますこのように:

// File: server.js
...
var config = require('./config/config');
...
mailer.setTransport(nodemailer.createTransport(config.mailerType, config.mailerConfig));

シナリオ2:定数ファイルを使用する

// File: constants.js
module.exports = {
  appName: 'My neat app',
  currentAPIVersion: 3
};

そして、このように使用します

// File: config/routes.js

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

module.exports = function(app, passport, auth) {
  var apiroot = '/api/v' + constants.currentAPIVersion;
...
  app.post(apiroot + '/users', users.create);
...

シナリオ3:ヘルパー関数を使用してデータを取得/設定する

これの大ファンではありませんが、少なくとも「名前」の使用を追跡し(OPの例を引用)、検証を行うことができます。

// File: helpers/nameHelper.js

var _name = 'I shall not be null'

exports.getName = function() {
  return _name;
};

exports.setName = function(name) {
  //validate the name...
  _name = name;
};

そしてそれを使用する

// File: controllers/users.js

var nameHelper = require('../helpers/nameHelper.js');

exports.create = function(req, res, next) {
  var user = new User();
  user.name = req.body.name || nameHelper.getName();
  ...

グローバルvarを持つ以外に解決策がない場合のユースケースがありますが、node.jsを使用し始めている場合は、通常、これらのシナリオのいずれかを使用してアプリ内のデータを共有できます(私は少し前に)そこにあるデータの扱い方を整理してみてください。データがすぐに乱雑になる可能性があるからです。

26
Felipe Pereira

複数の変数を共有する必要がある場合は、以下の形式を使用します

//module.js
   let name='foobar';
   let city='xyz';
   let company='companyName';

   module.exports={
    name,
    city,
    company
  }

使用法

  // main.js
    require('./modules');
    console.log(name); // print 'foobar'
12

更新

1つのオブジェクトとして共有する変数を保存します。次に、ロードされたモジュールに渡し、オブジェクト参照を介して変数にアクセスできるようにします。

// myModule.js
var shared = null;

function init(obj){
    shared = obj;
}

module.exports = {
    init:init
}

// main.js
var myModule = require('./myModule.js');
var shares = {value:123};
myModule.init(shares);

旧回答

モジュール間で変数を共有するには、関数を使用してメインとモジュール間で変数の値を取得できます。

//myModule.js
var mainFunction = null; //You can also put function reference in a Object or Array

function functionProxy(func){
    mainFunction = func; //Save the function reference
}

// --- Usage ---
// setTimeout(function(){
//   console.log(mainFunction('myString'));
//   console.log(mainFunction('myNumber'));
// }, 3000);

module.exports = {
    functionProxy:functionProxy
}

//main.js
var myModule = require('./myModule.js');
var myString = "heyy";
var myNumber = 12345;

function internalVariable(select){
    if(select=='myString') return myString;
    else if(select=='myNumber') return myNumber;
    else return null;
}

myModule.functionProxy(internalVariable);


// --- If you like to be able to set the variable too ---
// function internalVariable(select, set){
//    if(select=='myString'){
//        if(set!=undefined) myString = set;
//        else return myString;
//    }
//    else if(select=='myNumber'){
//      if(set!=undefined) myNumber = set;
//      else return myNumber;
//    }
//    else return null;
// }

値を変更しても、main.jsからいつでも値を取得できます。

5
StefansArya

varキーワードを使用して、または使用せずに宣言された変数がグローバルオブジェクトにアタッチされました。これは、varキーワードなしで変数を宣言することにより、Nodeにグローバル変数を作成するための基礎です。 varキーワードで宣言された変数はモジュールに対してローカルのままです。

詳細については、この記事を参照してください- https://www.hacksparrow.com/global-variables-in-node-js.html

1
criz

別の意見で、コードをglobalに公開する場合は、npm変数が最良の選択であると思います。すべてのパッケージが同じリリースのコードを使用していることを確認できないからです。 。したがって、singletonオブジェクトのエクスポートにファイルを使用すると、ここで問題が発生します。

globalrequire.main、またはファイル間で共有されるその他のオブジェクトを選択できます。

より良い解決策があれば教えてください。

1
LCB