126

我正在使用 node.js + express.js +everyauth.js。我已将所有的everyauth 逻辑移动到一个模块文件中

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

在这里面,我用密钥/秘密组合加载了我的 oAuth 配置文件:

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

这些代码对于不同的环境是不同的——开发/登台/生产,因为回调是针对不同的 url。

问题:如何在环境配置中设置这些以过滤所有模块,或者我可以将路径直接传递到模块中吗?

在环境中设置:

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

? 希望这是有道理的

4

9 回答 9

202

我的解决方案,

使用加载应用程序

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
于 2011-12-02T11:14:08.057 回答
62

您还可以拥有一个以 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 } }
    }
}
于 2014-03-20T05:17:43.917 回答
38

一个非常有用的解决方案是使用配置模块

安装模块后:

$ 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.jsonlocal-development.json

加载顺序的完整列表

在您的应用程序内部

在您的应用程序中,您只需要 require config 和 required 属性。

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

加载应用程序

使用以下方式加载应用程序:

NODE_ENV=production node app.js

或使用foreverpm2设置正确的环境

永远:

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

PM2(通过外壳):

export NODE_ENV=staging
pm2 start app.js

PM2(通过 .json):

进程.json

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

进而

$ pm2 start process.json --env production

这个解决方案非常干净,它可以轻松地为生产/暂存/开发环境和本地设置设置不同的配置文件。

于 2016-04-18T13:41:57.113 回答
20

简单来说

这种设置简单而优雅:

环境.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];
};

应用程序.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/ ,请查看更多详情。

于 2016-08-20T23:18:46.243 回答
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);
于 2011-12-01T09:40:23.153 回答
5

一种优雅的方法是使用.env文件在本地覆盖生产设置。不需要命令行开关。文件中不需要所有这些逗号和括号config.json在这里查看我的答案

示例:在我的机器上,.env文件是这样的:

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

我的本地.env覆盖任何环境变量。但是在登台或生产服务器上(也许它们在 heroku.com 上),环境变量已预先设置为 stageNODE_ENV=stage或 production NODE_ENV=prod

于 2015-03-03T00:12:13.780 回答
5

在部署服务器中设置环境变量(例如:像 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;

“base”包含所有环境的通用配置。

然后导入其他模块,如:

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

快乐的编码...

于 2019-10-30T09:35:23.483 回答
3

如何使用nodejs-config模块以更优雅的方式执行此操作。

该模块能够根据您的计算机名称设置配置环境。之后,当您请求配置时,您将获得特定于环境的值。

例如,假设您有两台名为 pc1 和 pc2 的开发机器和一台名为 pc3 的生产机器。当您在 pc1 或 pc2 的代码中请求配置值时,您必须获得“开发”环境配置,而在 pc3 中,您必须获得“生产”环境配置。这可以这样实现:

  1. 在 config 目录中创建一个基本配置文件,让我们说“app.json”并向其中添加所需的配置。
  2. 现在只需在配置目录中创建与您的环境名称匹配的文件夹,在本例中为“开发”和“生产”。
  3. 接下来,创建您希望覆盖的配置文件并在环境目录中为每个环境指定选项(请注意,您不必指定基本配置文件中的每个选项,而只需指定您希望覆盖的选项。环境配置文件将“级联”在基础文件之上。)。

现在使用以下语法创建新的配置实例。

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

   }
);

现在您可以获取任何配置值,而无需担心这样的环境:

config.get('app').configurationKey;
于 2014-10-15T18:04:17.757 回答
0

这个答案并不是什么新鲜事。这与@andy_t 提到的类似。但我使用以下模式有两个原因。

  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] }

我通常在我的节点项目中使用打字稿。下面是我实际复制粘贴的实现。

打字稿实现

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)
于 2019-10-30T09:17:33.387 回答