如何存储 Node.js 部署设置/配置文件?

发布于 2024-11-05 02:56:15 字数 444 浏览 4 评论 0 原文

我一直在开发一些 Node 应用程序,并且一直在寻找一种存储部署相关设置的良好模式。在 Django 世界(我来自的地方)中,常见的做法是拥有一个包含标准设置(时区等)的 settings.py 文件,然后是一个 local_settings.py< /code> 用于部署特定设置,即。与什么数据库通信,什么内存缓存套接字,管理员的电子邮件地址等等。

我一直在为 Node.js 寻找类似的模式。只要有一个配置文件就很好了,因此它不必与 app.js 中的其他所有内容混在一起,但我发现有一种方法可以在文件中包含特定于服务器的配置,这一点很重要这不在源代码管理中。同一个应用程序很可能部署在具有截然不同设置的不同服务器上,并且必须处理合并冲突以及所有这些都不是我的乐趣所在。

那么是否有某种框架/工具可以实现这一点,或者每个人都自己一起开发一些东西?

I have been working on a few Node apps, and I've been looking for a good pattern of storing deployment-related settings. In the Django world (where I come from), the common practise would be to have a settings.py file containing the standard settings (timezone, etc), and then a local_settings.py for deployment specific settings, ie. what database to talk to, what memcache socket, e-mail address for the admins and so on.

I have been looking for similar patterns for Node. Just a config file would be nice, so it does not have to be jammed in with everything else in app.js, but I find it important to have a way to have server-specific configuration in a file that is not in source control. The same app could well be deployed across different servers with wildly different settings, and having to deal with merge conflicts and all that is not my idea of fun.

So is there some kind of framework/tool for this, or does everyone just hack something together themselves?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

这个俗人 2024-11-12 02:56:15

我使用 package.json 作为我的包,使用 config.js 作为我的配置,它看起来像:

var config = {};

config.twitter = {};
config.redis = {};
config.web = {};

config.default_stuff =  ['red','green','blue','apple','yellow','orange','politics'];
config.twitter.user_name = process.env.TWITTER_USER || 'username';
config.twitter.password=  process.env.TWITTER_PASSWORD || 'password';
config.redis.uri = process.env.DUOSTACK_DB_REDIS;
config.redis.host = 'hostname';
config.redis.port = 6379;
config.web.port = process.env.WEB_PORT || 9980;

module.exports = config;

我从我的项目加载配置:

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

然后我可以访问我的来自 config.db_hostconfig.db_port 等的内容...这使我可以使用硬编码参数,或者如果我不想存储,则可以使用存储在环境变量中的参数源代码管理中的密码。

我还生成 package.json 并插入依赖项部分:

"dependencies": {
  "cradle": "0.5.5",
  "jade": "0.10.4",
  "redis": "0.5.11",
  "socket.io": "0.6.16",
  "twitter-node": "0.0.2",
  "express": "2.2.0"
}

当我将项目克隆到本地计算机时,我运行 npm install 来安装软件包。有关该内容的更多信息此处

该项目存储在 GitHub 中,并为我的生产服务器添加了遥控器。

I use a package.json for my packages and a config.js for my configuration, which looks like:

var config = {};

config.twitter = {};
config.redis = {};
config.web = {};

config.default_stuff =  ['red','green','blue','apple','yellow','orange','politics'];
config.twitter.user_name = process.env.TWITTER_USER || 'username';
config.twitter.password=  process.env.TWITTER_PASSWORD || 'password';
config.redis.uri = process.env.DUOSTACK_DB_REDIS;
config.redis.host = 'hostname';
config.redis.port = 6379;
config.web.port = process.env.WEB_PORT || 9980;

module.exports = config;

I load the config from my project:

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

and then I can access my things from config.db_host, config.db_port, etc... This lets me either use hardcoded parameters, or parameters stored in environmental variables if I don't want to store passwords in source control.

I also generate a package.json and insert a dependencies section:

"dependencies": {
  "cradle": "0.5.5",
  "jade": "0.10.4",
  "redis": "0.5.11",
  "socket.io": "0.6.16",
  "twitter-node": "0.0.2",
  "express": "2.2.0"
}

When I clone the project to my local machine, I run npm install to install the packages. More info on that here.

The project is stored in GitHub, with remotes added for my production server.

瀞厅☆埖开 2024-11-12 02:56:15

从 Node v0.5.x 开始,您可以要求 JSON 文件(引用此答案

config.json:

{
    "username" : "root",
    "password" : "foot"
}

app.js:

var config = require('./config.json');
log_in(config.username, config.password);

You can require JSON files as of Node v0.5.x (referencing this answer)

config.json:

{
    "username" : "root",
    "password" : "foot"
}

app.js:

var config = require('./config.json');
log_in(config.username, config.password);
三生池水覆流年 2024-11-12 02:56:15

很久以后,我发现了一个非常好的用于管理配置的 Node.js 模块:nconf

一个简单的例子:

var nconf = require('nconf');

// First consider commandline arguments and environment variables, respectively.
nconf.argv().env();

// Then load configuration from a designated file.
nconf.file({ file: 'config.json' });

// Provide default values for settings not provided above.
nconf.defaults({
    'http': {
        'port': 1337
    }
});

// Once this is in place, you can just use nconf.get to get your settings.
// So this would configure `myApp` to listen on port 1337 if the port
// has not been overridden by any of the three configuration inputs
// mentioned above.
myApp.listen(nconf.get('http:port'));

它还支持在 Redis 中存储设置,编写配置文件,并且具有相当可靠的 API,并且还得到以下之一的支持更多受人尊敬的 Node.js 商店 Nodejitsu,作为 Flatiron 的一部分 框架倡议,所以它应该是相当面向未来的。

查看 Github 上的 nconf

Much later, I found a pretty good Node.js module for managing configuration: nconf.

A simple example:

var nconf = require('nconf');

// First consider commandline arguments and environment variables, respectively.
nconf.argv().env();

// Then load configuration from a designated file.
nconf.file({ file: 'config.json' });

// Provide default values for settings not provided above.
nconf.defaults({
    'http': {
        'port': 1337
    }
});

// Once this is in place, you can just use nconf.get to get your settings.
// So this would configure `myApp` to listen on port 1337 if the port
// has not been overridden by any of the three configuration inputs
// mentioned above.
myApp.listen(nconf.get('http:port'));

It also supports storing settings in Redis, writing configuration files, and has a fairly solid API, and is also backed by one of the more well-respected Node.js shops, Nodejitsu, as part of the Flatiron framework initiative, so it should be fairly future-proof.

Check out nconf at Github.

等风来 2024-11-12 02:56:15

我的解决方案相当简单:

在 ./config/index.js 中加载环境配置 在 ./config/config.global.js

var env = process.env.NODE_ENV || 'development'
  , cfg = require('./config.'+env);

module.exports = cfg;

中定义一些默认值

var config = module.exports = {};

config.env = 'development';
config.hostname = 'dev.example.com';

//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';

覆盖 ./config/config.test.js 中的默认值

var config = require('./config.global');

config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';

module.exports = config;

在 ./models 中使用它/user.js:

var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);

