Skip to content

API changes between v0.10 and v4

Vasyl Boroviak edited this page Nov 21, 2015 · 15 revisions

When editing this page please be as detailed as possible. Examples are encouraged!

By Subsystem

assert

[Docs]

buffer

[Docs]

  • External memory is now allocated using TypedArrays, instead of using SlowBuffer or smalloc as the parent backing.

  • Buffer.concat() now always creates a new buffer, even if only called with one element. Previously when called with one element it would just return the element, even if not a Buffer.
  • SlowBuffer has been repurposed to return a Buffer instance who's parent backing is not pooled.
  • Buffer.prototype.toJSON()'s output is no longer the same as an array. Instead it is an object specifically tagged as a buffer, which can be recovered by passing it to (a new overload of) the Buffer constructor.
  • Buffer.prototype.parent is now a getter that points to buffer.buffer if the buffer's size is greater than zero.
  • Buffer.prototype.offset is now a read-only getter that returns buffer.byteOffset.
  • Buffer.prototype.fill() now accepts multi-character strings and will fill with the entire passed value. Additionally, fill() now returns its buffer and can be chained.
  • Buffer.prototype._charsWritten no longer is written to, nor exists.

Buffer changes from V8

Implementation changes in V8 have caused subtle impacts how buffers work with encodings in certain cases.

  • (new Buffer('text\0!', 'ascii')).toString() outputs 'text !' in 0.10 and 'text\u0000!' in 0.12.
  • Invalid unicode characters are replaced to no longer become invalid.
  • Refs: #2344

child_process

[Docs]

cluster

[Docs]

  • Cluster now uses round-robin load balancing by default on non-Windows platforms. The scheduling policy is configurable by setting cluster.schedulingPolicy.
    • It is advised that you do not use round-robin balancing on Windows as it is very inefficient.
    • Refs: e72cd41
  • Cluster has been made --debug-aware.
  • Cluster's 'setup' event now fires asynchronously.
  • Open connections (and other handles) in the master process are now closed when the last worker that holds a reference to them quits. Previously, they were only closed at cluster shutdown.
    • A side-effect of this is that the cluster master will refuse connections if there are no workers.
    • Refs: 41b75ca, #2606, #1239

crypto

[Docs]

  • crypto.randomBytes() now blocks if there is insufficient entropy.
    • Although it blocks, it should normally never take longer than a few milliseconds.
    • crypto.pseudoRandomBytes() is now an alias to crypto.randomBytes().
    • Refs: e5e5980
  • crypto.Sign.prototype.sign() will no longer swallow internal OpenSSL errors.

dgram

[Docs]

  • dgram.Socket.prototype.send() error semantics have changed.
    • Through 2.x, the the dgram socket.send() method emitted errors when a DNS lookup failed, even when a callback was provided. Starting from 3.0.0, if a callback is provided, no error event will be emitted.
    • When send() is supplied with a callback, it will no longer emit the 'error' event when an error occurs and instead pass the error to the callback.
    • Previously the behavior was to do both.
    • Refs: #1796

domain

[Docs]

The domain module has been scheduled for deprecation, awaiting an alternative for those who absolutely need domains.

It is suggested you avoid using domains if possible and rather rely on regular error checking.

  • domain.dispose() has been deprecated.
    • Please recover from failed IO actions explicitly via error event handlers set on the domain.
    • Refs: d86814a

events

[Docs]

freelist

  • The freelist module was only ever intended for internal use and is now deprecated.

fs

[Docs]

  • fs.createReadStream() and fs.createWriteStream() now have stricter type-checking for the options argument.
  • fs.exists() is now deprecated. It is suggested to use either fs.access() or fs.stat(). Please read the documentation carefully.
  • Added more informative errors and method call site details when the NODE_DEBUG environment is set to ease debugging.
    • The same thing applies to the synchronous versions of these APIs.
    • Refs: 1f76a2e
  • Fixed missing callbacks errors just being printed instead of thrown.
  • On Unix soft ulimit values are ignored.
  • Errors for async fs operations are now thrown if a callback is not present.
  • The error messages of most fs errors have been improved to be more descriptive and useful.

http

