Skip to content
This repository has been archived by the owner on Oct 16, 2021. It is now read-only.

API changes between v0.8 and v0.10

James Howe edited this page Sep 10, 2013 · 3 revisions

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

Changed

  • Streams Interface

    • Readable, Writable, Duplex, and Transform base classes added.
    • Readable streams use a read() method instead of emitting 'data' events right away.
    • Adding a 'data' event handler, or calling pause() or resume() will switch into "old mode".
      • This means that data event handlers won't ever miss the first chunk if they're not added right away, and pause() is no longer merely advisory.
    • If you don't consume the data, then streams will sit in a paused state forever, and the end event will never happen.
  • process.title no longer overwrites the environ. That means the length of process.title is now restricted to the length of the binary's name plus the command line arguments. On the upside, it works on OS X now!

  • The uv_after_work_cb signature has changed to take a second integer argument indicating status. For backwards compatibility, explicitly cast the 4th argument to uv_queue_work. Example

  • process.nextTick happens at the end of the current tick, immediately after the current stack unwinds. If you are currently using recursive nextTick calls, use setImmediate instead.

  • -p --print command line switch implies -e --eval

  • net: sockets created with net.createServer() no longer emit a connect event. The socket is already connected, by the time the connectionListener callback is called, so this was considered superfluous This was originally there to support Socket object re-use, which has not actually been possible since well before Node v0.4. The Socket is already connected by the time the Server has it, obviously, and the time of the event emission was thus actually a lie. When you get a socket on the server, it's already connected, so you can just go ahead and use it.

  • url: Parsed objects always have all properties, but unused ones are set to null. Example:

    // v0.8
    > url.parse('http://foo')
    { protocol: 'http:',
      slashes: true,
      host: 'foo',
      hostname: 'foo',
      href: 'http://foo/',
      pathname: '/',
      path: '/' }
    
    // 0.10
    > url.parse('http://foo')
    { protocol: 'http:',
      slashes: true,
      auth: null,
      host: 'foo',
      port: null,
      hostname: 'foo',
      hash: null,
      search: null,
      query: null,
      pathname: '/',
      path: '/',
      href: 'http://foo/' }
  • Domain-added properties on error objects are camelCase instead of snake_case

  • path.resolve and path.join throw a TypeError on non-string input

  • dgram.Socket#bind() is always asynchronous now. If you have code that looks like this:

    var s = dgram.createSocket('udp4');
    s.bind(1234);
    s.addMembership('224.0.0.114');

    You have to change it to this:

    var s = dgram.createSocket('udp4');
    s.bind(1234, function() {
      s.addMembership('224.0.0.114');
    });
  • The EventEmitter constructor initializes various properties now. It still works fine as an OOP inheritance parent, but you have to do inheritance properly. The Broken-Style JS inheritance pattern will not work when extending the EventEmitter class. This inheritance style was never supported, but prior to 0.10, it did not actually break.

    // Broken-Style Inheritance, which has never been safe or wise
    // but is shown on many broken tutorials around the web.
    function Child() {}
    Child.prototype = new Parent(); // <-- NEVER EVER DO THIS!!
    // If you see anyone doing this in any javascript library ever,
    // post a bug telling them that it is a huge terrible mistake!
    // Inheriting from a class should not call that class's ctor
    // on the prototype shared with EVERY instance of the child class!
    [ Why not? You don't provide any real argument for this statement! ]
    
    // Correct-Style Inheritance
    function Child() {
      Parent.call(this);
    }
    Child.prototype = Object.create(Parent.prototype, {
      constructor: {
        value: Child,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    // "Gee that's a lot of lines! I wish there was a helper method!"
    // There is.  Do this:
    util.inherits(Child, Parent);
  • https now does peer verification by default. This means that if you try to access an SSL endpoint which has a Certificate Authority that is not in the default CA list, you will get an error where you did not before. You can set rejectUnauthorized to false to get the old behavior.

  • https.createServer now requires SSL options at creation time and will throw if they are not sent. Prior versions tolerated not having options passed until .listen() was called.

  • os.tmpDir() has been renamed to os.tmpdir() as the recommended default. os.tmpDir() still exists as an alias.

  • Native addons can now receive the complete module object, allowing them to override exports with a custom object or function (i.e. the "substack pattern"). Simply adding a second argument to your Init() function gives you the module object: void Init(Handle<Object> exports, Handle<Object> module);. The addons examples now mix both classic and exports-overriding patterns (additionally the examples are now available in a GitHub repo).

    Classic

    Handle<Value> Booya(const Arguments& args) {
      HandleScope scope;
      return scope.Close(String::New("hello world"));
    }
    void Init(Handle<Object> exports) {
      exports->Set(String::NewSymbol("booya"), FunctionTemplate::New(Booya)->GetFunction());
    }
    NODE_MODULE(addon, Init)
    console.log(require('./build/Release/addon').booya())

    Single-function on exports

    Handle<Value> Booya(const Arguments& args) {
      HandleScope scope;
      return scope.Close(String::New("hello world"));
    }
    void Init(Handle<Object> exports, Handle<Object> module) {
      module->Set(String::NewSymbol("exports"), FunctionTemplate::New(Booya)->GetFunction());
    }
    NODE_MODULE(addon, Init)
    console.log(require('./build/Release/addon')())
  • FS operations that raise an error will throw if no callback is provided. This prevents missing potentially hazardous errors when a callback function was forgotten. To ignore errors, pass in function(){} as a callback. To track down the source of the callback-less fs operation, set NODE_DEBUG=fs in the environment.

  • FS readFile(), writeFile(), appendFile() and their Sync counterparts now take an options object (but the old API, an encoding string, is still supported)

  • Crypto methods return Buffer objects by default, rather than binary-encoded strings.

  • util.inspect() now takes an "options" object. The old API is still supported for backwards compatibility.

  • net: Connections are destroyed immediately after calling end() when "Connection: close" is in effect, rather than asynchronously.

Added

  • Streams - Added base classes for Readable, Writable, Duplex, and Transform
  • Streaming interfaces for Crypto API
  • process: add getgroups(), setgroups(), initgroups()
  • crypto: getHashes() getCiphers()
  • http: add response.headersSent property
  • events: 'removeListener' event
  • setImmediate() and clearImmediate() functions
  • string_decoder: the decoder.end() function was added
  • fs: ftruncate() and ftruncateSync()
  • buffer: Buffer.prototype.toJSON() function as added
  • timers: unref() and ref() functions added to setTimeout() and setInterval() handles