在测试环境中运行您的应用程序:

NODE_ENV=test node ./app.js

My solution is fairly simple:

Load the environment config in ./config/index.js

var env = process.env.NODE_ENV || 'development'
  , cfg = require('./config.'+env);

module.exports = cfg;

Define some defaults in ./config/config.global.js

var config = module.exports = {};

config.env = 'development';
config.hostname = 'dev.example.com';

//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';

Override the defaults in ./config/config.test.js

var config = require('./config.global');

config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';

module.exports = config;

Using it in ./models/user.js:

var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);

Running your app in test environment:

NODE_ENV=test node ./app.js
对你而言 2024-11-12 02:56:15

您还可以查看dotenv,它遵循12个原则-因素应用程序

我曾经使用node-config,但出于这个原因创建了dotenv。它完全受到 ruby​​ 的 dotenv 库的启发。

使用非常简单:

var dotenv = require('dotenv');
dotenv.load();

然后您只需创建一个 .env 文件并将设置放入其中,如下所示:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

这就是 Nodejs 的 dotenv

You might also look to dotenv which follows the tenets of a twelve-factor app.

I used to use node-config, but created dotenv for that reason. It was completely inspired by ruby's dotenv library.

Usage is quite easy:

var dotenv = require('dotenv');
dotenv.load();

Then you just create a .env file and put your settings in there like so:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

That's dotenv for nodejs.

不再见 2024-11-12 02:56:15

你们使用 npm 来启动脚本(env 等)吗?

如果您使用 .env 文件,您可以将它们包含在 package.json
并使用 npm 来获取/启动它们。

示例:

{
  "name": "server",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node test.js",
    "start-dev": "source dev.env; node test.js",
    "start-prod": "source prod.env; node test.js"
  },
  "dependencies": {
    "mysql": "*"
  }
}

然后运行 ​​npm 脚本:

$ npm start-dev

此处描述 https://gist.github.com/ericelliott/4152984
全部归功于埃里克·埃利奥特

Are you guys using npm to start your scripts (env etc) ?

If you use .env files you can include them in your package.json
and use npm to source/start them.

Example:

{
  "name": "server",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node test.js",
    "start-dev": "source dev.env; node test.js",
    "start-prod": "source prod.env; node test.js"
  },
  "dependencies": {
    "mysql": "*"
  }
}

then run the npm scripts:

$ npm start-dev

Its described here https://gist.github.com/ericelliott/4152984
All credit to Eric Elliot

誰ツ都不明白 2024-11-12 02:56:15

您还可以查看 node-config ,它根据 $HOST$NODE_ENV 变量(有点像 RoR):文档

这对于不同的部署设置(开发测试生产)非常有用。

You might also look to node-config which loads configuration file depending on $HOST and $NODE_ENV variable (a little bit like RoR) : documentation.

This can be quite useful for different deployment settings (development, test or production).

╰ゝ天使的微笑 2024-11-12 02:56:15

只需使用 exports 执行一个简单的 settings.js

exports.my_password = 'value'

然后,在您的脚本中执行 require

var settings = require('./settings.js');

现在您的所有设置都将通过 <代码>设置变量:

settings.my_password // 'value'

Just do a simple settings.js with exports:

exports.my_password = 'value'

Then, in your script, do a require:

var settings = require('./settings.js');

All your settings now will be availabe via settings variable:

settings.my_password // 'value'
英雄似剑 2024-11-12 02:56:15

Convict 是另一个添加验证模式的选项。与 nconf 一样,它支持从环境变量、参数、文件和 json 对象的任意组合加载设置。

自述文件中的示例:

var convict = require('convict');
var conf = convict({
  env: {
    doc: "The applicaton environment.",
    format: ["production", "development", "test"],
    default: "development",
    env: "NODE_ENV"
  },
  ip: {
    doc: "The IP address to bind.",
    format: "ipaddress",
    default: "127.0.0.1",
    env: "IP_ADDRESS",
  },
  port: {
    doc: "The port to bind.",
    format: "port",
    default: 0,
    env: "PORT"
  }
});

入门文章:
使用 node-convict 驯服配置

Convict is another option that adds a schema for validation. Like nconf, it supports loading settings from any combination of environment variables, arguments, files, and json objects.

Example from the README:

var convict = require('convict');
var conf = convict({
  env: {
    doc: "The applicaton environment.",
    format: ["production", "development", "test"],
    default: "development",
    env: "NODE_ENV"
  },
  ip: {
    doc: "The IP address to bind.",
    format: "ipaddress",
    default: "127.0.0.1",
    env: "IP_ADDRESS",
  },
  port: {
    doc: "The port to bind.",
    format: "port",
    default: 0,
    env: "PORT"
  }
});

Getting started article:
Taming Configurations with node-convict

勿忘初心 2024-11-12 02:56:15

我要在这里表示敬意,因为这些答案都没有解决几乎任何系统所需的所有关键组件。注意事项:

  • 公共配置(前端可以看到)与私有配置(莫格拉比(mograbi)做对了)。并确保它们分开保存。
  • 密钥等秘密
  • 默认值与特定于环境的覆盖
  • 前端捆绑包

以下是我的配置方式:

  • config.default.private.js - 在版本控制中,这些是默认配置选项,只能由后端看到。
  • config.default.public.js - 在版本控制中,这些是后端前端可以看到的默认配置选项
  • config.dev.private.js< /code> - 如果您需要不同的开发私有默认值。
  • config.dev.public.js - 如果您需要不同的开发公共默认值。
  • 的环境特定选项
  • config.private.js - 不在版本控制中,这些是覆盖 config.default.private.js config.public.js > - 不在版本控制中,这些是覆盖 config.default.public.js 的环境特定选项
  • keys/ - 每个文件存储某种不同秘密的文件夹。这也不受版本控制(密钥永远不应该受版本控制)。

