The Fundamentals of the Node.js Module Paradigm?

前端 未结 1 709
猫巷女王i
猫巷女王i 2021-01-23 03:49

I am struggling to really get a grasp on some fundamental basics here, and I feel it is not only holding me back, but resulting in crappy code and I don\'t like that.

I

1条回答
  •  抹茶落季
    2021-01-23 03:56

    Each node module is simply an object. The part of that object which is available to the outside world is the module.exports object which contains properties which can be functions or data.

    The require("xxx") command gets you the exports object for that module (from a central cache or loads it from the .js file is it hasn't yet been loaded).

    So, code sharing is simple. Just have each module do a require() on any other modules that it wants to share code from and have those modules make sure the shared functions are accessible via it's own exports object. This allows each module to essentially be stand-alone. It loads any other code that it needs and makes it a lot easier to reuse code. Modules are cached so doing lots of require() operations on the same module from lots of other modules is nothing more than a cache lookup and is not something to worry about.

    Data sharing (such as your app object) can be accomplished in several different ways. The most common way is when you load the module to just call some sort of initialization function for the module and pass it any data that it might need. That would be the push model. Or, you can also do the pull model where a module asks another module for some piece of data.

    All of this is a lot easier with the right code organization. If you start to feel like you have a spaghetti or interdependence, then perhaps you don't have the right code organization or you're just a bit too shy on just using require() to pull in everything a given module needs. Remember each module will load whatever it needs itself so you only have to worry about what you need. Load those modules and they will load what they need.

    You may also want to think more in terms of objects so you put most properties on some sort of object rather than lots of loose, individually shared variables. You can then share a single object and it automatically makes all the properties of that variable available to whomever you shared it with.


    As to your question about sharing the app object with another module, you can do that like this:

    // in your app module
    var express = require('express');
    var app = express();
    
    var otherModule = require('otherModule');
    otherModule.setApp(app);
    // now otherModule has the singleton `app` object that it can use
    // in this case, otherModule must be initialized this way before it can do its job
    

    In this example, I just used a single method .setApp() to set the app object. That means all the other methods are available for other access into that module.


    This could have also been done with a constructor-like method:

    // in your app module
    var express = require('express');
    var app = express();
    
    var otherModule = require('otherModule')(app);
    

    This works also because the constructor can then return an object with other methods on it if you want. If you want to be able to get access to otherModule from within other modules, but obviously you only want to initialize it just once and not in those other places, then you can either do this:

    var otherModule = require('otherModule')();
    

    from those other modules and have the constructor just check that if nothing is passed to it, then it is not getting the app object from this constructor call so it should just return an object with other methods. Or, you can use the first code block above that returns all the methods from the initial require(). You're totally free to decide what to return from the require(). It can be just a constructor-like function which then returns another object when it is called. It can be just an object that has methods on it or (because functions are objects that can also have properties), you can even return a constructor-like function that ALSO has methods on it (though this is a bit less standard way of doing things).

    And, your constructor function can decide what to do based on what is passed to it, given it a multitude of different behaviors based on what you pass to it.

    0 讨论(0)
提交回复
热议问题