C++ – For nodejs what are best design practices for native modules which share dependencies

cdependenciesnode.js

Hypothetical situation, I have 3 node modules all native, A, B, and C. 

  • A is a utilities module which exposes several functions to javascript through the node interface, in addition it declares/defines a rich set of native structures and functions
  • B is a module which is dependent on data structures and source in A, it exposes some functions to javascript, in addition it declares/defines native structures and functions
  • C is a module which is dependent on data structures and source in A & B, it exploses some functions to javascript, in addition it declares/defines native structures and functions

So far when setting up these modules I have a preinstall script to install other dependent includes, but in order to access all of another modules source what is the best way to link to it's share library object (*.node) ?

Is there an alternative best practice for native modules (such as installing all source from other modules before building that single module)?
Reply

Best Answer

There are essentially two ways to do this. Which one is suitable for you depends on what you want to accomplish.

  1. Case 1: A, B and C are loosely related, that is if e.g. B can be used without A and C. Having A and/or C available would extend the functionality of B.

  2. Case 2: A, B and C are tightly related and some part of A, B or C relies on the existence of A, B or C. Together they form a logical unit.

If Case 1 fits your projects' purpose, then you want to build separate node modules and have the end user pull in those modules and use them at will.

If Case 2 fits better, then you want to compile A, B and C into one module e.g. ABC. You can still structure the source code (and exported API) of the ABC module according to A, B and C.

Building three separate modules and linking them dynamically makes little sense. In fact, they are dynamically linked (by node) when imported (require'd) in node-land. Linking them together statically might make more sense, bus is essentially just a messier way of accomplishing "solution 2" (producing a single module).

Edit:

If A, B and C are three modules that are not authored by you, then you are dealing with a hierarchy. As you explain it in your hypothesis, the hierarchy of dependance is:

B --requires--> A
C --requires--> B
C --requires--> A

Thus A could be "owned" by B, and B could be owned by C. If you author C, then provide a user-facing API with an entry-point in JavaScript, where you require the three modules. Compile A, B and C as separate modules and have them live "inside" your compound module. The file system structure could look something like this:

foo/          # Your compound module
foo/index.js  # require('./_A'), require('./_B'), require('./_C')
foo/_A.node
foo/_B.node
foo/_C.node

As the code in _C.node requires certain symbols to be implemented (i.e. the depending symbols from A and B), you will need to load the modules in order.

Note that I have not tested this, but in theory, this should work.

Related Topic