我使用普通的 javascript 文件进行配置,因此我拥有 javascript 语言的全部功能(包括注释和执行诸如在特定于环境的文件中加载默认配置文件之类的操作的能力,以便可以覆盖它们)。如果你想使用环境变量,你可以将它们加载到这些配置文件中(尽管我建议不要使用环境变量,因为我不建议使用 json 文件的原因相同 - 你没有编程语言来构建的能力)你的配置)。

每个密钥位于单独的文件中的原因是供安装程序使用。这允许您拥有一个在计算机上创建密钥并将其存储在密钥文件夹中的安装程序。如果没有这个,当您加载无法访问密钥的配置文件时,安装程​​序可能会失败。通过这种方式,您可以遍历目录并加载该文件夹中的任何关键文件,而不必担心任何给定版本的代码中存在哪些文件以及不存在哪些文件。

由于您可能在私有配置中加载了密钥,因此您肯定不想在任何前端代码中加载您的私有配置。虽然将前端代码库与后端完全分离可能更理想,但很多时候 PITA 是一个足够大的障碍来阻止人们这样做,因此私有配置与公共配置。但是我做了两件事来防止在前端加载私有配置:

  1. 我有一个单元测试,确保我的前端包不包含我在私有配置中拥有的密钥之一。
  2. 我的前端代码与后端代码位于不同的文件夹中,并且我有两个名为“config.js”的不同文件 - 每一端一个。对于后端,config.js 加载私有配置,对于前端,它加载公共配置。然后你总是只需要 require('config') 并且不用担心它来自哪里。

最后一件事:您的配置应该通过一个与任何其他前端代码完全独立的文件加载到浏览器中。如果您捆绑前端代码,则公共配置应构建为完全独立的捆绑包。否则,您的配置不再是真正的配置 - 它只是代码的一部分。配置需要能够在不同的机器上有所不同。

I'm going to throw my hat into the ring here because none of these answers address all the critical components that pretty much any system needs. Considerations:

  • Public configuration (that can be seen by the frontend) vs private configuration (guy mograbi got this one right). And ensuring these are kept separate.
  • Secrets like keys
  • Defaults vs environment-specific overrides
  • Frontend bundles

Here's how I do my configuration:

  • config.default.private.js - In version control, these are default configuration options that can only be seen by your backend.
  • config.default.public.js - In version control, these are default configuration options that can be seen by backend and frontend
  • config.dev.private.js - If you need different private defaults for dev.
  • config.dev.public.js - If you need different public defaults for dev.
  • config.private.js - Not in version control, these are environment specific options that override config.default.private.js
  • config.public.js - Not in version control, these are environment specific options that override config.default.public.js
  • keys/ - A folder where each file stores a different secret of some kind. This is also not under version control (keys should never be under version control).

I use plain-old javascript files for configuration so I have the full power of the javascript langauge (including comments and the ability to do things like load the default config file in the environment-specific file so they can then be overridden). If you want to use environment variables, you can load them inside those config files (tho I recommend against using env vars for the same reason I don't recommend using json files - you don't have the power of a programming language to construct your config).

The reason each key is in a separate file is for installer use. This allows you to have an installer that creates keys on-machine and stores them in the keys folder. Without this, your installer might fail when you load your configuration file that can't access your keys. This way you can traverse the directory and load any key files that are in that folder without having to worry about what exists and what doesn't in any given version of your code.

Since you probably have keys loaded in your private configuration, you definitely don't want to load your private config in any frontend code. While its probably strictly more ideal to completely separate your frontend codebase from your backend, a lot of times that PITA is a big enough barrier to prevent people from doing it, thus private vs public config. But there's two things I do to prevent private config being loaded in the frontend:

  1. I have a unit test that ensures my frontend bundles don't contain one of the secret keys I have in the private config.
  2. I have my frontend code in a different folder than my backend code, and I have two different files named "config.js" - one for each end. For backend, config.js loads the private config, for frontend, it loads the public config. Then you always just require('config') and don't worry about where it comes from.

One last thing: your configuration should be loaded into the browser via a completely separate file than any of your other frontend code. If you bundle your frontend code, the public configuration should be built as a completely separate bundle. Otherwise, your config isn't really config anymore - its just part of your code. Config needs to be able to be different on different machines.

书信已泛黄 2024-11-12 02:56:15

您可以使用 Konfig 来获取特定于环境的配置文件。它自动加载 json 或 yaml 配置文件,具有默认值和动态配置功能。

Konfig 存储库中的示例:

File: config/app.json
----------------------------
{
    "default": {
        "port": 3000,
        "cache_assets": true,
        "secret_key": "7EHDWHD9W9UW9FBFB949394BWYFG8WE78F"
    },

    "development": {
        "cache_assets": false
    },

    "test": {
        "port": 3001
    },

    "staging": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    },

    "production": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    }
}

在开发中:

> config.app.port
3000

在生产中,假设我们使用 $ NODE_ENV=production PORT=4567 node app.js 启动应用程序

> config.app.port
4567

更多详细信息:https://github.com/vngrs/konfig

You can use Konfig for environment specific config files. It loads json or yaml config files automatically, it has default value and dynamic configuration features.

An example from Konfig repo:

File: config/app.json
----------------------------
{
    "default": {
        "port": 3000,
        "cache_assets": true,
        "secret_key": "7EHDWHD9W9UW9FBFB949394BWYFG8WE78F"
    },

    "development": {
        "cache_assets": false
    },

    "test": {
        "port": 3001
    },

    "staging": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    },

    "production": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    }
}

In development:

> config.app.port
3000

In production, assume we start application with $ NODE_ENV=production PORT=4567 node app.js

> config.app.port
4567

More details : https://github.com/vngrs/konfig

软糖 2024-11-12 02:56:15

我将创建一个文件夹作为配置文件,命名为 config.js ,稍后我将在需要的地方使用此文件,如下所示

config.js 示例

module.exports = {
    proxyURL: 'http://url:port',
    TWITTER: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    GOOGLE: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    FACEBOOK: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    }
}

