-1

I want to understand how HAP-Node.js works, but I cannot follow the Node.js code. I'm very new to Node.js, but not new to programming.

In this example below (which is the HAP-NodeJS project and can be found on GitHub) I cannot understand how the execution starts. I think the require functions at the top return only the exported object from the modules, but nothing in the require()’ed modules gets executed. Then I also see that the index.js file has nothing that appears to actually execute either. It appears to only define an object and init function that is called from some mystery caller.

As a comparison, in a C or Java program, there is an entry point function Main() that get called to start everything off. How does the “flow” work in this Node.js project? What can I look for to gain understanding of this? Is there some kind of Node.js preprocessor you can put all the code in to see it as a whole?

Please don’t take this question down to recommend I post it on GitHub because I truly think I’m asking a Node.js general question.

var Accessory = require('./lib/Accessory.js').Accessory;
var Bridge = require('./lib/Bridge.js').Bridge;
var Camera = require('./lib/Camera.js').Camera;
var Service = require('./lib/Service.js').Service;
var Characteristic = require('./lib/Characteristic.js').Characteristic;
var uuid = require('./lib/util/uuid');
var AccessoryLoader = require('./lib/AccessoryLoader.js');
var StreamController = require('./lib/StreamController.js').StreamController;
var storage = require('node-persist');

// ensure Characteristic subclasses are defined
var HomeKitTypes = require('./lib/gen/HomeKitTypes');

module.exports = {
  init: init,
  Accessory: Accessory,
  Bridge: Bridge,
  Camera: Camera,
  Service: Service,
  Characteristic: Characteristic,
  uuid: uuid,
  AccessoryLoader: AccessoryLoader,
  StreamController: StreamController
}

function init(storagePath) {
  // initialize our underlying storage system, passing on the directory if needed
  if (typeof storagePath !== 'undefined')
    storage.initSync({ dir: storagePath });
  else
    storage.initSync(); // use whatever is default
}
bwjohns4
  • 21
  • 2
  • `but nothing in the require()’ed modules gets executed` incorrect, the module gets executed, otherwise there would be no way to know what the module exports. `Then I also see that the index.js file has nothing that appears to actually execute either. It appears to only define an object and init function that is called from some mystery caller.` i assume that's related to the command you are using to start the server. This setup isn't typical. Something is calling `init`, it's not something built-in to node. – Kevin B Jan 23 '18 at 20:55

1 Answers1

1

In Node.js, as all JavaScript, the flow is always top-to-bottom. There is no main() or similar as there are in other languages.

With Node.js in particular, the first file to run is the one you run directly (usually named index.js by convention, but not required).

node index.js

Since node will automatically run an index.js file if you give it a folder name, you can also do it like this:

node myApp

which would run myApp/index.js.

When I fire it up, that file will be read and run top-to-bottom. As I hit things like require, it'll then pause to read those files from top-to-bottom as well.

Most requires will export an object or objects, so they won't "do" anything immediately.

But not all. I could just as easily have a require which will just run code (this is common of code like polyfills, which override global objects upon inclusion).

In the particular example above, you are correct that that file does not do anything on it's own. That file itself is also just exporting something (with module.exports).

That would mean running that file directly with node wouldn't really do anything. Instead, there is likely some other file which is pulling in that file and calling that init() function to kick things off. Probably something like this:

const setup = require('./setup.js'); // the file you have

setup.init(); // kick things off

Then, if I named that file index.js, I could kick the whole thing off with:

node index.js
samanime
  • 25,408
  • 15
  • 90
  • 139
  • I did not do the downvote. Thanks for your answer! If you require() a module and after the module.exports = {} there is just a console.log(); somewhere, will that actually execute? I guess I'm asking if it compiles/runs the entire module, then returns the exports to the calling function. Or does it just "compile" (I know it's a JIT VM kind of thing) it and return the exports? – bwjohns4 Jan 23 '18 at 21:38
  • It basically "returns" the `module.exports` after the file is done executing. You'll sometimes see the `module.exports` near the top, and then they modify it throughout. It essentially gets returned when it's done running the available code. – samanime Jan 23 '18 at 21:49