我有一个配置json文件,这是一个示例
{
"version": "1.0",
"producer": {
"name": "app_name_{{ ENVIRONMENT }}_producer",
"kms_key_alias": "alias/app_name_{{ ENVIRONMENT }}_producer_key",
"shards": 1,
"subscriptions": [
{
"name": "app_name1_{{ ENVIRONMENT }}_consumer",
"account_id": "123456789012",
"active": true
},
{
"name": "app_name2_{{ ENVIRONMENT }}_consumer",
"account_id": "987654321098",
"active": true
}
]
},
"consumers": [
{
"name": "app_name_{{ ENVIRONMENT }}_consumer",
"kms_key_alias": "alias/app_name_{{ ENVIRONMENT }}_consumer_key",
"shards": 1
}
],
"overrides": {
"prod": {
"producer": {
"shards": 2,
"subscriptions": [
{
"name": "app_name1_{{ ENVIRONMENT }}_consumer",
"account_id": "123456789012",
"active": false
}
]
},
"consumers": [
{
"name": "app_name_{{ ENVIRONMENT }}_consumer",
"shards": 3
}
]
}
}
}
我的目标是为该环境生成最终配置。环境是变量。
prod
的配置将有所不同。例如prod中的producer.shards
将是2,而不是1。
此过程是,读取json文件(属于producer
和consumers
的一部分,然后保存到新变量new_json
中。这可以理解为默认值。
{
"producer": {
...
}
consumers": {
...
}
}
然后读取覆盖会话,如果环境为prod
,它将覆盖相关键中的值。
我写了forEach
代码以读取overrides
中的每个键,然后我需要确认键是列表或映射,然后转到该部分的结尾,替换{{1 }}。
new_json
示例json是一个简单的json。真正的json有几百行。因此,遍历每个密钥不是有效的方法。
是否有任何快速/智能方法来覆盖对const json = JSON.parse(template)
if ({}.hasOwnProperty.call(overrides, environment)) {
const env = overrides[environment];
Object.keys(env).forEach((key){
...
}
}
的覆盖中的任何键?
使用Object.assign(),我仍然需要遍历每个键,否则,我得到的键会更少。
例如,使用下面的代码,我在new_json
列表中所占的比例减少了。
subscriptions
感谢您将我指向lodash.defaultsDeep,但在合并列表中的地图时,它必须在同一位置一对一匹配。
使用存在作为示例,如果我稍微调整$ cat a.js
const fs = require('fs');
const swig = require('swig-templates');
const environment='prod';
let template = swig.compileFile("jsoncontent.json");
template = template({
ENVIRONMENT: environment,
});
const json = JSON.parse(template);
Object.assign(json.producer, json.overrides.prod.producer)
delete json.overrides
console.log(JSON.stringify(json, null, 2));
$ node a.js
{
"version": "1.0",
"producer": {
"name": "app_name_prod_producer",
"kms_key_alias": "alias/app_name_prod_producer_key",
"shards": 2,
"subscriptions": [
{
"name": "app_name1_prod_consumer",
"account_id": "123456789012",
"active": false
}
]
},
"consumers": [
{
"name": "app_name_prod_consumer",
"kms_key_alias": "alias/app_name_prod_consumer_key",
"shards": 1
}
]
}
,则订阅的第一个列表,名称从overrides
更改为app_name1
app_name2
结果将是:
"overrides": {
"prod": {
"producer": {
"shards": 2,
"subscriptions": [
{
"name": "app_name2_{{ ENVIRONMENT }}_consumer",
"account_id": "123456789012",
"active": false
}
]
}
}
现在有两个{ shards: 2,
subscriptions:
[ { name: 'app_name2_prod_consumer',
account_id: '123456789012',
active: false },
{ name: 'app_name2_prod_consumer',
account_id: '987654321098',
active: true } ],
name: 'app_name_prod_producer',
kms_key_alias: 'alias/app_name_prod_producer_key' }
。
答案 0 :(得分:2)
Object.assign似乎正是您需要的。
示例:
var o1 = {
a: 1,
b: 2
}
var override = {
a: 9
}
Object.assign(o1, override)
console.log(o1) // {a: 9, b: 2}
编辑
Object.assign仅循环通过根级别。
对于深度分配,您可以使用lodash.defaultsDeep:
var env = _.defaultsDeep(json.overrides.prod.producer, json.producer)