Node.jsがeveryauthで使用される環境固有の構成をセットアップする


117

node.js + express.js + everyauth.jsを使用しています。すべてのeveryauthロジックをモジュールファイルに移動しました

var login = require('./lib/everyauthLogin');

この中に、キー/シークレットの組み合わせを含むoAuth構成ファイルをロードします。

var conf = require('./conf');
.....
twitter: {
    consumerKey: 'ABC', 
    consumerSecret: '123'
}

これらのコードは、コールバックのURLが異なるため、開発/ステージング/本番環境ごとに異なります。

Qu。これらを環境設定でどのように設定してすべてのモジュールをフィルタリングするか、またはパスをモジュールに直接渡すことができますか?

envで設定:

app.configure('development', function(){
  app.set('configPath', './confLocal');
});

app.configure('production', function(){
  app.set('configPath', './confProduction');
});

var conf = require(app.get('configPath'));

渡す

app.configure('production', function(){
  var login = require('./lib/everyauthLogin', {configPath: './confProduction'});
});

?それが理にかなっていると思います


オブジェクトではなくmodule = functionを使用することで、以下のいくつかのアイデアを使用しているソリューションを見つけました。process.env.NODE_ENVを評価して、環境に適したオブジェクトを返すことができます。少し面倒ですが動作します。
アンディt

恩赦恥知らずな自己宣伝が、私は別のファイルとコマンドラインスイッチを介してこれを行いますNode.jsのためのモジュールを書いた:ノードのconfigure
Randolpho

回答:


192

私の解決策、

を使用してアプリをロードする

NODE_ENV=production node app.js

次にconfig.js、オブジェクトではなく関数としてセットアップします。

module.exports = function(){
    switch(process.env.NODE_ENV){
        case 'development':
            return {dev setting};

        case 'production':
            return {prod settings};

        default:
            return {error or other settings};
    }
};

次に、Jansソリューションに従ってファイルをロードし、必要に応じて値を渡すことができる新しいインスタンスを作成しprocess.env.NODE_ENVます。この場合、グローバルなので必要ありません。

var Config = require('./conf'),
    conf = new Config();

次に、以前とまったく同じように構成オブジェクトのプロパティにアクセスできます

conf.twitter.consumerKey

2
ここでnewを使用するのはなぜですか?
bluehallu

5
@bluehalluの2番目です。であるnew必要?
Sung Cho、

2
Windowsでこれに相当するものは、SET NODE_ENV = development
mujaffars '19年

3
代わりにnew。私はconfig.js....Config = function(){...}; module.exports = Config()
Atu

50台のWebサーバーがあり、手動でスクリプトを開始するために各サーバーにアクセスすることが困難な場合
Rajesh

60

また、NODE_ENVを最上位レベルとするJSONファイルを作成することもできます。IMO、これは(設定を返すスクリプトを使用するのとは対照的に)構成設定を表現するためのより良い方法です。

var config = require('./env.json')[process.env.NODE_ENV || 'development'];

env.jsonの例:

{
    "development": {
        "MONGO_URI": "mongodb://localhost/test",
        "MONGO_OPTIONS": { "db": { "safe": true } }
    },
    "production": {
        "MONGO_URI": "mongodb://localhost/production",
        "MONGO_OPTIONS": { "db": { "safe": true } }
    }
}

こんにちは、これが構成設定を表現するためのより良い方法である理由を説明してください(設定を返すスクリプトを使用するのではなく)。?
Venkat Kotra 2014年

14
それほど大きな違いはないと思います。精神的には、JSONを見ると「静的データ」だと思いますが、JSファイルを見ると、その中になんらかのロジックがあると思います。また、.jsonタイプを使用するもう1つの利点は、他の言語が同じファイルをインポートできることです。
mattwad 2014年

1
@VenkatKotraの設定は一般に静的と見なされるため、json、yaml、iniなどで宣言的に最もよく表現されます。その状態を生成するスクリプトで強制的に実行すると、何かが動的に発生していることを示唆しているため、悪いことになります。
最大

9
このメソッドは、ソース管理で資格情報を公開することに注意してください。
Pier-Luc Gendreau 2016年

