Node requiring module before it's exposed is causing undefined

I'm ultimately trying to require var server = require('../../index.js'); in my foo-dao.js file so that I can get access to a hapi server plugin without having to pass it through the hapi request object from controller to dao.

The problem can be seen in the comments of my foo-dao.js method when trying to require index.js at the top of the file.

I believe the problem is because in my index.js, it requires the ./modules folder which requires the ./modules/foo/foo-routes.js which requires the ./modules/foo/foo-ctrl.js which requires the ./modules/foo/foo-dao.js.

Here's a simplified visual of the requires

./modules/index.js -> ./modules/foo/foo-routes.js -> ./modules/foo/foo-ctrl.js -> ./modules/foo/foo-dao.js -> ./modules/index.js <-- PROBLEM LIES HERE BECAUSE MY SERVER VARIABLE IN INDEX.JS HAS NOT BEEN EXPOSED YET.

/hapi/index.js

/**
 * Hapi.js server.
 *
 * @type {exports}
 */
var Hapi = require('hapi');
var modules = require('./modules');

// Instantiate the server
var server = new Hapi.Server('0.0.0.0', 4445, {cors: true, debug: {request: ['error']}});

...

/**
 * Add all the modules within the modules folder
 */
for(var route in modules) {
  server.route(modules[route]);
}

/**
 * Expose the server's methods when used as a require statement
 *
 * @type {exports.server}
 */
module.exports = server;

/hapi/modules/foo/foo-routes.js

var Joi = require('Joi');
var fooController = require('./foo-ctrl');

module.exports = function() {
  return [
    {
      method: 'GET',
      path: '/api/foo',
      config: {
        handler: fooController.foo//,
      }
    }
  ]
}();

/hapi/modules/foo/foo-ctrl.js

var fooDao = require('./foo-dao');

module.exports = function() {

  return {

    foo: function foo(req, reply) {

      fooDao.findFoo(function(err, data) {

        if (err) {
          return reply(Boom.badImplementation(err));
        }

        reply(data);
      });
    }
  }
}();

/hapi/modules/foo/foo-dao.js

var server = require('../../index.js');  //  WHEN I REQUIRE THE FILE HERE, IT'S UNDEFINED, PROBABLY BECAUSE THE server OBJECT HAS NOT BEEN EXPOSED YET

console.log('server = ');
console.log(server);

module.exports = function() {

  return {

    findFoo: function findFoo(callback) {
      var server = require('../../index.js');  //  WHEN I REQUIRE THE FILE HERE, IT'S ACTUALLY DEFINED, PROBABLY BECAUSE THE server OBJECT HAS BEEN EXPOSED BY THIS POINT. I DON'T WANT TO HAVE TO REQUIRE INDEX.JS IN EVERY SINGLE FUNCTION THOUGH. HOW CAN I CIRCUMVENT THIS PROBLEM?
      ... get data and return it in the callback
    }
  }
}();

I'm ultimately trying to require var server = require('../../index.js'); in my foo-dao.js file so that I can get access to a hapi server plugin without having to pass it through the hapi request object from controller to dao.

This is a very clear indication of poor design that the CommonJS system is trying to save you from. Don't take a submodule and make it aware of a higher related parent model. It makes the submodule non-reusable and strongly couples it to the containing application, which is the opposite of what you want. Deep, reusable modules should get what they need passed in via options and request objects, not by requiring higher-level application abstractions.

Here's what you want to do in your foo-dao.js at least as a first step to solve your circular require problem. But even beyond that I think you need a more extensive change to your code structure to make it clean.

module.exports = function makeDao(server) {

  return {
    findFoo: function findFoo(callback) {
      //now via closure you have permanent access to the server,
      //without being coupled so tightly to it's exact filesystem location
    }
  }
};

To load this up, you'll need to pass the server instance down from the top, which in your case is to modules.

var server = new Hapi.Server('0.0.0.0', 4445, {cors: true, debug: {request: ['error']}});
var modules = require('./modules')(server);

This will make your modules code both easier to test (dependency injection) and re-use.

I elaborate more on my overall approach in my express_code_structure repository. In particular note how the appinstance is passed down to the routes. Details of how this works change with express4 and I'm sure hapi.js is different, but the general ideas should probably still apply.