NODE.JS JAVASCRIPT FRAMEWORK

Table of Contents

About this Documentation#

The goal of this documentation is to comprehensively explain the Node.js API, both from a reference as well as a conceptual point of view. Each section describes a built-in module or high-level concept.

Where appropriate, property types, method arguments, and the arguments provided to event handlers are detailed in a list underneath the topic heading.

Every .html document has a corresponding .json document presenting the same information in a structured manner. This feature is experimental, and added for the benefit of IDEs and other utilities that wish to do programmatic things with the documentation.

Every .html and .json file is generated based on the corresponding .markdown file in the doc/api/ folder in node's source tree. The documentation is generated using the tools/doc/generate.js program. The HTML template is located at doc/template.html.

Stability Index#

Throughout the documentation, you will see indications of a section's stability. The Node.js API is still somewhat changing, and as it matures, certain parts are more reliable than others. Some are so proven, and so relied upon, that they are unlikely to ever change at all. Others are brand new and experimental, or known to be hazardous and in the process of being redesigned.

The stability indices are as follows:

    Stability: 0 - Deprecated  This feature is known to be problematic, and changes are  planned.  Do not rely on it.  Use of the feature may cause warnings.  Backwards  compatibility should not be expected.
    Stability: 1 - Experimental  This feature was introduced recently, and may change  or be removed in future versions.  Please try it out and provide feedback.  If it addresses a use-case that is important to you, tell the node core team.
    Stability: 2 - Unstable  The API is in the process of settling, but has not yet had  sufficient real-world testing to be considered stable. Backwards-compatibility  will be maintained if reasonable.
    Stability: 3 - Stable  The API has proven satisfactory, but cleanup in the underlying  code may cause minor changes.  Backwards-compatibility is guaranteed.
    Stability: 4 - API Frozen  This API has been tested extensively in production and is  unlikely to ever have to change.
    Stability: 5 - Locked  Unless serious bugs are found, this code will not ever  change.  Please do not suggest changes in this area; they will be refused.

JSON Output#

    Stability: 1 - Experimental

Every HTML file in the markdown has a corresponding JSON file with the same data.

This feature is new as of node v0.6.12. It is experimental.

Synopsis#

An example of a web server written with Node which responds with 'Hello World':

    var http = require('http');    http.createServer(function (request, response) {    response.writeHead(200, {'Content-Type': 'text/plain'});    response.end('Hello World\n');  }).listen(8124);    console.log('Server running at http://127.0.0.1:8124/');

To run the server, put the code into a file called example.js and execute it with the node program

    > node example.js  Server running at http://127.0.0.1:8124/

All of the examples in the documentation can be run similarly.

Global Objects#

These objects are available in all modules. Some of these objects aren't actually in the global scope but in the module scope - this will be noted.

global#

  • {Object} The global namespace object.

In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node this is different. The top-level scope is not the global scope; var something inside a Node module will be local to that module.

process#

  • {Object}

The process object. See the process object section.

console#

  • {Object}

Used to print to stdout and stderr. See the console section.

Class: Buffer#

  • {Function}

Used to handle binary data. See the buffer section

require()#

  • {Function}

To require modules. See the Modules section. require isn't actually a global but rather local to each module.

require.resolve()#

Use the internal require() machinery to look up the location of a module, but rather than loading the module, just return the resolved filename.

require.cache#

  • Object

Modules are cached in this object when they are required. By deleting a key value from this object, the nextrequire will reload the module.

require.extensions#

    Stability: 0 - Deprecated
  • Object

Instruct require on how to handle certain file extensions.

Process files with the extension .sjs as .js:

    require.extensions['.sjs'] = require.extensions['.js'];

Deprecated In the past, this list has been used to load non-JavaScript modules into Node by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node program, or compiling them to JavaScript ahead of time.

Since the Module system is locked, this feature will probably never go away. However, it may have subtle bugs and complexities that are best left untouched.

__filename#

  • {String}

The filename of the code being executed. This is the resolved absolute path of this code file. For a main program this is not necessarily the same filename used in the command line. The value inside a module is the path to that module file.