[Docs]

  • http server timing change (Use 'finish' instead of 'prefinish' when ending a response)
  • When doing HTTP pipelining of requests, the server creates new request and response objects for each incoming HTTP request on the socket. Starting from 3.0.0, these objects are now created a couple of ticks later, when we are certainly done processing the previous request. This could change the observable timing with certain HTTP server coding patterns.
  • The switch to 'finish' is intended to prevent the socket being detached from the response until after the data is actually sent to the other side.
  • Refs: 6020d2, #1411
  • Removed default chunked encoding on DELETE and OPTIONS requests.
  • http.STATUS_CODES now maps to the regulated IANA standard set of codes.
    • Updating the code mappings to conform to the IANA standard was a backwards incompatible change to consumers who depend on the text value of a header. The most significant of these changes was the text for 302, which was previously Moved Temporarily but is now Found.
    • Refs: 235036e, #1470
  • http.Agent.prototype.getName() no longer returns an extra trailing colon.
  • http.OutgoingMessage.prototype.flush() has been deprecated in favor of the new flushHeaders() method. The behavior remains the same.
  • http.OutgoingMessage.prototype.setHeader() will now throw an error if the second argument is undefined.
  • http.OutgoingMessage.prototype.write() will now emit an error on the OutgoingMessage (response) object if it has been called after end().
  • http.request() and http.get() wrongly decode multi-byte string characters as 'binary'.
  • http.request() and http.get() now throw a TypeError if the requested path contains illegal characters. (Currently only ' ').
  • http.request() and http.get() no longer accept non-ascii characters in the header fields or path.

net

[Docs]

os

[Docs]

  • os.tmpdir() now never returns a trailing slash regardless of the host platform.
  • os.tmpdir() on Windows now uses the %SystemRoot% or %WINDIR% environment variables instead of the hard-coded value of c:\windows when determining the temporary directory location.

path

[Docs]

process

[Docs]

  • Added the concept of beforeExit time.
    • Before the process emits 'exit' and begins shutting down, it will emit a 'beforeExit' event. Code that is run in the 'beforeExit' event can schedule async operations that will hold the event loop open, unlike 'exit' where it is too late to async operations.
    • Refs: a2eeb43
  • Chunked writes to sdtout/stderr will now be lost if the process is terminated early.
    • Chunked writes happen when the string to be written is beyond a certain, fairly large, size. (Usually 8192 bytes.)
    • This becomes a problem if you are terminating your process early via process.exit(), which is not suggested.
    • Refs: #784, #1771
  • process.kill() now throws errors on non-numeric input.
    • Strings that can be coerced to numbers still work. e.g. process.kill('0').
    • Refs: 832ec1c, 743a009
  • process.maxTickDepth has been removed, allowing process.nextTick() to starve I/O indefinitely.
    • This is due to adding setImmediate() in 0.10.
    • It is suggested you use setImmediate() over process.nextTick(). setImmediate() likely does what you are hoping for (a more efficient setTimeout(..., 0)), and runs after this tick's I/O. process.nextTick() does not actually run in the "next" tick anymore and will block I/O as if it were a synchronous operation.
    • Refs: 0761c90, 9a6c085
  • process.send() is now always asynchronous, where previously it was blocking on Unix.
    • Pull request #2620, which should land before 4.0.0, will make send() accept a callback as the last argument, with will be called with one argument: null if it succeeded, or an Error if it failed.
    • Refs: #760, #2620

Signal handling

In node 0.10.x, exit from a fatal signal was accomplished by a signal handler in node which called exit(128 + signo). So for SIGINT (signal 2), a node process observing the exit of a spawned node process would observe that process exiting 130, but no signal would be noted (see waitid(2) for more information on how a process waiting for another determines if the waitee exited due to a signal). In node 0.12.x, a node process observing the exit of a spawned child node process will see a null code, and a 'SIGINT' as the signal.

Here is a pair of test programs which illustrates the difference.

$ cat sleeper.js
setTimeout(function () {}, 300000)

$ cat test.js
var cp = require("child_process")
var p = cp.spawn("node", ["sleeper.js"])
p.on('exit', function (code, signal) {
  console.log("code=" + code + ", signal=" + signal)
})
setTimeout(function () { p.kill('SIGINT') }, 2000)

On node 0.10 this produces:

$ node test.js
code=130, signal=null

On node 0.12+ this produces:

$ node test.js
code=null, signal=SIGINT

This can be a subtle porting issue for multi-process node environments which care about signals (such as test harnesses). This change was introduced by c61b0e9main: Handle SIGINT properly.

querystring

[Docs]

smalloc

smalloc was a core module in 0.12 and io.js <3.0.0 for doing (external) raw memory allocation/deallocation/copying in JavaScript.

smalloc was removed in io.js 3.0.0, as the required v8 APIs were removed. smalloc used to be used in the buffer implementation, however buffers are now built on top of TypedArrays (Specifically Uint8Array).

