Ok, so there are a few things I would advise.
1. KISS. Simple functions or several of them per module, without complex inheritance chains.
2. Closures (the term describing the sharing scope that you are referring to).
Keep it simple. Yes, separation of concerns is great, but what is your ultimate goal? To separate concerns or have a server with functionalities?
You can simply attach 'methods' (not a fullly correct term, but let's roll for a bit) to server.
So your server can have a few lines at the top:
var initialize = require('./initialize');
var attachClients = require('./attach-clients');
var functionalityA = require('./functionality-a');
var functionalityB = require('./functionality-b');
...
etc.
Then attach them to your server.
Server.prototype.initialize = initialize;
Server.prototype.attachClients = attachClients;
...
So now your server has all the methods you need. You can even namespace it into server.ctrl.method if you like it that way, but that's just a detail.
The real thing is that those things can be simple functions that do what you want.
That's a typical node.js approach - make a lot of small modules that each does one thing and one thing well. Each can export maybe just one function or another can export a "class" (though I'd move away from that concept ASAP), or glue together a few of them to achieve something third.
Closures - that's also your friend. Given this:
function Server() {
// "close" this var inside the Server function
var myName = 'Server thing.';
function anAction() {
// this "inner" function has access to the Server closure, or all variables reachable within server - even after instantiation.
console.log('My name is', myName); // picks up the var from outer function
}
this.anAction = anAction; // if you really want to expose it.
return this;
};
Now you have an outer thing (Server "class"), and the inner thing (the action). when you instantiate the server (var server = new Server();), the Server function is ran and gone. But later when you call the 'anAction()' of it, it will still have access to the last known value of that myName var. And if some other action, function, "method" let's say, changes that variable, your anAction will have access to that updated info.
And this works on module level, too.
- You have an internal variable or set of them in a module.
- You export some functions and objects.
- Each of those exported things still has access to those internal variables.
- As you call them in the future, they can even modify the module.
And further on, require() is caching stuff, so if you require the same file sometime later from some other module, you will get that current, modified state of things.
That's how you would share info between your "Server" and "ServerController".
My advice is to learn a lot about closures in JS, and