How to correctly modularize a node.js project?

偶尔善良 提交于 2019-12-13 01:15:58

问题


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:

  1. I define my classes inside main.js. They'll have access to main.js's globals for being on it's closure, but main.js will become bloated.

  2. I move the class to another file such as my_class.js and require() it. This doesn't work because my_class's instances will lose the closure context and no longer be able to access main.js's globals.

  3. 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 of my_class.

  4. I move the class to another file and require it using my_class = eval(fs.readFileSync(()) instead of require. This works just fine as my_class gets main.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?


回答1:


Your problem seems tricky because you have a circular dependency: main.js depends on the functionality of my_class and my_class depends on the data of main.js.

By putting the data of main.js into the global object you resolve the circular dependency:

  • main.js depends on the functionality of my_class.js
  • main.js depends on the data in the global object
  • my_class.js depends on the data in the global object

Now, to get rid of putting the data into the global object, implement a third module in let us say data.js. Then you require the sources like this:

  • main.js requires data.js
  • main.js requires my_class.js
  • my_class.js requires data.js

Since modules in node.js are singletons both main.js and my_class.js will get the same instance of data.js.




回答2:


If I understood you correctly the possible solution:

main.js:

(function(){
  var global = "test"; // this you wanna have as a closure

  var my_class = require('./my_class')(global);
  my_class.go();
})();

my_class.js:

module.exports = function(global){
  return {
    go: function(){
      console.log(global);
    }
  };
};

So it's similar to your 3. option




回答3:


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.



来源:https://stackoverflow.com/questions/16233819/how-to-correctly-modularize-a-node-js-project

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!