管理NodeJS配置标志的更好方法?



我有一个NodeJS应用程序,我需要提供各种标志来定制环境。

我已经用dotenv处理环境文件,我也从CLI预加载到应用程序:

"scripts": {
"hello": "DOTENV_CONFIG_PATH=/my/path/dev.env node --max_semi_space_size 64 --inspect=0.0.0.0 dist/index.js"
}

我的问题是:我开始遇到一种情况,我需要在某些情况下添加越来越多的nodejs标志-有没有更好的方法来做到这一点?我无法想象将来传递20个cli参数(即--max_semi_space_size ...)给node。

我想到/听说过的选项有:

  • 将脚本逻辑移动到外部文件
  • 将node命令与node +标志混叠
  • 用我的自定义设置重新编译节点😱

但感觉很奇怪——我相信有一种方法可以处理这个问题,而不是那么粗糙。你会如何解决这个问题?我也在使用docker,如果这对你的建议有什么影响的话。

助教!

最佳实践是创建可重用且可以在多个级别上更改的机制。许多旨在广泛使用的docker容器都遵循这种方法。

分层配置

模块需要支持hierarchical configuration。这意味着将有不止一种方法来设置变量,并且将有一个严格的层次结构,基于优先级,哪个值将是最终值。层次结构的最佳实践如下:

  1. 设置为默认值
  2. 检查配置文件中是否有新值,如果有,覆盖值
  3. 检查环境变量是否有新值,如果有,则覆盖
  4. 检查启动标志是否有新值,如果有,覆盖该值。

这种方法适用于node CLI参数,除了层次结构较浅并且止于环境变量设置之外。

在这一系列检查之后,您将得到变量的最终值。

应用程序配置变量

Node.js有一个很好的库,叫做nconf,你可以在github上找到。该库允许您进行分层配置。下面是一个简单的示例(取自库中的示例,为节省空间而进行了修剪)

var nconf = require('nconf');
// 1. any overrides
nconf.overrides({
'always': 'be this value'
});
// 2. `process.env`
// 3. `process.argv`
nconf.env().argv();
// 4. Values in `config.json`
nconf.file('/path/to/config.json');
// 5. Any default values
nconf.defaults({
'if nothing else': 'use this value'
});

将其封装在您自己的模块中,并添加处理配置所需的附加逻辑

var myConfig = require('nconf');
..
...
..
module.exports = myConfig;

然后使用代码中的配置,如下所示

var config = require('./myConfig');
config.get('hello');

这将允许您在映像中设置默认配置,并在后续映像中覆盖它们。下面是一个示例,第一个映像base将在构建期间从文件中设置hello标志,第二个映像将使用ENV覆盖该设置:

FROM debian:latest as base
COPY ./hello_config.json /path/to/config.json
...
...
FROM base AS second
ENV hello="Hello world from second image!"
...
...

现在,当您创建容器时,您可以通过传递新环境文件(--env-file)或单个标志(-e--env)来覆盖更改

docker run --env hello="Hi from container!" --env-file ./new_conf.list secod

注意,环境文件应该是shell格式FLAG=VALUE,而不是json格式。

节点CLI参数

Node CLI参数也可以用这种方法处理(唯一的区别是层次结构止于CLI)。容器应该在Dockerfile中定义NODE_OPTIONS环境变量和所需的标志,如下所示:

...
ENV NODE_OPTIONS="--max_semi_space_size 64 --inspect=0.0.0.0"
...

这可以增强为接受构建选项以及逐步构建变量

...
ARG NODE_OPTIONS=""
ENV NODE_OPTIONS="${NODE_OPTIONS} --max_semi_space_size 64"
ENV NODE_OPTIONS="${NODE_OPTIONS} --inspect=0.0.0.0"
...

现在,在构建过程中,我们可以指定如下的附加选项

docker build --build-arg NODE_OPTIONS="--cpu-prof --heapsnapshot-near-heap-limit=3" .

与应用程序配置相同,您可以使用-env--env-file文件来为特定的容器修改它。

从我的角度来看。Json文件应该尽可能的干净。对于这种情况,我通常创建scriptsshell目录,然后将所有脚本放入单独的bash或shell文件中。最后从npm命令中调用这些文件。

使用npm 运行bash脚本我不确定在这种情况下使用nconf是一个好的选择。

我想这个可以满足你的需要:https://nodejs.org/api/cli.html cli_node_options_options

NODE_OPTIONS =选项…

用空格分隔的命令行选项列表。

NODE_OPTIONS='--require "./a.js"' node --require "./b.js"
# is equivalent to:
node --require "./a.js" --require "./b.js"

…除了:

如果使用了环境中不允许的选项,Node.js将退出并报错

--max_semi_space_size不在允许的选项中…但你可以试试。

但无论如何

"scripts": {
"hello": "./run_node_with_options.sh"
}
# run_node_with_options.sh
DOTENV_CONFIG_PATH=/my/path/dev.env node --max_semi_space_size 64 --inspect=0.0.0.0 dist/index.js"

似乎是一个更健壮的解决方案。

最新更新