docs: function _from_envfile (fname_tmpl, opts, cfg_so_far, cb) {
    var vals = {
      env: process.env.NODE_ENV || 'development'
    };
    
    _.merge (vals, cfg_so_far);
  
    var fname = interpolator.parse (fname_tmpl, vals);
  
  // check existence
    fs.access (fname, function (err) {
      if (err) {
        if (opts.ignore_missing) {
          return cb (null, {});
        }
        else {
          return cb (err);
        }
      }
  
      try {
        var readf = fs.readFileSync (fname);
        var envConfig = dotenv.parse (readf);
        var ka = [];
        var va = [];
    
        if (!opts) opts = {};
    
        _.forEach (envConfig, function (v, k) {
          if (opts.regexp && !(k.match (opts.regexp))) return;
          if (opts.prefix && !(_.startsWith (k, opts.prefix))) return;
          if (opts.prefix) k = k.substr (opts.prefix.length);
          
          // change __ into . in k
          k = k.replace (/__/g, '.');
      
          ka.push (k);
          va.push (v);
        });
      
        var obj = _.zipObjectDeep (ka, va);
  
        // expand variables in loaded object
        _expand (obj, vals, cb);
    
      } catch (e) {
        return cb (e);
      }
    });
  }