I'm creating a node.js project following the class constructor pattern:
function my_class(x,y){
this.x = x;
this.y = y;
}
The starting point of the project is the main.js
file. Any class of the project must be able to access global objects (such as "world" and "socket") which are defined on main.js
. I found 4 options:
I define my classes inside
main.js
. They'll have access tomain.js
's globals for being on it's closure, butmain.js
will become bloated.I move the class to another file such as
my_class.js
andrequire()
it. This doesn't work because my_class's instances will lose the closure context and no longer be able to accessmain.js
's globals.I move the class to another file and manually inject dependencies to it's constructor (ex:
my_class(world,socket)
). The problem is, code becomes much more complicated and weird semantics such as "my_instance.world" pop on the source, which is nonsense because "world" is not property ofmy_class
.I move the class to another file and require it using
my_class = eval(fs.readFileSync(())
instead ofrequire
. This works just fine as my_class getsmain.js
's closure context, and is the solution I'm using, but seems hacky.
Which is the right way to modularize such node.js project?
Your problem seems tricky because you have a circular dependency:
main.js
depends on the functionality ofmy_class
andmy_class
depends on the data ofmain.js
.By putting the data of
main.js
into theglobal
object you resolve the circular dependency:main.js
depends on the functionality ofmy_class.js
main.js
depends on the data in theglobal
objectmy_class.js
depends on the data in theglobal
objectNow, to get rid of putting the data into the
global
object, implement a third module in let us saydata.js
. Then you require the sources like this:main.js
requiresdata.js
main.js
requiresmy_class.js
my_class.js
requiresdata.js
Since modules in node.js are singletons both
main.js
andmy_class.js
will get the same instance ofdata.js
.If I understood you correctly the possible solution:
main.js:
my_class.js:
So it's similar to your 3. option
If you want to make variables in main.js available anywhere, then you can assign properties to the
global
object. See node.js global variables? for example. It would work fine as long as you don't over do it. With Neo's solution, you gain a little more flexibility for example with testing, because you can "inject" an arbitrary object into the module. Not every module has to use the same "global" per se.