ステージングおよびプロダクション用の差分URLを作成できますか?
Alex

34

非常に便利なソリューションは、configモジュールを使用することです

モジュールをインストールした後:

$ npm install config

default.json構成ファイルを作成できます。(拡張子.json5を使用して、JSONまたはJSオブジェクトを使用できます)

例えば

$ vi config/default.json

{
  "name": "My App Name",
  "configPath": "/my/default/path",
  "port": 3000
}

このデフォルト構成は、環境構成ファイルまたはローカル開発環境のローカル構成ファイルでオーバーライドできます。

production.jsonは次のようになります。

{
  "configPath": "/my/production/path",
  "port": 8080
}

development.jsonは次のようになります。

{
  "configPath": "/my/development/path",
  "port": 8081
}

ローカルPC では、すべての環境をオーバーライドするlocal.jsonを使用するか、特定のローカル構成をlocal-production.jsonまたはlocal-development.jsonとして使用できます。

ロード順序の完全なリスト

アプリ内

アプリでは、configと必要な属性のみが必要です。

var conf = require('config'); // it loads the right file
var login = require('./lib/everyauthLogin', {configPath: conf.get('configPath'));

アプリをロードする

以下を使用してアプリをロードします。

NODE_ENV=production node app.js

または、foreverまたはpm2で正しい環境を設定する

永遠に:

NODE_ENV=production forever [flags] start app.js [app_flags]

PM2(シェル経由):

export NODE_ENV=staging
pm2 start app.js

PM2(.json経由):

process.json

{
   "apps" : [{
    "name": "My App",
    "script": "worker.js",
    "env": {
      "NODE_ENV": "development",
    },
    "env_production" : {
       "NODE_ENV": "production"
    }
  }]
}

その後

$ pm2 start process.json --env production

このソリューションは非常にクリーンであり、本番/ステージング/開発環境およびローカル設定用にさまざまな構成ファイルを簡単に設定できます。


npm install config --save、それは良くないですか?
stackdave 2017

14

簡単に

この種の設定はシンプルでエレガントです。

env.json

{
  "development": {
      "facebook_app_id": "facebook_dummy_dev_app_id",
      "facebook_app_secret": "facebook_dummy_dev_app_secret",
  }, 
  "production": {
      "facebook_app_id": "facebook_dummy_prod_app_id",
      "facebook_app_secret": "facebook_dummy_prod_app_secret",
  }
}

common.js

var env = require('env.json');

exports.config = function() {
  var node_env = process.env.NODE_ENV || 'development';
  return env[node_env];
};

app.js

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

var facebook_app_id = config.facebook_app_id;
// do something with facebook_app_id

本番モードで実行するには: $ NODE_ENV=production node app.js


詳細に

この解決策は次のとおりです:http : //himanshu.gilani.info/blog/2012/09/26/bootstraping-a-node-dot-js-app-for-dev-slash-prod-environment/、確認してくださいもっと詳しく。


5

これを行う方法は、環境でアプリを起動するときに引数を渡すことです。例えば:

node app.js -c dev

次にapp.jsで、dev.js構成ファイルとしてロードします。これらのオプションはoptparse-jsで解析できます。

これで、この構成ファイルに依存するいくつかのコアモジュールができました。そのようにそれらを書くとき:

var Workspace = module.exports = function(config) {
    if (config) {
         // do something;
    }
}

(function () {
    this.methodOnWorkspace = function () {

    };
}).call(Workspace.prototype);

そして、あなたはそれを次のapp.jsように呼び出すことができます:

var Workspace = require("workspace");
this.workspace = new Workspace(config);

すべてのロジックをapp.js app.configure('developmentコード内に保持したいのですが、それでこのソリューションを使用できるかどうかを確認します
andy t

この回答の更新:アーキテクトは、これをより良い方法で解決する依存関係管理フレームワークです。
Jan Jongboom 2013年

5

エレガントな方法は、.envファイルを使用して本番設定をローカルで上書きすることです。コマンドラインスイッチは必要ありません。config.jsonファイルにこれらのすべてのコンマとブラケットを含める必要はありません。ここで私の答えを見てください

例:私のマシンの.envファイルは次のとおりです:

NODE_ENV=dev
TWITTER_AUTH_TOKEN=something-needed-for-api-calls

ローカルは.envすべての環境変数を上書きします。しかし、ステージングや本番サーバー上で変数をステージに予め設定された環境(多分彼らはheroku.comにしている)、NODE_ENV=stageまたは生産NODE_ENV=prod


4

展開サーバーに環境変数を設定します(例:NODE_ENV = productionのように)。process.env.NODE_ENVを介して環境変数にアクセスできます。グローバル設定の次の構成ファイルを見つけます

const env = process.env.NODE_ENV || "development"

const configs = {
    base: {
        env,
        host: '0.0.0.0',
        port: 3000,
        dbPort: 3306,
        secret: "secretKey for sessions",
        dialect: 'mysql',
        issuer : 'Mysoft corp',
        subject : 'some@user.com',
    },
    development: {
        port: 3000,
        dbUser: 'root',
        dbPassword: 'root',

    },
    smoke: {
        port: 3000,
        dbUser: 'root',
    },
    integration: {
        port: 3000,
        dbUser: 'root',
    },
    production: {
        port: 3000,
        dbUser: 'root',
    }
};

const config = Object.assign(configs.base, configs[env]);

module.exports= config;

ベースには、すべての環境に共通の構成が含まれています。

次に、他のモジュールにインポートします

const config =  require('path/to/config.js')
console.log(config.port)

ハッピーコーディング...


3

nodejs-configモジュールでこれをはるかにエレガントな方法で行うのはどうですか?

このモジュールは、コンピューターの名前に基づいて構成環境を設定できます。その後、構成を要求すると、環境固有の値が取得されます。

たとえば、pc1とpc2という名前の2つの開発マシンとpc3という名前の本番マシンがあるとします。pc1またはpc2のコードで構成値を要求するときは常に、「開発」環境構成を取得する必要があり、pc3では「本番」環境構成を取得する必要があります。これは次のようにして実現できます。

  1. configディレクトリーに基本構成ファイルを作成し、「app.json」と言って、それに必要な構成を追加します。
  2. 次に、環境名に一致するconfigディレクトリ内にフォルダーを作成します。この場合は、「開発」と「本番」です。
  3. 次に、オーバーライドする構成ファイルを作成し、環境ディレクトリで各環境のオプションを指定します(基本構成ファイルにあるすべてのオプションを指定する必要はなく、オーバーライドするオプションのみを指定する必要があることに注意してください。環境構成ファイルは、基本ファイルの上に「カスケード」します。)

次の構文で新しい構成インスタンスを作成します。

var config = require('nodejs-config')(
   __dirname,  // an absolute path to your applications 'config' directory
   {
      development: ["pc1", "pc2"],
      production: ["pc3"],

   }
);

これで、次のような環境を気にすることなく、任意の構成値を取得できます。

config.get('app').configurationKey;

0

この答えは新しいものではありません。これは、@ andy_tが言及したものに似ています。しかし、以下のパターンを使用する理由は2つあります。

  1. 外部npm依存関係のないクリーンな実装

  2. デフォルトの構成設定を環境ベースの設定とマージします。

JavaScriptの実装

const settings = {
    _default: {
       timeout: 100
       baseUrl: "http://some.api/",
    },
    production: {
       baseUrl: "http://some.prod.api/",
    },
}
// If you are not using ECMAScript 2018 Standard
// https://stackoverflow.com/a/171256/1251350
module.exports = { ...settings._default, ...settings[process.env.NODE_ENV] }

私は通常、ノードプロジェクトでtypescriptを使用します。以下はコピー貼り付けされた私の実際の実装です。

Typescriptの実装

const settings: { default: ISettings, production: any } = {
    _default: {
        timeout: 100,
        baseUrl: "",
    },
    production: {
        baseUrl: "",
    },
}

export interface ISettings {
    baseUrl: string
}

export const config = ({ ...settings._default, ...settings[process.env.NODE_ENV] } as ISettings)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.