6
头图

管理跨不同环境的多个配置文件可能具有挑战性,并且有多种工具正试图用不同的方法解决这个问题。但是,在本文中,我们将学习如何使用 node-config 跨不同部署环境创建和管理 Node.js 配置文件。

node-config是什么?

Node-config允许你在你的Node应用程序中为不同的部署环境创建配置文件。有了它,你可以定义一个你打算跨环境重复使用的默认配置文件,然后将默认配置扩展到其他环境,如开发、暂存等。

你可以使用一些临时的命令行参数来覆盖这些参数,比如在你的命令行参数中加入NODE_ENV=development

Node-config使创建和管理一个在所有部署环境中共享的一致的配置界面变得更加容易。

为了更好地理解如何设置这个配置,让我们使用一个Node应用样本。首先,在你的终端上运行下面的命令来克隆这个资源库,或者从这里下载并解压它。

git clone https://github.com/ezesundayeze/node-env-sample

要安装 Node 依赖项,请运行:

npm install

设置 node-config

因为node-config是一个npm包,我们可以通过运行这些命令中的任何一个来用npm或yarn安装它。

npm install config

或者

yarn add config

支持的 node-config 文件扩展名

Node-config 支持许多文件扩展名。在发布时,当前版本的 node-config (3.3.6) 支持以下扩展:

- .json
- .json5
- .hjson
- .yaml or .yml
- .coffee
- .js
- .cson
- .properties
- .toml
- .ts
- .xml

这意味着你可以用任何一个支持的扩展来创建你的配置文件,但为你的项目选择一个扩展并在整个构建过程中坚持使用它是有意义的。

在本教程中,我们将使用 .json 扩展名。

创建默认环境变量

创建一个 config 目录并向其中添加一个 config/default.json 文件。这将是默认配置文件,并将包含所有默认环境变量。

在我们的示例应用程序中它应该是这样的:

config/default.json

{
  "server": {
    "host": "localhost",
    "port": 0,
  }
}

我们将在我们的应用程序中通过导入 config 和使用 get 方法访问变量来访问它。

const config = require('config');
const port = config.get('server.port');
const host = config.get('server.host');

让我们创建一个 server.js 文件并添加以下代码。

const express = require('express');
const config = require('config');
const app = express();
const port = config.get('server.port');
const host = config.get('server.host');

app.get('/', (req, res) => {
  res.send('Hello World');
});
const server = app.listen(port, host, (err) => {
  if (err) {
    console.log(err);
    process.exit(1);
  }
  console.log(`Server is running on ${host}:${server.address().port}`);
});

你可以在你的应用程序的其他部分以类似的方式使用node-config。

扩展默认配置文件

你可以通过创建其他配置文件来扩展默认的配置文件。例如,你可以为开发、生产、QA、暂存、本地等创建配置文件。让我们来介绍一下我们将在我们的应用程序中使用的配置文件的主要类型。

本地配置文件

创建本地配置文件是为了覆盖你的配置文件的部署版本。例如,对于你的开发部署,你可以有一个 local-development.json 文件来存储你所有的本地开发配置——它反映了你在部署的开发环境中期望的那种行为。

因此,你可以拥有这样的东西:

local-{instance}.EXT
local-{deployment}.EXT
local-{deployment}-{instance}.EXT

短主机名和完整主机名

你也可以使用简短和完整的主机名来定义你在特定平台上的配置文件,以防你要在多个实例上进行部署。例如,您可以有一个 {short_hostname},它将代表您的服务器名称直到第一个点。如果您的主机名是 demo.example.com,则配置可以是 demo.EXT (demo.json)

此外,如果您的 {full_hostname} 是您的整个服务器名称,则您可以在 {short_hostname} 与其他机器发生冲突时使用它。因此,在您的主机名是 demo.example.com 的情况下,您的配置文件名将是 demo.example.com.json

自定义配置文件

你可能还想创建一个自定义的配置文件来容纳一些环境变量的覆盖。Node-config提供了对配置文件类型的支持,你可以用 custom-environment-variables.EXT(custom-environment-variables.json)的名字来定义。

测试配置值

如果您的环境变量没有设置,使用它们的服务就会中断。所以,你应该确保你的环境变量已经过测试。Node-config 提供了多个实用程序,其中之一是 config.has() 方法,它允许您验证是否设置了环境变量。

你可以创建一个测试文件或将其添加到你的预提交钩子中,以确保你的配置文件都已设置好。

以下是如何使用 config.has() 检查配置变量是否存在的示例:

if (config.has('dbConfig')) { 
... 
}

你也可以在你的Jest测试中使用它,像这样:

const config = require('config');
test('Server config exist', () => {
  expect(config.has("server")).toBe(true);
});
test('Default config exist', () => {
  expect(config.has("server.port")).toBe(true);
  expect(config.has("server.host")).toBe(true);
});

使用命令行重写

使用命令行覆盖允许你从你的终端或命令行中即时指定配置参数。你需要在启动应用程序时通过指定 NODE_CONFIG='{...}' 命令来设置配置,参数必须是JSON字符串的格式。

下面是一个例子:

NODE_CONFIG='{"server": {"host":"192.168.43.13", "port":"3030"}}' npm run dev

JSON 值周围的单引号允许您安全地使用双引号。在某些情况下,根据您的操作系统,您可能需要对某些字符进行转义。您还可以使用命令行导出来避免一直键入命令。

在你的终端上运行下面的命令将覆盖你的服务器的主机和端口或你选择覆盖的任何其他配置。

export NODE_CONFIG='{"server": {"host":"192.168.43.13", "port":"3030"}}'

如果您更喜欢使用 JavaScript,可以在调用配置库之前将其添加到您的服务器文件中,如下所示:

const express = require('express');
process.env.NODE_CONFIG = '{"server": {"host":"localhost", "port":"3030"}}';
const config = require('config');

诀窍是在配置加载之前将 NODE_CONFIG 变量设置为 JSON 字符串。

发生这种情况是因为命令行覆盖优先于所有其他类型的覆盖。下面是一些在使用 node-config 时不能用作环境变量的保留字,因为库提供了它们的实现,可能会与您的实现冲突。

get
has
util
getConfigSources
makeHidden
makeImmutable
setModuleDefaults
watch 
_attachProtoDeep
_cloneDeep
_diffDeep

这不是一个详尽的列表,所以一定要查看文档。

有一些插件可以让你高效地使用 node-config 和 Docker 来管理密钥,一个插件可以让你自动重新加载 node-config(你可能已经知道,配置不会在文件更改时自动加载),以及允许您取消缓存您的配置(uncache your config)变量的插件。

总结

使用 node-config 时,有无数种方法可以配置您的 Node 应用程序。有了它,您可以轻松管理您的配置文件并根据需要扩展它们,从而在您的项目中实现最大的灵活性、可靠性和一致性。谢谢阅读。


杭州程序员张张
11.8k 声望6.7k 粉丝

Web/Flutter/独立开发者/铲屎官