Source: apc-static/task/worker/generate_constants_json.js

/**
 * Generate path names json file.
 * @function task.worker.generateConstantsJson
 * @param {object} config - Task configuration.
 * @param {string} config.dest - Destination file name.
 * @param {string} config.data - Constants data.
 * @param {function} callback - Callback when done.
 * @example generateConstantsJson({
 *      dest: 'foo/bar/pathnames.json',
 *      data: {
 *          LOG_DIR_PATH: 'var/log',
 *          ACCESS_LOG_PATH: '#{LOG_DIR_PATH}/access.log'
 *      }
 * }, function(err){
 *      console.log('done!');
 * })
 * @author Taka Okunishi
 *
 */
var path = require('path'),
    file = require('../../lib/file'),
    object = require('../../lib/object'),
    fallbackCopy = object.fallbackCopy,
    debug = require('./_debug'),
    apeman = require('apeman'),
    writeReadonlyFile = file.writeReadonlyFile;

exports = module.exports = function (config, callback) {
    var dest = path.resolve(config.dest),
        data = exports._evaluateData(config.data || {}),
        content = JSON.stringify(data, null, 4);
    writeReadonlyFile(dest, content, function (err) {
        if (!err) {
            debug.didCreateFile(dest);
        }
        callback(err);
    });
};

exports._evaluateData = function (data) {
    var result = {};
    with (data) {
        Object.keys(data).sort().forEach(function (key) {
            function evaluate(value) {
                if (typeof(value) === 'string') {
                    var pattern = /(#\{)(.*?)(\})/g;
                    value = value.replace(pattern, function ($0, $1, $2) {
                        try {
                            return eval($2)
                        } catch (e) {
                            var value = global.apemandata[$2];
                            if (value) {
                                return value;
                            } else {
                                throw e;
                            }
                        }
                    });
                    if (!!value.match(pattern)) value = evaluate(value);
                }
                return value;
            }

            result[key] = evaluate(data[key]);
        });
    }
    return result;
};