微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

管理 NodeJS 配置标志的更好方法? 分层配置应用配置变量节点 CLI 参数

如何解决管理 NodeJS 配置标志的更好方法? 分层配置应用配置变量节点 CLI 参数

我有一个 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 ... 到节点。

我想到/听说过的一些选择是:

  • 将脚本逻辑移动到外部文件
  • 使用节点 + 标志为节点命令添加别名
  • 使用我的自定义设置重新编译节点 ?

但感觉很奇怪 - 我相信有一种方法可以处理不那么笨拙的问题。你会如何解决这个问题?如果这对您的建议有任何影响,我也在 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 文件针对特定容器进行修改。

,

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

像这样:Running bash scripts with npm

我不确定在这种情况下使用 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"

似乎是一个更强大的解决方案。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。