2

I have this JSON config for a backend CLI utility:

{
  "searchRoots": ["$HOME"],
  "list": []
}

if I did this with JavaScript, I would do:

module.exports = {
   searchRoots": [process.env.HOME],
   list: []
};

the problem with using JSON instead of JS, is that I cannot programmatically reference environment variables or any variables really, everything is hardcoded.

So what I will do in my Node.js code, is do:

const conf = require('./conf.json');

const searchRoots = conf.searchRoots.map(function(item){
   return process.env[item];
});

Is there another good way to do this? Without env variables?

What is the best way to include some sort of variable in JSON that can be interpreted by the reader of the file?

Is there a way to do bash-style interpretation of the path via Node.js?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817

3 Answers3

1

Seems like this is the best way to handle this type of situation. Use bash-style path interpretation, and call bash from your process.

With your JSON config file like so:

{
  "searchRoots": ["$HOME"],
  "list": []
}

You can write a routine like this, which will use bash to interpret the strings, and turn them into absolute paths:

searchRoots: function (cb) {

    const mappedRoots = searchRoots.map(function (v) {
      return `echo "${v}";`;
    });

    const k = cp.spawn('bash');

    k.stdin.write('\n' + mappedRoots + '\n');

    process.nextTick(function () {
      k.stdin.end();
    });

    const data = [];
    k.stderr.pipe(process.stderr);

    k.stdout.on('data', function (d) {
      data.push(d);
    });

    k.once('close', function (code) {
      if (code > 0) {
        return cb({
          code: code
        });
      }
      cb(null, data.map(function (d) {
        return String(d).trim();
      }));
    });
  },

This will transform the original data to:

  {
      "searchRoots": ["/Users/YourHomeDir"],
      "list": []
   }

And it's generic, so it can handle other env variables, not just the $HOME variable. That's the big win here.

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
1

For this exact reason I use a .js file instead of .json for the config. So as an example ... the file would be called config.js and would have the following code.

module.exports = {
    "searchRoots": [ process.env.HOME ],
    "list": []
}
Naraen
  • 3,240
  • 2
  • 22
  • 20
0

if you structure your library properly, it should have a method to update your variable or you should be able to access your global variable as long as the variable makes part of the same environment. you can check any documentation or JS book on accessing local and global variables.

  • Sorry this answer does not make any sense to me, I just added some more relevant details to the question. – Alexander Mills Apr 13 '17 at 17:15
  • Note that the value of your searchRoots is an array. You might be looking at process.env[item[0]] or jsonObject.searchRoots[0] . Have look at both links https://www.codementor.io/nodejs/tutorial/how-to-use-json-files-in-node-js and http://stackoverflow.com/questions/4870328/read-environment-variables-in-node-js – joaoantonio Apr 13 '17 at 17:52