Node.js 设置要与 everyauth 一起使用的特定于环境的配置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8332333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:50:10  来源:igfitidea点击:

Node.js setting up environment specific configs to be used with everyauth

node.jsenvironment-variableseveryauth

提问by andy t

I am using node.js + express.js + everyauth.js. I have moved all my everyauth logic into a module file

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

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

inside this I load my oAuth config file with the key/secret combinations:

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

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

These codes are different for different environments - development / staging / production as the callbacks are to different urls.

这些代码对于不同的环境是不同的 - 开发/暂存/生产,因为回调是到不同的 url。

Qu.How do I set these in the environmental config to filter through all modules or can I pass the path directly into the module?

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

Set in env:

在环境中设置:

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

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

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

Pass in

传入

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

? hope that makes sense

? 希望这是有道理的

回答by andy t

My solution,

我的解决方案,

load the app using

使用加载应用程序

NODE_ENV=production node app.js

Then setup config.jsas a function rather than an object

然后设置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};
    }
};

Then as per Jans solution load the file and create a new instance which we could pass in a value if needed, in this case process.env.NODE_ENVis global so not needed.

然后按照 Jans 解决方案加载文件并创建一个新实例,如果需要,我们可以传入一个值,在这种情况下process.env.NODE_ENV是全局的,因此不需要。

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

Then we can access the config object properties exactly as before

然后我们可以完全像以前一样访问配置对象属性

conf.twitter.consumerKey

回答by mattwad

You could also have a JSON file with NODE_ENV as the top level. IMO, this is a better way to express configuration settings (as opposed to using a script that returns settings).

您还可以拥有一个以 NODE_ENV 作为顶级的 JSON 文件。IMO,这是表达配置设置的更好方法(与使用返回设置的脚本相反)。

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

Example for env.json:

env.json 的示例:

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

回答by Zauker

A very useful solution is use the config module.

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

after install the module:

安装模块后:

$ npm install config

You could create a default.jsonconfiguration file. (you could use JSON or JS object using extension .json5 )

您可以创建一个default.json配置文件。(您可以使用扩展名 .json5 的 JSON 或 JS 对象)

For example

例如

$ vi config/default.json

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

This default configuration could be override by environment config file or a local config file for a local develop environment:

此默认配置可以被环境配置文件或本地开发环境的本地配置文件覆盖:

production.jsoncould be:

production.json可以是:

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

development.jsoncould be:

development.json可以是:

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

In your local PC you could have a local.jsonthat override all environment, or you could have a specific local configuration as local-production.jsonor local-development.json.

在您的本地 PC 中,您可以拥有一个覆盖所有环境的local.json,或者您可以拥有一个特定的本地配置,如local-production.jsonlocal-development.json

The full list of load order.

加载顺序的完整列表

Inside your App

在您的应用程序中

In your app you only need to require config and the needed attribute.

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

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

Load the App

加载应用程序

load the app using:

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

NODE_ENV=production node app.js

or setting the correct environment with foreveror pm2

或使用永久pm2设置正确的环境

Forever:

永远:

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

PM2 (via shell):

PM2(通过外壳):

export NODE_ENV=staging
pm2 start app.js

PM2 (via .json):

PM2(通过 .json):

process.json

进程.json

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

And then

进而

$ pm2 start process.json --env production

This solution is very clean and it makes easy set different config files for Production/Staging/Development environment and for local setting too.

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

回答by kris

In brief

简单来说

This kind of a setup is simple and elegant :

这种设置简单而优雅:

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

常见的.js

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

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

app.js

应用程序.js

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

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


To run in production mode :$ NODE_ENV=production node app.js

在生产模式下运行:$ NODE_ENV=production node app.js



In detail

详细

This solution is from : http://himanshu.gilani.info/blog/2012/09/26/bootstraping-a-node-dot-js-app-for-dev-slash-prod-environment/, check it out for more detail.

这个解决方案来自:http: //himanshu.gilani.info/blog/2012/09/26/bootstraping-a-node-dot-js-app-for-dev-slash-prod-environment/,检查一下更多详情。

回答by Benxamin

An elegant way is to use .envfile to locally override production settings. No need for command line switches. No need for all those commas and brackets in a config.jsonfile. See my answer here

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

Example: on my machine the .envfile is this:

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

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

My local .envoverrides any environment variables. But on the staging or production servers (maybe they're on heroku.com) the environment variables are pre-set to stage NODE_ENV=stageor production NODE_ENV=prod.

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

回答by Jan Jongboom

The way we do this is by passing an argument in when starting the app with the environment. For instance:

我们这样做的方法是在使用环境启动应用程序时传入一个参数。例如:

node app.js -c dev

In app.js we then load dev.jsas our configuration file. You can parse these options with optparse-js.

在 app.js 中,我们然后dev.js作为我们的配置文件加载。您可以使用optparse-js解析这些选项。

Now you have some core modules that are depending on this config file. When you write them as such:

现在你有一些依赖于这个配置文件的核心模块。当你这样写时:

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

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

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

And you can call it then in app.jslike:

然后你可以app.js像这样调用它:

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

回答by Harish Anchu

How about doing this in a much more elegant way with nodejs-configmodule.

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

This module is able to set configuration environment based on your computer's name. After that when you request a configuration you will get environment specific value.

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

For example lets assume your have two development machines named pc1 and pc2 and a production machine named pc3. When ever you request configuration values in your code in pc1 or pc2 you must get "development" environment configuration and in pc3 you must get "production" environment configuration. This can be achieved like this:

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

  1. Create a base configuration file in the config directory, lets say "app.json" and add required configurations to it.
  2. Now simply create folders within the config directory that matches your environment name, in this case "development" and "production".
  3. Next, create the configuration files you wish to override and specify the options for each environment at the environment directories(Notice that you do not have to specify every option that is in the base configuration file, but only the options you wish to override. The environment configuration files will "cascade" over the base files.).
  1. 在 config 目录中创建一个基本配置文件,比如说“app.json”并向其中添加所需的配置。
  2. 现在只需在 config 目录中创建与您的环境名称匹配的文件夹,在本例中为“development”和“production”。
  3. 接下来,创建您希望覆盖的配置文件,并在环境目录中为每个环境指定选项(请注意,您不必指定基本配置文件中的每个选项,而只需指定您希望覆盖的选项。环境配置文件将在基本文件上“级联”。)。

Now create new config instance with following syntax.

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

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

   }
);

Now you can get any configuration value without worrying about the environment like this:

现在你可以得到任何配置值而不必担心这样的环境:

config.get('app').configurationKey;

回答by ajaykumar mp

set environment variable in deployment server(ex: like NODE_ENV=production). You can access your environmental variable through process.env.NODE_ENV. Find the following config file for the global settings

在部署服务器中设置环境变量(例如:像 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 : '[email protected]',
    },
    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 contains common config for all environments.

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

then import in other modules like

然后导入其他模块,如

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

Happy Coding...

快乐编码...

回答by Faraj Farook

This answer is not something new. It's similar to what @andy_t has mentioned. But I use the below pattern for two reasons.

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

  1. Clean implementation with No external npm dependencies

  2. Merge the default config settings with the environment based settings.

  1. 没有外部 npm 依赖的干净实现

  2. 将默认配置设置与基于环境的设置合并。

Javascript implementation

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

I usually use typescript in my node project. Below is my actual implementation copy-pasted.

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

Typescript implementation

打字稿实现

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)