Example: running node example.js from /Users/mjr

    console.log(__filename);  // /Users/mjr/example.js

__filename isn't actually a global but rather local to each module.

__dirname#

  • {String}

The name of the directory that the currently executing script resides in.

Example: running node example.js from /Users/mjr

    console.log(__dirname);  // /Users/mjr

__dirname isn't actually a global but rather local to each module.

module#

  • {Object}

A reference to the current module. In particular module.exports is used for defining what a module exports and makes available through require().

module isn't actually a global but rather local to each module.

See the module system documentation for more information.

exports#

A reference to the module.exports that is shorter to type. See module system documentation for details on when to use exports and when to use module.exports.

exports isn't actually a global but rather local to each module.

See the module system documentation for more information.

See the module section for more information.

setTimeout(cb, ms)#

Run callback cb after at least ms milliseconds. The actual delay depends on external factors like OS timer granularity and system load.

The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days.

Returns an opaque value that represents the timer.

clearTimeout(t)#

Stop a timer that was previously created with setTimeout(). The callback will not execute.

setInterval(cb, ms)#

Run callback cb repeatedly every ms milliseconds. Note that the actual interval may vary, depending on external factors like OS timer granularity and system load. It's never less than ms but it may be longer.

The interval must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days.

Returns an opaque value that represents the timer.

clearInterval(t)#

Stop a timer that was previously created with setInterval(). The callback will not execute.

The timer functions are global variables. See the timers section.

console#

    Stability: 4 - API Frozen
  • Object

For printing to stdout and stderr. Similar to the console object functions provided by most web browsers, here the output is sent to stdout or stderr.

The console functions are synchronous when the destination is a terminal or a file (to avoid lost messages in case of premature exit) and asynchronous when it's a pipe (to avoid blocking for long periods of time).

That is, in the following example, stdout is non-blocking while stderr is blocking:

    $ node script.js 2> error.log | tee info.log

In daily use, the blocking/non-blocking dichotomy is not something you should worry about unless you log huge amounts of data.

console.log([data], [...])#

Prints to stdout with newline. This function can take multiple arguments in a printf()-like way. Example:

    console.log('count: %d', count);

If formatting elements are not found in the first string then util.inspect is used on each argument. Seeutil.format() for more information.

console.info([data], [...])#

Same as console.log.

console.error([data], [...])#

Same as console.log but prints to stderr.

console.warn([data], [...])#

Same as console.error.

console.dir(obj)#

Uses util.inspect on obj and prints resulting string to stdout.

console.time(label)#

Mark a time.

console.timeEnd(label)#

Finish timer, record output. Example:

    console.time('100-elements');  for (var i = 0; i < 100; i++) {    ;  }  console.timeEnd('100-elements');

console.trace(label)#

Print a stack trace to stderr of the current position.

console.assert(expression, [message])#

Same as assert.ok() where if the expression evaluates as false throw an AssertionError with message.

Timers#

    Stability: 5 - Locked

All of the timer functions are globals. You do not need to require() this module in order to use them.

setTimeout(callback, delay, [arg], [...])#

To schedule execution of a one-time callback after delay milliseconds. Returns a timeoutId for possible use with clearTimeout(). Optionally you can also pass arguments to the callback.

It is important to note that your callback will probably not be called in exactly delay milliseconds - Node.js makes no guarantees about the exact timing of when the callback will fire, nor of the ordering things will fire in. The callback will be called as close as possible to the time specified.

clearTimeout(timeoutId)#

Prevents a timeout from triggering.

setInterval(callback, delay, [arg], [...])#

To schedule the repeated execution of callback every delay milliseconds. Returns a intervalId for possible use with clearInterval(). Optionally you can also pass arguments to the callback.

clearInterval(intervalId)#

Stops a interval from triggering.

unref()#

The opaque value returned by setTimeout and setInterval also has the method timer.unref() which will allow you to create a timer that is active but if it is the only item left in the event loop won't keep the program running. If the timer is already unrefd calling unref again will have no effect.

In the case of setTimeout when you unref you create a separate timer that will wakeup the event loop, creating too many of these may adversely effect event loop performance -- use wisely.

ref()#

