Table of Contents
- About this Documentation
- Synopsis
- Global Objects
- console
- Timers
- Modules
- Addons
- process
- Event: 'exit'
- Event: 'uncaughtException'
- Signal Events
- process.stdout
- process.stderr
- process.stdin
- process.argv
- process.execPath
- process.execArgv
- process.abort()
- process.chdir(directory)
- process.cwd()
- process.env
- process.exit([code])
- process.getgid()
- process.setgid(id)
- process.getuid()
- process.setuid(id)
- process.getgroups()
- process.setgroups(groups)
- process.initgroups(user, extra_group)
- process.version
- process.versions
- process.config
- process.kill(pid, [signal])
- process.pid
- process.title
- process.arch
- process.platform
- process.memoryUsage()
- process.nextTick(callback)
- process.maxTickDepth
- process.umask([mask])
- process.uptime()
- process.hrtime()
- util
- util.format(format, [...])
- util.debug(string)
- util.error([...])
- util.puts([...])
- util.print([...])
- util.log(string)
- util.inspect(object, [options])
- util.isArray(object)
- util.isRegExp(object)
- util.isDate(object)
- util.isError(object)
- util.pump(readableStream, writableStream, [callback])
- util.inherits(constructor, superConstructor)
- Events
- Class: events.EventEmitter
- emitter.addListener(event, listener)
- emitter.on(event, listener)
- emitter.once(event, listener)
- emitter.removeListener(event, listener)
- emitter.removeAllListeners([event])
- emitter.setMaxListeners(n)
- emitter.listeners(event)
- emitter.emit(event, [arg1], [arg2], [...])
- Class Method: EventEmitter.listenerCount(emitter, event)
- Event: 'newListener'
- Event: 'removeListener'
- Class: events.EventEmitter
- Domain
- Buffer
- Class: Buffer
- new Buffer(size)
- new Buffer(array)
- new Buffer(str, [encoding])
- Class Method: Buffer.isEncoding(encoding)
- buf.write(string, [offset], [length], [encoding])
- buf.toString([encoding], [start], [end])
- buf.toJSON()
- buf[index]
- Class Method: Buffer.isBuffer(obj)
- Class Method: Buffer.byteLength(string, [encoding])
- Class Method: Buffer.concat(list, [totalLength])
- buf.length
- buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd])
- buf.slice([start], [end])
- buf.readUInt8(offset, [noAssert])
- buf.readUInt16LE(offset, [noAssert])
- buf.readUInt16BE(offset, [noAssert])
- buf.readUInt32LE(offset, [noAssert])
- buf.readUInt32BE(offset, [noAssert])
- buf.readInt8(offset, [noAssert])
- buf.readInt16LE(offset, [noAssert])
- buf.readInt16BE(offset, [noAssert])
- buf.readInt32LE(offset, [noAssert])
- buf.readInt32BE(offset, [noAssert])
- buf.readFloatLE(offset, [noAssert])
- buf.readFloatBE(offset, [noAssert])
- buf.readDoubleLE(offset, [noAssert])
- buf.readDoubleBE(offset, [noAssert])
- buf.writeUInt8(value, offset, [noAssert])
- buf.writeUInt16LE(value, offset, [noAssert])
- buf.writeUInt16BE(value, offset, [noAssert])
- buf.writeUInt32LE(value, offset, [noAssert])
- buf.writeUInt32BE(value, offset, [noAssert])
- buf.writeInt8(value, offset, [noAssert])
- buf.writeInt16LE(value, offset, [noAssert])
- buf.writeInt16BE(value, offset, [noAssert])
- buf.writeInt32LE(value, offset, [noAssert])
- buf.writeInt32BE(value, offset, [noAssert])
- buf.writeFloatLE(value, offset, [noAssert])
- buf.writeFloatBE(value, offset, [noAssert])
- buf.writeDoubleLE(value, offset, [noAssert])
- buf.writeDoubleBE(value, offset, [noAssert])
- buf.fill(value, [offset], [end])
- buffer.INSPECT_MAX_BYTES
- Class: SlowBuffer
- Class: Buffer
- Stream
- Crypto
- crypto.getCiphers()
- crypto.getHashes()
- crypto.createCredentials(details)
- crypto.createHash(algorithm)
- Class: Hash
- crypto.createHmac(algorithm, key)
- Class: Hmac
- crypto.createCipher(algorithm, password)
- crypto.createCipheriv(algorithm, key, iv)
- Class: Cipher
- crypto.createDecipher(algorithm, password)
- crypto.createDecipheriv(algorithm, key, iv)
- Class: Decipher
- crypto.createSign(algorithm)
- Class: Sign
- crypto.createVerify(algorithm)
- Class: Verify
- crypto.createDiffieHellman(prime_length)
- crypto.createDiffieHellman(prime, [encoding])
- Class: DiffieHellman
- diffieHellman.generateKeys([encoding])
- diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding])
- diffieHellman.getPrime([encoding])
- diffieHellman.getGenerator([encoding])
- diffieHellman.getPublicKey([encoding])
- diffieHellman.getPrivateKey([encoding])
- diffieHellman.setPublicKey(public_key, [encoding])
- diffieHellman.setPrivateKey(private_key, [encoding])
- crypto.getDiffieHellman(group_name)
- crypto.pbkdf2(password, salt, iterations, keylen, callback)
- crypto.pbkdf2Sync(password, salt, iterations, keylen)
- crypto.randomBytes(size, [callback])
- crypto.pseudoRandomBytes(size, [callback])
- crypto.DEFAULT_ENCODING
- Recent API Changes
- TLS (SSL)
- Client-initiated renegotiation attack mitigation
- NPN and SNI
- tls.getCiphers()
- tls.createServer(options, [secureConnectionListener])
- tls.SLAB_BUFFER_SIZE
- tls.connect(options, [callback])
- tls.connect(port, [host], [options], [callback])
- tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
- Class: SecurePair
- Class: tls.Server
- Class: CryptoStream
- Class: tls.CleartextStream
- StringDecoder
- File System
- fs.rename(oldPath, newPath, callback)
- fs.renameSync(oldPath, newPath)
- fs.ftruncate(fd, len, callback)
- fs.ftruncateSync(fd, len)
- fs.truncate(path, len, callback)
- fs.truncateSync(path, len)
- fs.chown(path, uid, gid, callback)
- fs.chownSync(path, uid, gid)
- fs.fchown(fd, uid, gid, callback)
- fs.fchownSync(fd, uid, gid)
- fs.lchown(path, uid, gid, callback)
- fs.lchownSync(path, uid, gid)
- fs.chmod(path, mode, callback)
- fs.chmodSync(path, mode)
- fs.fchmod(fd, mode, callback)
- fs.fchmodSync(fd, mode)
- fs.lchmod(path, mode, callback)
- fs.lchmodSync(path, mode)
- fs.stat(path, callback)
- fs.lstat(path, callback)
- fs.fstat(fd, callback)
- fs.statSync(path)
- fs.lstatSync(path)
- fs.fstatSync(fd)
- fs.link(srcpath, dstpath, callback)
- fs.linkSync(srcpath, dstpath)
- fs.symlink(srcpath, dstpath, [type], callback)
- fs.symlinkSync(srcpath, dstpath, [type])
- fs.readlink(path, callback)
- fs.readlinkSync(path)
- fs.realpath(path, [cache], callback)
- fs.realpathSync(path, [cache])
- fs.unlink(path, callback)
- fs.unlinkSync(path)
- fs.rmdir(path, callback)
- fs.rmdirSync(path)
- fs.mkdir(path, [mode], callback)
- fs.mkdirSync(path, [mode])
- fs.readdir(path, callback)
- fs.readdirSync(path)
- fs.close(fd, callback)
- fs.closeSync(fd)
- fs.open(path, flags, [mode], callback)
- fs.openSync(path, flags, [mode])
- fs.utimes(path, atime, mtime, callback)
- fs.utimesSync(path, atime, mtime)
- fs.futimes(fd, atime, mtime, callback)
- fs.futimesSync(fd, atime, mtime)
- fs.fsync(fd, callback)
- fs.fsyncSync(fd)
- fs.write(fd, buffer, offset, length, position, callback)
- fs.writeSync(fd, buffer, offset, length, position)
- fs.read(fd, buffer, offset, length, position, callback)
- fs.readSync(fd, buffer, offset, length, position)
- fs.readFile(filename, [options], callback)
- fs.readFileSync(filename, [options])
- fs.writeFile(filename, data, [options], callback)
- fs.writeFileSync(filename, data, [options])
- fs.appendFile(filename, data, [options], callback)
- fs.appendFileSync(filename, data, [options])
- fs.watchFile(filename, [options], listener)
- fs.unwatchFile(filename, [listener])
- fs.watch(filename, [options], [listener])
- fs.exists(path, callback)
- fs.existsSync(path)
- Class: fs.Stats
- fs.createReadStream(path, [options])
- Class: fs.ReadStream
- fs.createWriteStream(path, [options])
- Class: fs.WriteStream
- Class: fs.FSWatcher
- Path
- net
- net.createServer([options], [connectionListener])
- net.connect(options, [connectionListener])
- net.createConnection(options, [connectionListener])
- net.connect(port, [host], [connectListener])
- net.createConnection(port, [host], [connectListener])
- net.connect(path, [connectListener])
- net.createConnection(path, [connectListener])
- Class: net.Server
- server.listen(port, [host], [backlog], [callback])
- server.listen(path, [callback])
- server.listen(handle, [callback])
- server.close([callback])
- server.address()
- server.unref()
- server.ref()
- server.maxConnections
- server.connections
- server.getConnections(callback)
- Event: 'listening'
- Event: 'connection'
- Event: 'close'
- Event: 'error'
- Class: net.Socket
- new net.Socket([options])
- socket.connect(port, [host], [connectListener])
- socket.connect(path, [connectListener])
- socket.bufferSize
- socket.setEncoding([encoding])
- socket.write(data, [encoding], [callback])
- socket.end([data], [encoding])
- socket.destroy()
- socket.pause()
- socket.resume()
- socket.setTimeout(timeout, [callback])
- socket.setNoDelay([noDelay])
- socket.setKeepAlive([enable], [initialDelay])
- socket.address()
- socket.unref()
- socket.ref()
- socket.remoteAddress
- socket.remotePort
- socket.localAddress
- socket.localPort
- socket.bytesRead
- socket.bytesWritten
- Event: 'connect'
- Event: 'data'
- Event: 'end'
- Event: 'timeout'
- Event: 'drain'
- Event: 'error'
- Event: 'close'
- net.isIP(input)
- net.isIPv4(input)
- net.isIPv6(input)
- UDP / Datagram Sockets
- dgram.createSocket(type, [callback])
- Class: dgram.Socket
- Event: 'message'
- Event: 'listening'
- Event: 'close'
- Event: 'error'
- socket.send(buf, offset, length, port, address, [callback])
- socket.bind(port, [address], [callback])
- socket.close()
- socket.address()
- socket.setBroadcast(flag)
- socket.setTTL(ttl)
- socket.setMulticastTTL(ttl)
- socket.setMulticastLoopback(flag)
- socket.addMembership(multicastAddress, [multicastInterface])
- socket.dropMembership(multicastAddress, [multicastInterface])
- socket.unref()
- socket.ref()
- DNS
- dns.lookup(domain, [family], callback)
- dns.resolve(domain, [rrtype], callback)
- dns.resolve4(domain, callback)
- dns.resolve6(domain, callback)
- dns.resolveMx(domain, callback)
- dns.resolveTxt(domain, callback)
- dns.resolveSrv(domain, callback)
- dns.resolveNs(domain, callback)
- dns.resolveCname(domain, callback)
- dns.reverse(ip, callback)
- Error codes
- HTTP
- http.STATUS_CODES
- http.createServer([requestListener])
- http.createClient([port], [host])
- Class: http.Server
- Event: 'request'
- Event: 'connection'
- Event: 'close'
- Event: 'checkContinue'
- Event: 'connect'
- Event: 'upgrade'
- Event: 'clientError'
- server.listen(port, [hostname], [backlog], [callback])
- server.listen(path, [callback])
- server.listen(handle, [callback])
- server.close([callback])
- server.maxHeadersCount
- server.setTimeout(msecs, callback)
- server.timeout
- Class: http.ServerResponse
- Event: 'close'
- Event: 'finish'
- response.writeContinue()
- response.writeHead(statusCode, [reasonPhrase], [headers])
- response.setTimeout(msecs, callback)
- response.statusCode
- response.setHeader(name, value)
- response.headersSent
- response.sendDate
- response.getHeader(name)
- response.removeHeader(name)
- response.write(chunk, [encoding])
- response.addTrailers(headers)
- response.end([data], [encoding])
- http.request(options, [callback])
- http.get(options, [callback])
- Class: http.Agent
- http.globalAgent
- Class: http.ClientRequest
- http.IncomingMessage
- HTTPS
- URL
- Query String
- punycode
- Readline
- REPL
- Executing JavaScript
- Child Process
- Assert
- assert.fail(actual, expected, message, operator)
- assert(value, message), assert.ok(value, [message])
- assert.equal(actual, expected, [message])
- assert.notEqual(actual, expected, [message])
- assert.deepEqual(actual, expected, [message])
- assert.notDeepEqual(actual, expected, [message])
- assert.strictEqual(actual, expected, [message])
- assert.notStrictEqual(actual, expected, [message])
- assert.throws(block, [error], [message])
- assert.doesNotThrow(block, [message])
- assert.ifError(value)
- TTY
- Zlib
- Examples
- zlib.createGzip([options])
- zlib.createGunzip([options])
- zlib.createDeflate([options])
- zlib.createInflate([options])
- zlib.createDeflateRaw([options])
- zlib.createInflateRaw([options])
- zlib.createUnzip([options])
- Class: zlib.Zlib
- Class: zlib.Gzip
- Class: zlib.Gunzip
- Class: zlib.Deflate
- Class: zlib.Inflate
- Class: zlib.DeflateRaw
- Class: zlib.InflateRaw
- Class: zlib.Unzip
- Convenience Methods
- zlib.deflate(buf, callback)
- zlib.deflateRaw(buf, callback)
- zlib.gzip(buf, callback)
- zlib.gunzip(buf, callback)
- zlib.inflate(buf, callback)
- zlib.inflateRaw(buf, callback)
- zlib.unzip(buf, callback)
- Options
- Memory Usage Tuning
- Constants
- os
- Debugger
- Cluster
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 unref
d 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 ref
d 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.exports
instead 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.js
then 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 dpkg
, rpm
, 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 thefoo
package, version 1.2.3./usr/lib/node/bar/4.3.2/
- Contents of thebar
package thatfoo
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 thatbar
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.gyp
file:
{ "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
Post a Comment