stream

[Docs]

The changes to streams are not as drastic as the transition from streams1 to streams2: they are a refinement of existing ideas, and should make the API slightly less surprising for humans and faster for computers. As a whole the changes are referred to as "streams3", but the changes should largely go unnoticed by the majority of stream consumers and implementers.

Readable Streams

The distinction between "flowing" and "non-flowing" modes has been refined. Entering "flowing" mode is no longer an irreversible operation -- it is possible to return to "non-flowing" mode from "flowing" mode. Additionally, the two modes now flow through the same machinery instead of replacing methods. Any time data is returned as a result of a .read() call that data will also be emitted on the 'data' event.

As before, adding a listener for the 'readable' or 'data' event will start flowing the stream; as will piping to another stream.

Writable Streams

The ability to "bulk write" to underlying resources has been added to Writable streams. For stream implementers, one can signal that a stream is bulk-writable by specifying a _writev method. Bulk writes will occur in two situations:

  1. When a bulk-writable stream is clearing its backlog of buffered write requests,
  2. or if an end user has made use of the new .cork() and .uncork() API methods.

.cork and .uncork allow the end user to control the buffering behavior of writable streams separate from exerting backpressure. .cork() indicates that the stream should accept new writes (up to .highWaterMark), while .uncork() resets that behavior and attempts to bulk-write all buffered writes to the underlying resource.

The only core stream API that currently implements _writev() is net.Socket.

In addition to the bulk-write changes, the performance of repeated small writes to non-bulk-writable streams (such as fs.WriteStream) has been drastically improved. Users piping high volume log streams to disk should see an improvement.

For a detailed overview of how streams3 interact, see this diagram.

  • WritableState.prototype.buffer has been deprecated in favor of _writableState.getBuffer(), which builds an array from an internal object single-way linked list.
    • Mutating the array returned will have no effect as getBuffer() constructs it from the linked list. However modifying one of the array's element's .next property will effect the list.
    • Refs: 9158666
  • WritableStream.prototype._write() now gets called with 'buffer' encoding when chunk is a Buffer.
  • Writable streams now emit 'finish' on the next tick if there was a write() when finishing.

Transform Streams

  • When in objectMode, Transform.prototype._read() now processes false-y (but not null) values, such as '', 0, etc.

sys

As of 1.0.0 the sys module is deprecated. It is advised to use the util module instead.

timers

[Docs]

  • Updated setImmediate() to process the full queue each turn of the event loop, instead of one per queue.
    • It is suggested you use setImmediate() over process.nextTick(). setImmediate() likely does what you are hoping for (a more efficient setTimeout(..., 0)), and runs after this tick's I/O. process.nextTick() does not actually run in the "next" tick anymore and will block I/O as if it were a synchronous operation.
    • Refs: fa46483
  • setImmediate()'s timing was adjusted slightly, but is still after process.nextTick() and I/O, but before regular timeouts and intervals.
  • Internal timeouts now run in a separate queue with slightly different semantics, and will never keep the process alive on their own.
    • This may effect your performance profile.
    • It is strongly advised you do not attempt to use _unrefActive() as it will probably be hidden in the future.
    • Refs: f46ad01
  • Timer globals (e.g. setTimeout()) are no longer lazy-loaded.

tls

[Doc]

  • The tls server option SNICallback required returning a secureContext synchronously as function (hostname) { return secureContext; }. The function signature is now asynchronous as function (hostname, cb) { cb(null, secureContext); }. You can feature detect with 'function' === typeof cb.
  • The tls server option dhparam must now have a key length greater than 1024 bits, or else it will throw an error.
  • RC4 is now disabled on the cipher list.
    • RC4 is now considered insecure and has been removed from the list of default ciphers for TLS servers. Use the ciphers option when starting a new TLS server to supply an alternative list.
    • Refs: #826
    • Potentially mitigated if archive#39 is merged.
  • Implemented TLS streams in C++, boosting their performance.
  • Moved & renamed crypto.createCredentials() to tls.createSecureContext().
  • Removed SSLv2 and SSLv3 support.
    • Both SSLv2 and SSLv3 are now considered too insecure for general use and have been disabled at compile-time.
    • Refs: #290, #315, archive#20

url