If you had previously unref()d a timer you can call ref() to explicitly request the timer hold the program open. If the timer is already refd calling ref again will have no effect.

setImmediate(callback, [arg], [...])#

To schedule the "immediate" execution of callback after I/O events callbacks and before setTimeout andsetInterval . Returns an immediateId for possible use with clearImmediate(). Optionally you can also pass arguments to the callback.

Immediates are queued in the order created, and are popped off the queue once per loop iteration. This is different from process.nextTick which will execute process.maxTickDepth queued callbacks per iteration.setImmediate will yield to the event loop after firing a queued callback to make sure I/O is not being starved. While order is preserved for execution, other I/O events may fire between any two scheduled immediate callbacks.

clearImmediate(immediateId)#

Stops an immediate from triggering.

Modules#

    Stability: 5 - Locked

Node has a simple module loading system. In Node, files and modules are in one-to-one correspondence. As an example, foo.js loads the module circle.js in the same directory.

The contents of foo.js:

    var circle = require('./circle.js');  console.log( 'The area of a circle of radius 4 is '             + circle.area(4));

The contents of circle.js:

    var PI = Math.PI;    exports.area = function (r) {    return PI * r * r;  };    exports.circumference = function (r) {    return 2 * PI * r;  };

The module circle.js has exported the functions area() and circumference(). To add functions and objects to the root of your module, you can add them to the special exports object.

Variables local to the module will be private, as though the module was wrapped in a function. In this example the variable PI is private to circle.js.

If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exportsinstead of exports.

Below, bar.js makes use of the square module, which exports a constructor:

    var square = require('./square.js');  var mySquare = square(2);  console.log('The area of my square is ' + mySquare.area());

The square module is defined in square.js:

    // assigning to exports will not modify module, must use module.exports  module.exports = function(width) {    return {      area: function() {        return width * width;      }    };  }

The module system is implemented in the require("module") module.

Cycles#

When there are circular require() calls, a module might not be done being executed when it is returned.

Consider this situation:

a.js:

    console.log('a starting');  exports.done = false;  var b = require('./b.js');  console.log('in a, b.done = %j', b.done);  exports.done = true;  console.log('a done');

b.js:

    console.log('b starting');  exports.done = false;  var a = require('./a.js');  console.log('in b, a.done = %j', a.done);  exports.done = true;  console.log('b done');

main.js:

    console.log('main starting');  var a = require('./a.js');  var b = require('./b.js');  console.log('in main, a.done=%j, b.done=%j', a.done, b.done);

When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop an unfinished copy of the a.js exports object is returned to the b.js module. b.jsthen finishes loading, and its exports object is provided to the a.js module.

By the time main.js has loaded both modules, they're both finished. The output of this program would thus be:

    $ node main.js  main starting  a starting  b starting  in b, a.done = false  b done  in a, b.done = true  a done  in main, a.done=true, b.done=true

If you have cyclic module dependencies in your program, make sure to plan accordingly.

Core Modules#

Node has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation.

The core modules are defined in node's source in the lib/ folder.

Core modules are always preferentially loaded if their identifier is passed to require(). For instance,require('http') will always return the built in HTTP module, even if there is a file by that name.

File Modules#

If the exact filename is not found, then node will attempt to load the required filename with the added extension of .js.json, and then .node.

.js files are interpreted as JavaScript text files, and .json files are parsed as JSON text files. .node files are interpreted as compiled addon modules loaded with dlopen.

A module prefixed with '/' is an absolute path to the file. For example, require('/home/marco/foo.js')will load the file at /home/marco/foo.js.

A module prefixed with './' is relative to the file calling require(). That is, circle.js must be in the same directory as foo.js for require('./circle') to find it.

Without a leading '/' or './' to indicate a file, the module is either a "core module" or is loaded from anode_modules folder.

If the given path does not exist, require() will throw an Error with its code property set to'MODULE_NOT_FOUND'.

Loading from node_modules Folders#

If the module identifier passed to require() is not a native module, and does not begin with '/''../', or'./', then node starts at the parent directory of the current module, and adds /node_modules, and attempts to load the module from that location.

If it is not found there, then it moves to the parent directory, and so on, until the root of the tree is reached.