然后,如果我想在某处使用此配置文件,

我将首先如下导入

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

我可以访问以下值

const oauth = OAuth({
    consumer: {
        key: config.TWITTER.consumerkey,
        secret: config.TWITTER.consumerSecrete
    },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
    }
});

I will create a folder as config a file naming as config.js and later I will use this file wherever required as below

Example of config.js

module.exports = {
    proxyURL: 'http://url:port',
    TWITTER: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    GOOGLE: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    FACEBOOK: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    }
}

Then if i want to use this config file somewhere

I will first import as below

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

and I can access the values as below

const oauth = OAuth({
    consumer: {
        key: config.TWITTER.consumerkey,
        secret: config.TWITTER.consumerSecrete
    },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
    }
});
椵侞 2024-11-12 02:56:15

只需使用npm模块config(超过300000次下载)

https://www.npmjs.com/package/config

Node-config 为您的应用程序部署组织分层配置。

它允许您定义一组默认参数,并将它们扩展到不同的部署环境(开发、质量保证、登台、生产等)。

$ npm install config
$ mkdir config
$ vi config/default.json


{
      // Customer module configs
      "Customer": {
        "dbConfig": {
          "host": "localhost",
          "port": 5984,
          "dbName": "customers"
        },
        "credit": {
          "initialLimit": 100,
          // Set low for development
          "initialDays": 1
        }
      }
}



$ vi config/production.json

{
  "Customer": {
    "dbConfig": {
      "host": "prod-db-server"
    },
    "credit": {
      "initialDays": 30
    }
  }
}



$ vi index.js

var config = require('config');
//...
var dbConfig = config.get('Customer.dbConfig');
db.connect(dbConfig, ...);

if (config.has('optionalFeature.detail')) {
  var detail = config.get('optionalFeature.detail');
  //...
}


$ export NODE_ENV=production
$ node index.js

Just use npm module config (more than 300000 downloads)

https://www.npmjs.com/package/config

Node-config organizes hierarchical configurations for your app deployments.

It lets you define a set of default parameters, and extend them for different deployment environments (development, qa, staging, production, etc.).

$ npm install config
$ mkdir config
$ vi config/default.json


{
      // Customer module configs
      "Customer": {
        "dbConfig": {
          "host": "localhost",
          "port": 5984,
          "dbName": "customers"
        },
        "credit": {
          "initialLimit": 100,
          // Set low for development
          "initialDays": 1
        }
      }
}



$ vi config/production.json

{
  "Customer": {
    "dbConfig": {
      "host": "prod-db-server"
    },
    "credit": {
      "initialDays": 30
    }
  }
}



$ vi index.js

var config = require('config');
//...
var dbConfig = config.get('Customer.dbConfig');
db.connect(dbConfig, ...);

if (config.has('optionalFeature.detail')) {
  var detail = config.get('optionalFeature.detail');
  //...
}


$ export NODE_ENV=production
$ node index.js
孤独岁月 2024-11-12 02:56:15

有点晚了(仅仅 10 年),但我使用了如下结构的 config.js:

const env = process.env.NODE_ENV || 'development';

var config_temp = {
    default:{
        port: 3000,
        mysql_host: "localhost",
        logging_level: 5,
        secret_api_key: process.env.SECRET_API_KEY
    },
    development: {
        logging_level: 10
    },
    production: {
        port: 3001,
        mysql_host: "not-localhost"
    }
};
var config = {
    ...config_temp.default, 
    ...config_temp[env]
}
module.exports = config;

我加载配置:

var config = require('./config');
var port = config.port;