[Docs]

  • url.parse() will now always return a query object and search string, even if they are empty, when parseQueryString (the second argument) is set to true.
    • e.g. a url.parse(..., true) return value will now include { search: '', query: {} } where previously both properties would not exist.
    • Refs: b705b73
  • url.parse() now escapes the following characters and spaces (' ') in the parsed object's properties:
    < > " ` \r \n \t { } | \ ^ '
    
    • e.g.
    url.parse("http://example.com/{z}/{x}/{y}.png#foo{}").href === 'http://example.com/%7Bz%7D/%7Bx%7D/%7By%7D.png#foo%7B%7D'
    
  • url.resolve() now resolves properly to '.' and '..'.
    • This means that resolve('/a/b/', '.') will return '/a/b/', and resolve('/a/b', '.') will return '/a/'.
    • resolve('/a/b/', '..') returns '/a/'.
    • This change, while technically a potentially breaking change, also landed in node 0.10.37.
    • Refs: faa687b, #278

util

[Docs]

  • util.is*() (isArray() ... isUndefined()) type-checking functions were added in 0.12 but are scheduled for deprecation. Please use user-land solutions instead.
    • The type checking these use will be come brittle with the eventual addition of Symbol.toStringTag.
    • Refs: #2447
  • Updated util.format() to receive several changes:
    • -0 is now displayed as such, instead of as 0.
    • Anything that is instanceof Error is now formatted as an error.
    • Circular references in JavaScript objects are now handled for the %j specifier.
    • Custom inspect functions now receive any arguments passed to util.inspect.
    • Displays the constructor name if available.
  • The following utilities were deprecated in 896b2aa:

vm

[Docs]

  • The vm module has been rewritten to work better, based on the excellent Contextify native module. All of the functionality of Contextify is now in core, with improvements!
  • Updated vm.createContext(sandbox) to "contextify" the sandbox, making it suitable for use as a global for vm scripts, and then return it. It no longer creates a separate context object.
  • Updated most vm and vm.Script methods to accept an options object, allowing you to configure a timeout for the script, the error display behavior, and sometimes the filename (for stack traces).
  • Updated the supplied sandbox object to be used directly as the global, remove error-prone copying of properties back and forth between the supplied sandbox object and the global that appears inside the scripts run by the vm module.

For more information, see the vm documentation linked above.

JavaScript: array.values() has been removed since 0.12

  • array.values() came from an unofficial release of V8 and has since been removed pending further work on V8's conformance with the spec. Instead of continuing to float a patch on top of V8, io.js and the converged repository are currently without support for it.

General Node

  • Unknown command-line options are now errors.

  • The built-in mdb_v8 bindings have been removed due to a lack of maintenance.
    • They may be re-added later in 4.x. Please see #2517 for more info.
    • Refs: 37bb1df

  • Building node now has the following compiler version minimum requirements due to the newer v8 versions:
    • g++ 4.8 & gcc 4.2 OR clang++ 3.4 & clang 3.2
    • Refs: 48774ec

Dependencies

c-ares

[Repo]

1.9.0-DEV --> bagder/c-ares#bba4dc5 + 7e1c0e7...08d0866

This is roughly c-ares version 1.10.1. At this point the Node.js team effectively "maintains" c-ares.

gtest

[Repo]

New in 0080788, added to test c++ code. Only used in node's tests. Not exposed.

http_parser

[Repo]

1.0 --> 2.5.0

libuv

[Repo]

0.10.36 --> ^1.6.1

npm

[Repo]

1.4.28 --> ^2.13.3

Note that npm minor and patch versions are pulled into io.js and node at an almost-weekly rate.

Also, the version of npm that ships with node.js v4.0.0+ has had it's node-gyp dependency patched in a couple ways. node-gyp is used to compile native add-ons.

  • Enabled the windows delay-load hook by default. 3bda6cb
    • A rare few native modules will not work with this on by default unless they are updated to fix the issues.
    • More info about the delay-load hook can be found at efadffe.
  • Downloads the new headers-only tarballs introduced in io.js. e52f963
    • Instead of downloading full tarballs of node.js, we now download tarballs of only the headers, which are much smaller. Full tarballs are still available for nodejs.org.
  • Nightly and pre-release versions of node.js are able to download tarballs. 902c9ca & 9f727f5

OpenSSL

[Repo]

1.0.1p --> 1.0.2d

punycode

[Repo]

v1.2.0 --> v1.3.2

zlib

[Repo]

1.2.3 --> 1.2.8 + 59ad4b0...a80b977

V8

v3.14.5.9 --> v4.5.x + floating patches

The version bump is contains about 21 stable (n.X) V8 releases.

c++

Virtually all native addons must be updated to work with 4.0.0 from 0.10 or 0.12. Please see NAN's API docs for help with migrating your native addons.

Clone this wiki locally