For example, if the file at '/home/ry/projects/foo.js' called require('bar.js'), then node would look in the following locations, in this order:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

This allows programs to localize their dependencies, so that they do not clash.

Folders as Modules#

It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to that library. There are three ways in which a folder may be passed to require() as an argument.

The first is to create a package.json file in the root of the folder, which specifies a main module. An example package.json file might look like this:

    { "name" : "some-library",    "main" : "./lib/some-library.js" }

If this was in a folder at ./some-library, then require('./some-library') would attempt to load ./some-library/lib/some-library.js.

This is the extent of Node's awareness of package.json files.

If there is no package.json file present in the directory, then node will attempt to load an index.js orindex.node file out of that directory. For example, if there was no package.json file in the above example, thenrequire('./some-library') would attempt to load:

  • ./some-library/index.js
  • ./some-library/index.node

Caching#

Modules are cached after the first time they are loaded. This means (among other things) that every call torequire('foo') will get exactly the same object returned, if it would resolve to the same file.

Multiple calls to require('foo') may not cause the module code to be executed multiple times. This is an important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.

If you want to have a module execute code multiple times, then export a function, and call that function.

Module Caching Caveats#

Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee thatrequire('foo') will always return the exact same object, if it would resolve to different files.

The module Object#

  • {Object}

In each module, the module free variable is a reference to the object representing the current module. For convenience, module.exports is also accessible via the exports module-global. module isn't actually a global but rather local to each module.

module.exports#

  • Object

The module.exports object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this assign the desired export object to module.exports. Note that assigning the desired object to exports will simply rebind the local exports variable, which is probably not what you want to do.

For example suppose we were making a module called a.js

    var EventEmitter = require('events').EventEmitter;    module.exports = new EventEmitter();    // Do some work, and after some time emit  // the 'ready' event from the module itself.  setTimeout(function() {    module.exports.emit('ready');  }, 1000);

Then in another file we could do

    var a = require('./a');  a.on('ready', function() {    console.log('module a is ready');  });

Note that assignment to module.exports must be done immediately. It cannot be done in any callbacks. This does not work:

x.js:

    setTimeout(function() {    module.exports = { a: "hello" };  }, 0);

y.js:

    var x = require('./x');  console.log(x.a);

exports alias#

The exports variable that is available within a module starts as a reference to module.exports. As with any variable, if you assign a new value to it, it is no longer bound to the previous value.