以这种方式:

  • 读取 env 变量包含在 config.js 文件中,这样我就可以避免这种丑陋的情况: require('./config')[process.env.NODE_ENV || '开发']。
  • 文件 config.js 可以上传到代码存储库中,因为敏感变量继续由 process.env 处理。
  • 如果 default:{custom_env:{ 中都包含相同的元素,则仅保留第二个元素。
  • 没有专用文件夹和多个文件(如 config 中所示)

A bit late (just 10 year) but I use a config.js structured like this:

const env = process.env.NODE_ENV || 'development';

var config_temp = {
    default:{
        port: 3000,
        mysql_host: "localhost",
        logging_level: 5,
        secret_api_key: process.env.SECRET_API_KEY
    },
    development: {
        logging_level: 10
    },
    production: {
        port: 3001,
        mysql_host: "not-localhost"
    }
};
var config = {
    ...config_temp.default, 
    ...config_temp[env]
}
module.exports = config;

and I load the config with:

var config = require('./config');
var port = config.port;

In this way:

  • The reading of the env variable is included in the config.js file so I can avoid this ugliness: require('./config')[process.env.NODE_ENV || 'development'].
  • The file config.js can be uploaded in the code 's repo because sensitive variables continue to be handled with process.env.
  • If the same element is contained in both default:{ and custom_env:{ only the second is kept.
  • There are no dedicated folders and multiple files (like in config)
來不及說愛妳 2024-11-12 02:56:15

我知道这是一篇非常旧的帖子。但我想分享我的用于配置环境变量的模块,我认为这是非常灵活的解决方案。
这是模块 json-configurator

var configJson = {
  'baseUrl': 'http://test.com',
  '$prod_baseUrl': 'https://prod.com',
  'endpoints': {
    'users': '<%= baseUrl %>/users',
    'accounts': '<%= baseUrl %>/accounts'
    },
  foo: 'bar',
  foobar: 'foobar',
  $prod_foo: 'foo in prod',
  $test_foo: 'foo in test',
  deep:{
    veryDeep: {
      publicKey: 'abc',
      secret: 'secret',
      $prod_secret: 'super secret'
    }
  }
};

var config = require('json-configurator')(configJson, 'prod');

console.log(config.deep.veryDeep.secret) 
// super secret 

console.log(config.endpoints.users)
// https://prod.com/users 

然后你可以使用 process.env.NODE_ENV 获取您的环境的所有变量。

I know this is a really old post. But I want to share my module for configuring environment variables, I think it is very flexible solution.
Here is the module json-configurator

var configJson = {
  'baseUrl': 'http://test.com',
  '$prod_baseUrl': 'https://prod.com',
  'endpoints': {
    'users': '<%= baseUrl %>/users',
    'accounts': '<%= baseUrl %>/accounts'
    },
  foo: 'bar',
  foobar: 'foobar',
  $prod_foo: 'foo in prod',
  $test_foo: 'foo in test',
  deep:{
    veryDeep: {
      publicKey: 'abc',
      secret: 'secret',
      $prod_secret: 'super secret'
    }
  }
};

var config = require('json-configurator')(configJson, 'prod');

console.log(config.deep.veryDeep.secret) 
// super secret 

console.log(config.endpoints.users)
// https://prod.com/users 

Then you can use process.env.NODE_ENV to get all the variables for your environment.

明月夜 2024-11-12 02:56:15

最好将'开发''生产'配置分开。

我使用以下方式:
这是我的 config/index.js 文件:

const config = {
    dev : {
        ip_address : '0.0.0.0',
        port : 8080,
        mongo :{
            url : "mongodb://localhost:27017/story_box_dev",
            options : ""
        }
    },
    prod : {
        ip_address : '0.0.0.0',
        port : 3000,
        mongo :{
            url : "mongodb://localhost:27017/story_box_prod",
            options : ""
        }
    }
} 

对于需要配置,请使用以下内容:

const config = require('../config')[process.env.NODE_ENV];

您可以使用您的配置对象:

const ip_address = config.ip_address;
const port = config.port;

It's better to separate 'development' and 'production' configs.

I use following way:
Here is my config/index.js file:

const config = {
    dev : {
        ip_address : '0.0.0.0',
        port : 8080,
        mongo :{
            url : "mongodb://localhost:27017/story_box_dev",
            options : ""
        }
    },
    prod : {
        ip_address : '0.0.0.0',
        port : 3000,
        mongo :{
            url : "mongodb://localhost:27017/story_box_prod",
            options : ""
        }
    }
} 

For require the config use following:

const config = require('../config')[process.env.NODE_ENV];

Than you can use your config object:

const ip_address = config.ip_address;
const port = config.port;
丶视觉 2024-11-12 02:56:15

我在游戏中有点晚了,但我在这里或其他地方找不到我需要的东西,所以我自己写了一些东西。

我对配置机制的要求如下:

  1. 支持前端。如果前端不能使用配置还有什么意义呢?
  2. 支持 settings-overrides.js - 看起来相同,但允许覆盖 settings.js 中的配置。这里的想法是在不更改代码的情况下轻松修改配置。我发现它对于 saas 很有用。

即使我不太关心支持环境 - 也会解释如何将其轻松添加到我的解决方案

var publicConfiguration = {
    "title" : "Hello World"
    "demoAuthToken" : undefined, 
    "demoUserId" : undefined, 
    "errorEmail" : null // if null we will not send emails on errors. 

};

var privateConfiguration = {
    "port":9040,
    "adminAuthToken":undefined,
    "adminUserId":undefined
}

var meConf = null;
try{
    meConf = require("../conf/dev/meConf");
}catch( e ) { console.log("meConf does not exist. ignoring.. ")}




var publicConfigurationInitialized = false;
var privateConfigurationInitialized = false;

function getPublicConfiguration(){
    if (!publicConfigurationInitialized) {
        publicConfigurationInitialized = true;
        if (meConf != null) {
            for (var i in publicConfiguration) {
                if (meConf.hasOwnProperty(i)) {
                    publicConfiguration[i] = meConf[i];
                }
            }
        }
    }
    return publicConfiguration;
}


function getPrivateConfiguration(){
    if ( !privateConfigurationInitialized ) {
        privateConfigurationInitialized = true;

        var pubConf = getPublicConfiguration();

        if ( pubConf != null ){
            for ( var j in pubConf ){
                privateConfiguration[j] = pubConf[j];
            }
        }
        if ( meConf != null ){
              for ( var i in meConf ){
                  privateConfiguration[i] = meConf[i];
              }
        }
    }
    return privateConfiguration;

}


exports.sendPublicConfiguration = function( req, res ){
    var name = req.param("name") || "conf";

    res.send( "window." + name + " = " + JSON.stringify(getPublicConfiguration()) + ";");
};


var prConf = getPrivateConfiguration();
if ( prConf != null ){
    for ( var i in prConf ){
        if ( prConf[i] === undefined ){

            throw new Error("undefined configuration [" + i + "]");
        }
        exports[i] = prConf[i];
    }
}


return exports;

中 解释

  • undefined 表示此属性是必需的
  • null 表示它是可选的
  • meConf - 目前代码的目标是 app 下的文件。 meConf 是针对 conf/dev 的覆盖文件 - 它被我的 vcs 忽略。
  • publicConfiguration - 从前端和后端可见。
  • privateConfiguration - 仅在后端可见。
  • sendPublicConfiguration - 将公开公共配置并将其分配给全局变量的路由。例如,下面的代码将在前端将公共配置公开为全局变量 myConf。默认情况下它将使用全局变量名称conf

    app.get("/backend/conf", require("conf").sendPublicConfiguration);

覆盖 privateConfiguration 的逻辑

  • 与 publicConfiguration 合并,然后与 meConf 合并。
  • publicConfiguration 检查每个键是否有覆盖,并使用该覆盖。这样我们就不会暴露任何隐私。

添加环境支持

尽管我不认为“环境支持”有用,但也许有人会。

要添加环境支持,您需要将 meConf require 语句更改为类似这样的内容(伪代码)

if (environment == "Production") {
meConf = require("../conf/dev/meConf"). Production;
}

if (环境==“开发”){
meConf = require("../conf/dev/meConf").development;
同样,

您可以为每个环境创建一个文件

 meConf.development.js
 meConf.production.js

并导入正确的文件。
其余逻辑保持不变。

I am a bit late in the game, but I couldn't find what I needed here- or anywhere else - so I wrote something myself.

My requirements for a configuration mechanism are the following:

  1. Support front-end. What is the point if the front-end cannot use the configuration?
  2. Support settings-overrides.js - which looks the same but allows overrides of configuration at settings.js. The idea here is to modify configuration easily without changing the code. I find it useful for saas.

Even though I care less about supporting environments - the will explain how to add it easily to my solution

var publicConfiguration = {
    "title" : "Hello World"
    "demoAuthToken" : undefined, 
    "demoUserId" : undefined, 
    "errorEmail" : null // if null we will not send emails on errors. 

};

var privateConfiguration = {
    "port":9040,
    "adminAuthToken":undefined,
    "adminUserId":undefined
}

var meConf = null;
try{
    meConf = require("../conf/dev/meConf");
}catch( e ) { console.log("meConf does not exist. ignoring.. ")}




var publicConfigurationInitialized = false;
var privateConfigurationInitialized = false;

function getPublicConfiguration(){
    if (!publicConfigurationInitialized) {
        publicConfigurationInitialized = true;
        if (meConf != null) {
            for (var i in publicConfiguration) {
                if (meConf.hasOwnProperty(i)) {
                    publicConfiguration[i] = meConf[i];
                }
            }
        }
    }
    return publicConfiguration;
}


function getPrivateConfiguration(){
    if ( !privateConfigurationInitialized ) {
        privateConfigurationInitialized = true;

        var pubConf = getPublicConfiguration();

        if ( pubConf != null ){
            for ( var j in pubConf ){
                privateConfiguration[j] = pubConf[j];
            }
        }
        if ( meConf != null ){
              for ( var i in meConf ){
                  privateConfiguration[i] = meConf[i];
              }
        }
    }
    return privateConfiguration;

}


exports.sendPublicConfiguration = function( req, res ){
    var name = req.param("name") || "conf";

    res.send( "window." + name + " = " + JSON.stringify(getPublicConfiguration()) + ";");
};


var prConf = getPrivateConfiguration();
if ( prConf != null ){
    for ( var i in prConf ){
        if ( prConf[i] === undefined ){

            throw new Error("undefined configuration [" + i + "]");
        }
        exports[i] = prConf[i];
    }
}


return exports;

Explanation

  • undefined means this property is required
  • null means it is optional
  • meConf - currently the code is target to a file under app. meConf is the overrides files which is targeted to conf/dev - which is ignored by my vcs.
  • publicConfiguration - will be visible from front-end and back-end.
  • privateConfiguration - will be visible from back-end only.
  • sendPublicConfiguration - a route that will expose the public configuration and assign it to a global variable. For example the code below will expose the public configuration as global variable myConf in the front-end. By default it will use the global variable name conf.

    app.get("/backend/conf", require("conf").sendPublicConfiguration);

Logic of overrides

  • privateConfiguration is merged with publicConfiguration and then meConf.
  • publicConfiguration checks each key if it has an override, and uses that override. This way we are not exposing anything private.

Adding environment support

Even though I don't find an "environment support" useful, maybe someone will.

To add environment support you need to change the meConf require statement to something like this (pseudocode)

if ( environment == "production" ) {
meConf = require("../conf/dev/meConf").production;
}

if ( environment == "development" ) {
meConf = require("../conf/dev/meConf").development;
}

Similarly you can have a file per environment

 meConf.development.js
 meConf.production.js

and import the right one.
The rest of the logic stays the same.

著墨染雨君画夕 2024-11-12 02:56:15

我刚刚使用的替代示例是因为我想要比典型的 .json 文件更灵活,但不希望将其抽象到需要依赖项的库中,就像这样。基本上,导出一个立即调用的函数,该函数返回一个具有我想要设置的值的对象。提供很大的灵活性。

     module.exports = function(){
       switch(node_env){
         case 'dev':
           return
           { var1 = 'development'};
         }
    }();

这里有一个更好的解释和完整的例子。 在 Node.js 中使用配置文件

an alt example I just used because I wanted more flexibility than a typical .json file but didn't want it abstracted away into a library which would require a dependency is something like this. Basically, exporting a function invoked immediately which returned an object with values I wanted set. Gives a lot of flexibility.

     module.exports = function(){
       switch(node_env){
         case 'dev':
           return
           { var1 = 'development'};
         }
    }();

There is a much better explanation with full example here. Using Config Files in Node.js

青春有你 2024-11-12 02:56:15

这是一种受这篇文章启发的简洁方法。除了无处不在的 lodash 包之外,它不需要任何其他包。此外,它还允许您通过特定于环境的覆盖来管理嵌套默认值。

首先,在包根路径中创建一个 config 文件夹,如下所示,

package
  |_config
      |_ index.js
      |_ defaults.json
      |_ development.json
      |_ test.json
      |_ production.json

这里是 index.js 文件

const _ = require("lodash");
const defaults = require("./defaults.json");
const envConf = require("./" + (process.env.NODE_ENV || "development") + ".json" );
module.exports = _.defaultsDeep(envConf, defaults);

现在假设我们有一个像这样的 defaults.json

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value3",
    "confKey4": "value4"
  }
}

和像这样的development.json,

{
  "confKey2": {
    "confKey3": "value10",
  }
}

如果您执行 config = require(' ./config') 这是您将得到的内容

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value10",
    "confKey4": "value4"
  }
}

。请注意,您将获得除特定于环境的文件中定义的值之外的所有默认值。因此您可以管理配置层次结构。使用defaultsDeep可以确保您甚至可以拥有嵌套的默认值。

Here is a neat approach inspired by this article. It does not require any additional packages except the ubiquitous lodash package. Moreover, it lets you manage nested defaults with environment-specific overwrites.

First, create a config folder in the package root path that looks like this

package
  |_config
      |_ index.js
      |_ defaults.json
      |_ development.json
      |_ test.json
      |_ production.json

here is the index.js file

const _ = require("lodash");
const defaults = require("./defaults.json");
const envConf = require("./" + (process.env.NODE_ENV || "development") + ".json" );
module.exports = _.defaultsDeep(envConf, defaults);

Now let's assume we have a defaults.json like so

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value3",
    "confKey4": "value4"
  }
}

