如何将环境变量转换为JS中的对象?

时间:2016-08-29 19:41:01

标签: javascript node.js env

我尝试将环境变量转换为值的对象以便在JavaScript中进行配置,但我不知道实现此目的的最佳方法。

想法是将ah输出为:

SAMPLE_ENV_VAR=value

到目前为止我所拥有的:

{
    sample: {
        env: {
            var: value
        }
    }
}

5 个答案:

答案 0 :(得分:3)

我不知道你为什么要这样做。但无论如何,这是一个基于你的更完整的解决方案:

const _ = require('lodash');
const result = {};

// We'll take the following as an example:
// process.env = { HELLO_WORLD_HI: 5 }
// We'll expect the following output:
// result = { hello: { world: { hi: 5 } } }
_.each(process.env, (value, key) => {
    // We'll separate each key every underscore.
    // In simple terms, this will turn:
    // "HELLLO_WORLD_HI" -> ['HELLO', 'WORLD', 'HI']
    const keys = key.toLowerCase().split('_');

    // We'll start on the top-level object
    let current = result;

    // We'll assign here the current "key" we're iterating on
    // It will have the values:
    // 'hello' (1st loop), 'world' (2nd), and 'hi' (last)
    let currentKey;

    // We'll iterate on every key. Moreover, we'll
    // remove every key (starting from the first one: 'HELLO')
    // and assign the removed key as our "currentKey".
    // currentKey = 'hello', keys = ['world', 'hi']
    // currentKey = 'world', keys = ['hi'], and so on..
    while ( (currentKey = keys.shift()) ) {
        // If we still have any keys to nest,
        if ( keys.length ) {
          // We'll assign that object property with an object value
          // result =// { HELLO: {} }
          current[currentKey] = {};

          // And then move inside that object so
          // could nest for the next loop
          // 1st loop: { HELLO: { /*We're here*/ } }
          // 2nd loop: { HELLO: { WORLD: { /*We're here*/ } } }
          // 3rd loop: { HELLO: { WORLD: { HI : { /*We're here*/ } } } }
          current = current[currentKey];
        } else {
          // Lastly, when we no longer have any key to nest
          // e.g., we're past the third loop in our example
          current[currentKey] = process.env[key]
        }
    }
});

console.log(result);

简单地说:

  • 我们将遍历每个环境变量(from process.env
  • 使用下划线拆分键名称,然后再次循环每个键(['HELLO', 'WORLD', 'HI']
  • 将其分配给对象({ hello: {} } - > { hello: { world: {} } } - > { hello: world: { hi: ? } } }
  • 当我们不再有任何键时,将其指定为实际值({ hello: { world: { hi: 5 } } }

答案 1 :(得分:0)

有趣的是,我刚刚完成了这个个人项目的代码。我最终使用的并不理想,但对我有用:

export function keyReducer(
  src: any,
  out: any,
  key: string,
  pre: string,
  del: string
): ConfigScope {
  const path = key.toLowerCase().split(del);
  if (path[0] === pre.toLowerCase()) {
    path.shift();
  }

  if (path.length === 1) { // single element path
    const [head] = path;
    out[head] = src[key];
  } else {
    const tail = path.pop();
    const target = path.reduce((parent: any, next: string) => {
      if (parent[next]) {
        return parent[next];
      } else {
        return (parent[next] = <ConfigScope>{});
      }
    }, out);
    target[tail] = src[key];
  }
  return out;
}

static fromEnv(env: Environment, {prefix = 'ABC', delimiter = '_'} = {}) {
  const data: ConfigScope = Object.keys(env).filter(key => {
    return StringUtils.startsWith(key, prefix);
  }).reduce((out, key) => {
    return keyReducer(env, out, key, prefix, '_');
  }, <ConfigScope>{});
  return new Config(data);
}

(使用TypeScript类型注释)

这里的想法是拆分每个键,在向下的路上创建目标对象,然后设置最终值。

答案 2 :(得分:0)

这是我的快速看法:

var object = {}; // the object to store the value in 
var name = "SAMPLE_ENV_VAR"; // the environment variable key
var value = "value"; // the value of the environment variable

// helper function to automatically create an inner object if none exists
function getOrCreateInnerObj(obj, name) {
  if (!obj.hasOwnProperty()) {
    obj[name] = {};
  }
  return obj[name];
}

// an array of the individual parts (e.g. ["sample", "env", "var"])
var keyParts = name.toLowerCase().split("_");

// innerObj will contain the second to last element object in the tree based on the array of keys
var innerObj = getOrCreateInnerObj(object, keyParts[0]);
for (var i = 1; i < keyParts.length - 1; i++) {
  innerObj = getOrCreateInnerObj(innerObj, keyParts[i]);
}

// set the value itself
innerObj[keyParts[keyParts.length - 1]] = value;

$("body").html(JSON.stringify(object));

它的要点是,除了关键部分数组中的最后一个元素之外,您在该键的当前父对象中获取或创建一个对象,并且一旦您为除了最后一个键之外的所有键重复此操作,你将拥有倒数第二个内部对象,然后你可以设置值。

修改:Working example

编辑2:Here是一个更清晰的例子,它使用一点点递归来完成同样的事情

答案 3 :(得分:0)

const basic = {};
let current;
`YOUR_VARIABLE_NAME`
  .split(`_`)
  .forEach((item, index, array) => {
    if(index === 0) {
      return current = basic[item] = {};
    }
    if(index === array.length - 1) {
      return current[item] = process.env.HE_LO_NA;
    }
    current = current[item] = {};
});

console.log(require('util').inspect(basic, {depth: 10}));

答案 4 :(得分:0)

const _ = require('lodash');
const process = require('process');

const result = Object.entries(process.env).reduce((acc, [key, value]) => {
    _.set(acc, key.toLowerCase().replace('_', '.'), value);
    return acc;
}, {})
相关问题