Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I document NodeJS native (V8) modules?

I have developed a native NodeJS module (using the NAN helpers). Now I am wondering what is the best way to document it.

The methods the module exports exist only in the C++ source code, however I wish to export Javascript documentation.

like image 543
Jozef Legény Avatar asked Oct 31 '22 14:10

Jozef Legény


1 Answers

EDIT: I found another way that I think is better:

All JSDoc needs is to be able to attach the doclet to SOMETHING, so you can actually just do this (if you ignore JSHint warning about expecting an assignment or call instead of expression):

var nativeStuff = require('some/native/stuff');

/**
 * My Cool Class
 * @class
 */
nativeStuff.MyCoolClass;

/**
 * My Cool Method
 * @function
 * @param {String} [name] The argument
 */
nativeStuff.MyCoolClass.prototype.CoolMethod;

/**
 * Some Other Value
 * @type {String}
 */
nativeStuff.someStringValue;

module.exports = nativeStuff;

This has the advantage of working with IDE's (at least WebStorm) and not requiring you to copy or proxy the object itself. Note though that you have to explicitly tell it what kind of field each entry is (with @function or @class or @type) because it can't infer it automatically otherwise.


Original Answer

There are a couple ways I know of, though I admit none seem particularly elegant.

In the small adapter file where you require() the native parts of the code and make it available as a module, you can assign each component individually and document them that way:

var nativeStuff = require('some/native/stuff');

// If your module only has one thing
/**
 * My Cool Class
 * @class MyCoolClass
 */
module.exports = nativeStuff;

// If it has several things
module.exports = {
    /**
     * My cool class
     * @class
     */
    MyCoolClass: nativeStuff.MyCoolClass,

    /**
     * My Other Cool Member
     */
    OtherCoolMember: nativeStuff.OtherCoolMember
};

You could document members of the class this way too if you want to pick apart the class and re-assemble it, but it gets kinda unwieldy the deeper you go.

The other way I know of is to wrap every class method in native JS, which comes with a (almost negligible) performance hit:

var nativeStuff = require('some/native/stuff');

/**
 * My Cool Class
 */
class MyCoolClass {

    constructor() {
        this._nativeObj = new nativeStuff.MyCoolClass();
    }

    /**
     * Some Cool Method
     * @param {String} [name] My name
     */
    coolMethod(name) {
        return this._nativeObj(name);
    }
}

module.exports = MyCoolClass;

(Note this also works in older JS versions, but ES6 classes make stuff way easier to understand visually :)

You also can try using the @typedef directive to define things since a doclet about a typedef can be separate from the object it describes, but I don't think typedef's can document methods or classes in general, they're just for data objects.

like image 122
PLavigne Avatar answered Nov 10 '22 12:11

PLavigne