and development.json like so

{
  "confKey2": {
    "confKey3": "value10",
  }
}

if you do config = require('./config') here is what you will get

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value10",
    "confKey4": "value4"
  }
}

Notice that you get all the default values except for those defined in environment-specific files. So you can manage a config hierarchy. Using defaultsDeep makes sure that you can even have nested defaults.

尛丟丟 2024-11-12 02:56:15
npm i config

In config/default.json
{
    "app": {
        "port": 3000
    },
    "db": {
        "port": 27017,
        "name": "dev_db_name"
    }
}

In config/production.json
{
    "app": {
        "port": 4000
    },
    "db": {
        "port": 27000,
        "name": "prod_db_name"
    }
}

In index.js

const config = require('config');

let appPort = config.get('app.port');
console.log(`Application port: ${appPort}`);

let dbPort = config.get('db.port');
console.log(`Database port: ${dbPort}`);

let dbName = config.get('db.name');
console.log(`Database name: ${dbName}`);

console.log('NODE_ENV: ' + config.util.getEnv('NODE_ENV'));

$ node index.js
Application port: 3000
Database port: 27017
Database name: dev_db_name
NODE_ENV: development

For production
$ set NODE_ENV=production
$ node index.js
Application port: 4000
Database port: 27000
Database name: prod_db_name
NODE_ENV: production
npm i config