To illustrate the behaviour, imagine this hypothetical implementation of require():

    function require(...) {    // ...    function (module, exports) {      // Your module code here      exports = some_func;        // re-assigns exports, exports is no longer                                  // a shortcut, and nothing is exported.      module.exports = some_func; // makes your module export 0    } (module, module.exports);    return module;  }

As a guideline, if the relationship between exports and module.exports seems like magic to you, ignoreexports and only use module.exports.

module.require(id)#

  • id String
  • Return: Object module.exports from the resolved module

The module.require method provides a way to load a module as if require() was called from the original module.

Note that in order to do this, you must get a reference to the module object. Since require() returns themodule.exports, and the module is typically only available within a specific module's code, it must be explicitly exported in order to be used.

module.id#

  • String

The identifier for the module. Typically this is the fully resolved filename.

module.filename#

  • String

The fully resolved filename to the module.

module.loaded#

  • Boolean

Whether or not the module is done loading, or is in the process of loading.

module.parent#

  • Module Object

The module that required this one.

module.children#

  • Array

The module objects required by this one.

All Together...#

To get the exact filename that will be loaded when require() is called, use the require.resolve() function.

Putting together all of the above, here is the high-level algorithm in pseudocode of what require.resolve does:

    require(X) from module at path Y  1. If X is a core module,     a. return the core module     b. STOP  2. If X begins with './' or '/' or '../'     a. LOAD_AS_FILE(Y + X)     b. LOAD_AS_DIRECTORY(Y + X)  3. LOAD_NODE_MODULES(X, dirname(Y))  4. THROW "not found"    LOAD_AS_FILE(X)  1. If X is a file, load X as JavaScript text.  STOP  2. If X.js is a file, load X.js as JavaScript text.  STOP  3. If X.node is a file, load X.node as binary addon.  STOP    LOAD_AS_DIRECTORY(X)  1. If X/package.json is a file,     a. Parse X/package.json, and look for "main" field.     b. let M = X + (json main field)     c. LOAD_AS_FILE(M)  2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP  3. If X/index.node is a file, load X/index.node as binary addon.  STOP    LOAD_NODE_MODULES(X, START)  1. let DIRS=NODE_MODULES_PATHS(START)  2. for each DIR in DIRS:     a. LOAD_AS_FILE(DIR/X)     b. LOAD_AS_DIRECTORY(DIR/X)    NODE_MODULES_PATHS(START)  1. let PARTS = path split(START)  2. let ROOT = index of first instance of "node_modules" in PARTS, or 0  3. let I = count of PARTS - 1  4. let DIRS = []  5. while I > ROOT,     a. if PARTS[I] = "node_modules" CONTINUE     c. DIR = path join(PARTS[0 .. I] + "node_modules")     b. DIRS = DIRS + DIR     c. let I = I - 1  6. return DIRS

Loading from the global folders#

If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then node will search those paths for modules if they are not found elsewhere. (Note: On Windows, NODE_PATH is delimited by semicolons instead of colons.)

Additionally, node will search in the following locations:

  • 1: $HOME/.node_modules
  • 2: $HOME/.node_libraries
  • 3: $PREFIX/lib/node

Where $HOME is the user's home directory, and $PREFIX is node's configured node_prefix.

These are mostly for historic reasons. You are highly encouraged to place your dependencies locally innode_modules folders. They will be loaded faster, and more reliably.

Accessing the main module#

When a file is run directly from Node, require.main is set to its module. That means that you can determine whether a file has been run directly by testing

    require.main === module

For a file foo.js, this will be true if run via node foo.js, but false if run by require('./foo').

Because module provides a filename property (normally equivalent to __filename), the entry point of the current application can be obtained by checking require.main.filename.

Addenda: Package Manager Tips#

The semantics of Node's require() function were designed to be general enough to support a number of sane directory structures. Package manager programs such as dpkgrpm, and npm will hopefully find it possible to build native packages from Node modules without modification.

Below we give a suggested directory structure that could work:

Let's say that we wanted to have the folder at /usr/lib/node/<some-package>/<some-version> hold the contents of a specific version of a package.

Packages can depend on one another. In order to install package foo, you may have to install a specific version of package bar. The bar package may itself have dependencies, and in some cases, these dependencies may even collide or form cycles.

Since Node looks up the realpath of any modules it loads (that is, resolves symlinks), and then looks for their dependencies in the node_modules folders as described above, this situation is very simple to resolve with the following architecture:

  • /usr/lib/node/foo/1.2.3/ - Contents of the foo package, version 1.2.3.
  • /usr/lib/node/bar/4.3.2/ - Contents of the bar package that foo depends on.
  • /usr/lib/node/foo/1.2.3/node_modules/bar - Symbolic link to /usr/lib/node/bar/4.3.2/.
  • /usr/lib/node/bar/4.3.2/node_modules/* - Symbolic links to the packages that bar depends on.

Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use.

When the code in the foo package does require('bar'), it will get the version that is symlinked into/usr/lib/node/foo/1.2.3/node_modules/bar. Then, when the code in the bar package callsrequire('quux'), it'll get the version that is symlinked into /usr/lib/node/bar/4.3.2/node_modules/quux.

Furthermore, to make the module lookup process even more optimal, rather than putting packages directly in/usr/lib/node, we could put them in /usr/lib/node_modules/<name>/<version>. Then node will not bother looking for missing dependencies in /usr/node_modules or /node_modules.

In order to make modules available to the node REPL, it might be useful to also add the/usr/lib/node_modules folder to the $NODE_PATH environment variable. Since the module lookups usingnode_modules folders are all relative, and based on the real path of the files making the calls to require(), the packages themselves can be anywhere.

Addons#

Addons are dynamically linked shared objects. They can provide glue to C and C++ libraries. The API (at the moment) is rather complex, involving knowledge of several libraries:

  • V8 JavaScript, a C++ library. Used for interfacing with JavaScript: creating objects, calling functions, etc. Documented mostly in the v8.h header file (deps/v8/include/v8.h in the Node source tree), which is also available online.

  • libuv, C event loop library. Anytime one needs to wait for a file descriptor to become readable, wait for a timer, or wait for a signal to be received one will need to interface with libuv. That is, if you perform any I/O, libuv will need to be used.

  • Internal Node libraries. Most importantly is the node::ObjectWrap class which you will likely want to derive from.

  • Others. Look in deps/ for what else is available.

Node statically compiles all its dependencies into the executable. When compiling your module, you don't need to worry about linking to any of these libraries.

All of the following examples are available for download and may be used as a starting-point for your own Addon.

Hello world#

To get started let's make a small Addon which is the C++ equivalent of the following JavaScript code:

    module.exports.hello = function() { return 'world'; };

First we create a file hello.cc:

    #include <node.h>  #include <v8.h>    using namespace v8;    Handle<Value> Method(const Arguments& args) {    HandleScope scope;    return scope.Close(String::New("world"));  }    void init(Handle<Object> exports) {    exports->Set(String::NewSymbol("hello"),        FunctionTemplate::New(Method)->GetFunction());  }    NODE_MODULE(hello, init)

Note that all Node addons must export an initialization function:

    void Initialize (Handle<Object> exports);  NODE_MODULE(module_name, Initialize)

There is no semi-colon after NODE_MODULE as it's not a function (see node.h).

The module_name needs to match the filename of the final binary (minus the .node suffix).

The source code needs to be built into hello.node, the binary Addon. To do this we create a file calledbinding.gyp which describes the configuration to build your module in a JSON-like format. This file gets compiled by node-gyp.

    {    "targets": [      {        "target_name": "hello",        "sources": [ "hello.cc" ]      }    ]  }

The next step is to generate the appropriate project build files for the current platform. Use node-gyp configure for that.

Now you will have either a Makefile (on Unix platforms) or a vcxproj file (on Windows) in the build/directory. Next invoke the node-gyp build command.

Now you have your compiled .node bindings file! The compiled bindings end up in build/Release/.

You can now use the binary addon in a Node project hello.js by pointing require to the recently builthello.node module:

    var addon = require('./build/Release/hello');    console.log(addon.hello()); // 'world'

Please see patterns below for further information or

https://github.com/arturadib/node-qt for an example in production.

Addon patterns#

Below are some addon patterns to help you get started. Consult the online v8 reference for help with the various v8 calls, and v8's Embedder's Guide for an explanation of several concepts used such as handles, scopes, function templates, etc.

In order to use these examples you need to compile them using node-gyp. Create the following binding.gypfile:

    {    "targets": [      {        "target_name": "addon",        "sources": [ "addon.cc" ]      }    ]  }

In cases where there is more than one .cc file, simply add the file name to the sources array, e.g.:

    "sources": ["addon.cc", "myexample.cc"]

Now that you have your binding.gyp ready, you can configure and build the addon:

    $ node-gyp configure build

Function arguments#

The following pattern illustrates how to read arguments from JavaScript function calls and return a result. This is the main and only needed source addon.cc:

    #define BUILDING_NODE_EXTENSION  #include <node.h>    using namespace v8;    Handle<Value> Add(const Arguments& args) {    HandleScope scope;      if (args.Length() < 2) {      ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));      return scope.Close(Undefined());    }      if (!args[0]->IsNumber() || !args[1]->IsNumber()) {      ThrowException(Exception::TypeError(String::New("Wrong arguments")));      return scope.Close(Undefined());    }      Local<Number> num = Number::New(args[0]->NumberValue() +        args[1]->NumberValue());    return scope.Close(num);  }    void Init(Handle<Object> exports) {    exports->Set(String::NewSymbol("add"),        FunctionTemplate::New(Add)->GetFunction());  }    NODE_MODULE(addon, Init)

You can test it with the following JavaScript snippet:

    var addon = require('./build/Release/addon');    console.log( 'This should be eight:', addon.add(3,5) );

Callbacks#

You can pass JavaScript functions to a C++ function and execute them from there. Here's addon.cc:

    #define BUILDING_NODE_EXTENSION  #include <node.h>    using namespace v8;    Handle<Value> RunCallback(const Arguments& args) {    HandleScope scope;      Local<Function> cb = Local<Function>::Cast(args[0]);    const unsigned argc = 1;    Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };    cb->Call(Context::GetCurrent()->Global(), argc, argv);      return scope.Close(Undefined());  }    void Init(Handle<Object> exports, Handle<Object> module) {    module->Set(String::NewSymbol("exports"),        FunctionTemplate::New(RunCallback)->GetFunction());  }    NODE_MODULE(addon, Init)

Note that this example uses a two-argument form of Init() that receives the full module object as the second argument. This allows the addon to completely overwrite exports with a single function instead of adding the function as a property of exports.

To test it run the following JavaScript snippet:

    var addon = require('./build/Release/addon');    addon(function(msg){    console.log(msg); // 'hello world'  });

Object factory#

You can create and return new objects from within a C++ function with this addon.cc pattern, which returns an object with property msg that echoes the string passed to createObject():

    #define BUILDING_NODE_EXTENSION  #include <node.h>    using namespace v8;    Handle<Value> CreateObject(const Arguments& args) {    HandleScope scope;      Local<Object> obj = Object::New();    obj->Set(String::NewSymbol("msg"), args[0]->ToString());      return scope.Close(obj);  }    void Init(Handle<Object> exports, Handle<Object> module) {    module->Set(String::NewSymbol("exports"),        FunctionTemplate::New(CreateObject)->GetFunction());  }    NODE_MODULE(addon, Init)

To test it in JavaScript:

    var addon = require('./build/Release/addon');    var obj1 = addon('hello');  var obj2 = addon('world');  console.log(obj1.msg+' '+obj2.msg); // 'hello world'

Function factory#

This pattern illustrates how to create and return a JavaScript function that wraps a C++ function:

    #define BUILDING_NODE_EXTENSION  #include <node.h>    using namespace v8;    Handle<Value> MyFunction(const Arguments& args) {    HandleScope scope;    return scope.Close(String::New("hello world"));  }    Handle<Value> CreateFunction(const Arguments& args) {    HandleScope scope;      Local<FunctionTemplate> tpl = FunctionTemplate::New(MyFunction);    Local<Function> fn = tpl->GetFunction();    fn->SetName(String::NewSymbol("theFunction")); // omit this to make it anonymous      return scope.Close(fn);  }    void Init(Handle<Object> exports, Handle<Object> module) {    module->Set(String::NewSymbol("exports"),        FunctionTemplate::New(CreateFunction)->GetFunction());  }    NODE_MODULE(addon, Init)

To test:

    var addon = require('./build/Release/addon');    var fn = addon();  console.log(fn()); // 'hello world'

Wrapping C++ objects#

Here we will create a wrapper for a C++ object/class MyObject that can be instantiated in JavaScript through the new operator. First prepare the main module addon.cc:

    #define BUILDING_NODE_EXTENSION  #include <node.h>  #include "myobject.h"    using namespace v8;    void InitAll(Handle<Object> exports) {    MyObject::Init(exports);  }    NODE_MODULE(addon, InitAll)

Then in myobject.h make your wrapper inherit from node::ObjectWrap:

    #ifndef MYOBJECT_H  #define MYOBJECT_H    #include <node.h>    class MyObject : public node::ObjectWrap {   public:    static void Init(v8::Handle<v8::Object> exports);     private:    explicit MyObject(double value = 0);    ~MyObject();      static v8::Handle<v8::Value> New(const v8::Arguments& args);    static v8::Handle<v8::Value> PlusOne(const v8::Arguments& args);    static v8::Persistent<v8::Function> constructor;    double value_;  };    

Comments

Popular posts from this blog

Generate a Report using Crystal Reports in Visual Studio 2010

SQL Server Database is enabled for Database Mirroring, but the database lacks quorum, and cannot be opened – Error 955

40 Cool Kitchen Gadgets For Food Lovers. I’d Love To Have #14!