I am still lost after reading the how-to article.
It is said that
The load callback is a Duktape/C function which takes the resolved module ID and: (1) returns the Ecmascript source code for the module or undefined if there's no source code, e.g. for pure C modules, (2) can populate module.exports itself, and (3) can replace module.exports.
But when loading a native C module,
duk_push_undefined(ctx) instead of duk_push_string(ctx, module_source)? return 0 instead of return 1? I tried to call myobject_init (using the default instance in http://wiki.duktape.org/HowtoNativeConstructor.html) in the load callback cb_load_module. But duktape complains
TypeError: [object Object] not constructable
when I evaluate var MyObject = require("MyObject"), no matter if I
Problem solved. There are a few more details scattered in
The most important tricks are:
The module init function should return a function (constructor is also a function). Do NOT register the function using duk_put_global_string.
duk_ret_t module_init(duk_context* ctx)
{
duk_push_c_function(ctx, module_constructor, num_arguments_for_constructor);
// set properties for the constructor
return 1; // stack: [ ... constructor ]
}
The function cb_load_module must push the module init function into the value stack, then use duk_call to call it and set module.exports. Do NOT call the module init function directly.
duk_ret_t cb_load_module(duk_context *ctx)
{
// stack: [ resolved_id exports module ]
...
duk_push_c_function(ctx, module_init, 0);
duk_call(ctx, 0);
duk_put_prop_string(ctx, 2, "exports"); // obj_idx(module) = 2
return 0; // no .js source for native modules
}