In config/default.json
{
    "app": {
        "port": 3000
    },
    "db": {
        "port": 27017,
        "name": "dev_db_name"
    }
}

In config/production.json
{
    "app": {
        "port": 4000
    },
    "db": {
        "port": 27000,
        "name": "prod_db_name"
    }
}

In index.js

const config = require('config');

let appPort = config.get('app.port');
console.log(`Application port: ${appPort}`);

let dbPort = config.get('db.port');
console.log(`Database port: ${dbPort}`);

let dbName = config.get('db.name');
console.log(`Database name: ${dbName}`);

console.log('NODE_ENV: ' + config.util.getEnv('NODE_ENV'));

$ node index.js
Application port: 3000
Database port: 27017
Database name: dev_db_name
NODE_ENV: development

For production
$ set NODE_ENV=production
$ node index.js
Application port: 4000
Database port: 27000
Database name: prod_db_name
NODE_ENV: production
So要识趣 2024-11-12 02:56:15

除了 nconf 模块 /5869216/how-to-store-node-js-deployment-settings-configuration-files/8563528#8563528">这个答案,以及node-config 1411373">这个答案,还有node-iniparserIniReader,它们似乎是更简单的 .ini 配置文件解析器。

In addition to the nconf module mentioned in this answer, and node-config mentioned in this answer, there are also node-iniparser and IniReader, which appear to be simpler .ini configuration file parsers.

桃扇骨 2024-11-12 02:56:15

我最近刚刚发布了一个小模块来加载任何类型的配置文件。
这非常简单,您可以在 https://github.com/flesler/config-node< /a>

I just recently released a small module to load any type of configuration files.
It's pretty straight-forward, you can check it at https://github.com/flesler/config-node

伴随着你 2024-11-12 02:56:15

您可以使用 pconf: https://www.npmjs.com/package/pconf

示例:

var Config = require("pconf");
var testConfig = new Config("testConfig");
testConfig.onload = function(){

  testConfig.setValue("test", 1);
  testConfig.getValue("test");
  //testConfig.saveConfig(); Not needed

}

You can use pconf: https://www.npmjs.com/package/pconf

Example:

var Config = require("pconf");
var testConfig = new Config("testConfig");
testConfig.onload = function(){

  testConfig.setValue("test", 1);
  testConfig.getValue("test");
  //testConfig.saveConfig(); Not needed

}
剩一世无双 2024-11-12 02:56:15

我使用 Dotenv-Flow 进行配置管理。

这正在按预期工作。很多时候你有多个
本地、开发、登台和生产等环境。只要流动这些
创建您自己的环境的步骤。

1. npm i dotenv-flow。

2. 创建类似 .env | 的文件.env.dev | .env.prod

出于测试目的,请复制此内容

.env

DATABASE_HOST=global
DATABASE_PORT=global
DATABASE_USER=global
DATABASE_PASS=global
DATABASE_NAME=global

.env.dev

DATABASE_NAME=dev
DATABASE_PASS=dev

.env.prod

DATABASE_NAME=prod
DATABASE_PASS=prod

现在使用这些环境变量创建一个测试文件。

test.js

console.log('database host:', process.env.DATABASE_HOST);
console.log('database port:', process.env.DATABASE_PORT);
console.log('database user:', process.env.DATABASE_USER);
console.log('database pass:', process.env.DATABASE_PASS);
console.log('database name:', process.env.DATABASE_NAME);

< strong>现在使用这些命令来运行您的脚本。

node -r dotenv-flow/config test.js
node -r dotenv-flow/config test.js --node-env=dev
node -r dotenv-flow/config test.js --node-env=prod

如果您在特定文件夹中创建这些环境变量文件,就像在我的例子中一样,我已在 envs 文件夹中创建了这些文件,然后使用以下命令。 >

node -r dotenv-flow/config test.js --dotenv-flow-path=./envs
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=dev
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=prod

I used Dotenv-Flow for configuration management.

This is working as expected. It's very often that you have multiple
environments like local, dev, staging, and production. Just flow these
steps to create your own environments.

1. npm i dotenv-flow.

2. Create files like .env | .env.dev | .env.prod.

For testing purposes copy this content

.env

DATABASE_HOST=global
DATABASE_PORT=global
DATABASE_USER=global
DATABASE_PASS=global
DATABASE_NAME=global

.env.dev

DATABASE_NAME=dev
DATABASE_PASS=dev

.env.prod

DATABASE_NAME=prod
DATABASE_PASS=prod

Now create a test file use these environment variables.

test.js

console.log('database host:', process.env.DATABASE_HOST);
console.log('database port:', process.env.DATABASE_PORT);
console.log('database user:', process.env.DATABASE_USER);
console.log('database pass:', process.env.DATABASE_PASS);
console.log('database name:', process.env.DATABASE_NAME);

Now use these commands to run your script.

node -r dotenv-flow/config test.js
node -r dotenv-flow/config test.js --node-env=dev
node -r dotenv-flow/config test.js --node-env=prod

If you create these environment variables files in a specific folder like in my case I have created these files in envs folder then use the below command.

node -r dotenv-flow/config test.js --dotenv-flow-path=./envs
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=dev
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=prod
笨笨の傻瓜 2024-11-12 02:56:15

对于那些访问这个旧线程的人来说,这里有一个我认为很好的包。

https://www.npmjs.org/package/config

For those who are visiting this old thread here is a package I find to be good.

https://www.npmjs.org/package/config

东走西顾 2024-11-12 02:56:15

我在这里尝试了一些建议的解决方案,但对它们不满意,所以我创建了自己的模块。它称为 mikro-config,主要区别在于它遵循约定优于配置,因此您只需需要该模块即可开始使用它。

您可以将配置存储在 /config 文件夹中的纯 js 或 json 文件中。首先,它加载 default.js 文件,然后加载 /config 目录中的所有其他文件,然后根据 $NODE_ENV 变量加载环境特定配置。

它还允许使用 local.js 或特定于环境的 /config/env/$NODE_ENV.local.js 覆盖此配置以进行本地开发。

您可以在这里查看它:

https://www.npmjs.com/package/mikro -config

https://github.com/B4nan/mikro-config

I tryied some of suggested solutions here, but was not sattisfied with them, so I created my own module. It is called mikro-config and the main difference is that it honors convention over configuration, so you can just require the module and start using it.

You store your configuration in either plain js, or json files from /config folder. First it loads default.js file, then all other files from /config directory, then it loads environment specific configuration based on $NODE_ENV variable.

It also allows to override this configuration for local development with local.js or environment specific /config/env/$NODE_ENV.local.js.

You can take at look at it here:

https://www.npmjs.com/package/mikro-config

https://github.com/B4nan/mikro-config

拥有 2024-11-12 02:56:15

长期以来,我一直使用此处解决方案中提到的方法。然而,人们对明文秘密的安全性存在担忧。您可以在 config 之上使用另一个包,以便处理安全位。

看看这个: https://www .attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

For long, I used to use the approach mentioned in the solution here. There is a concern however, about security of the secrets in clear text. You can use another package on top of config so that the security bits are taken care of.

Check this out: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

清晨说晚安 2024-11-12 02:56:15

我们如何使用 TypeScript 做到这一点。

export const loadConfig = () => {
    const configLoadeded = configLoader.util.toObject() as any
    Config = configLoadeded
}

export interface ConfigI {
    productName: string;
    productId: string;
    googleCloudApiKey: string;
}

How we do it with TypeScript.

export const loadConfig = () => {
    const configLoadeded = configLoader.util.toObject() as any
    Config = configLoadeded
}

export interface ConfigI {
    productName: string;
    productId: string;
    googleCloudApiKey: string;
}
南风起 2024-11-12 02:56:15

如今,在使用数据库时,最简单的方法是根本不处理配置文件,因为仅使用单个环境变量(例如,将其称为 DB_CONNECTION)即可更轻松地设置部署环境,并且根据需要向其传递任何其他配置数据。

配置数据示例:

const config = {
    userIds: [1, 2, 3],
    serviceLimit: 100,
    // etc., configuration data of any complexity    
};
// or you can read it from a config file

创建一个连接字符串,其中包含数据库驱动程序不关心的额外参数:

import {ConnectionString} from 'connection-string';

const cs = new ConnectionString('postgres://localhost@dbname', {
    user: 'user-name',
    password: 'my-password',
    params: {
        config
    }  ​
});

然后我们可以生成结果字符串以将其存储在环境中:

cs.toString();
//=>postgres://localhost:my-password@dbname?config=%7B%22userIds%22%3A%5B1%2C2%2C3%5D%2C%22serviceLimit%22%3A100%7D

因此您可以将其存储在您的环境中,比方说,DB_CONNECTION,在客户端进程中,您可以通过 process.env.DB_CONNECTION 读取它:

const cs = new ConnectionString(process.env.DB_CONNECTION);

const config = JSON.parse(cs.params?.config); // parse extra configuration
//=> { userIds: [ 1, 2, 3 ], serviceLimit: 100 }

这样您将同时拥有连接和所有额外的信息。所需的配置全部在一个单一的环境变量,无需搞乱配置文件。

These days, when working with databases it is the easiest not to deal with configuration files at all, because deployment environments are easier to set up with just a single environment variable, call it DB_CONNECTION, for example, and pass it any additional configuration data as required.

configuration data example:

const config = {
    userIds: [1, 2, 3],
    serviceLimit: 100,
    // etc., configuration data of any complexity    
};
// or you can read it from a config file

Create a connection string, with extra parameters that the database driver doesn't care about:

import {ConnectionString} from 'connection-string';

const cs = new ConnectionString('postgres://localhost@dbname', {
    user: 'user-name',
    password: 'my-password',
    params: {
        config
    }  ​
});

Then we can generate the resulting string for storing it in the environment:

cs.toString();
//=>postgres://localhost:my-password@dbname?config=%7B%22userIds%22%3A%5B1%2C2%2C3%5D%2C%22serviceLimit%22%3A100%7D

So you store this in your environment, let's say, DB_CONNECTION, and within the client process you can just read it via process.env.DB_CONNECTION:

const cs = new ConnectionString(process.env.DB_CONNECTION);

const config = JSON.parse(cs.params?.config); // parse extra configuration
//=> { userIds: [ 1, 2, 3 ], serviceLimit: 100 }

This way you will have both the connection, and all the extra configuration needed, all within a single environment variable, no need messing with configuration files.

梦醒灬来后我 2024-11-12 02:56:15

尝试使用properties-gen
https://www.npmjs.com/package/properties-gen

非常类似于node-config 加载配置基础文件并根据您设置的环境使用 ext 文件对其进行扩展,但这是一个按需运行且完全可配置的 cli。

npx properties-gen init

要创建 cli 配置,然后将其安装在项目中

npm install properties-gen --save-dev

定义配置文件(基本文件和扩展文件)并在构建过程之前或在项目中启动开发服务器之前运行 generate 命令。

{
  "name": "myApp",
  "scripts": {
    "config": "properties-gen generate",
    "dev": "npm run config && next dev",
    "build": "npm run config && next build",
    "start": "next start"
  }
}

一件很酷的事情是,您可以定义多个配置组,以防您需要生成多个输出,例如客户端和服务器特定文件。

Try with properties-gen
https://www.npmjs.com/package/properties-gen

Pretty similar to node-config which loads a configuration base file and extends it with an ext file depending on the environment you set, but this is a cli that runs on demand and is fully configurable.

npx properties-gen init

To create the cli configuration, then install it in your project

npm install properties-gen --save-dev

Define your configuration files (base and extensions) and run the generate command before build process or before starting dev server in your project.

{
  "name": "myApp",
  "scripts": {
    "config": "properties-gen generate",
    "dev": "npm run config && next dev",
    "build": "npm run config && next build",
    "start": "next start"
  }
}

One cool thing is you can define multiple configuration groups, in case you need to generate multiple outputs for example a client and server specific files.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文