Node 8 and npm@5 release: What's new?

June 15, 2017 0 Comments

Node 8 and npm@5 release: What's new?

 

 

TL;DR: Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. It has gained massive adoption by developers and organizations around the world because of it's efficient, event-driven and non-blocking I/O model. Node.js makes it possible for developers to code the most popular language (JavaScript) in the world on the backend. Furthermore, Node.js's package manager,npm, houses the largest distribution of open source libraries in the world. Node.js and npm just had new major releases. In this article, we'll highlight 7 notable additions to Node.js and dabble into the new monster, npm@5.

Node.js 8.0.0 was announced to the world on May 31, 2017. The previous Node.js version was v7.10.0. The v was dropped in order to avoid confusion with the V8 JavaScript engine. This major release brings a lot of new features, deprecations and changes. By October, 2017, Node.js 8 will become a Long Term Support (LTS) release. Next, notable additions!

1. Node.js API (N-API)

Currently, this is an experimental feature behind a flag. 30 percent of JavaScript modules rely indirectly on native modules.

Existing native modules are written in C/C++ and directly depend on V8 or Native Abstractions for Node.js (NAN) APIs. This dependency requires native modules to be recompiled and updated for every major Node.js release. This is a burden for native modules maintainers. Furthermore, companies and products depending on these modules find it difficult to upgrade their Node.js versions in production because of potential massive code breakage.

Now, the N-API is here to eliminate breakage of dependencies that happens between release lines with native modules. The full N-API functions can be found in the documentation.

Note: These 5 modules, node-sass, canvas , leveldown , nanomsg, and iotivity have successfully been ported to use N-API.

Native modules builders and users can start experimenting with this feature. More details can be found here.

2. Better Support for Promises

This release includes a new util.promisify() API that allows developers to wrap standard callback-style APIs in a function that returns a Promise. Check out this sample code:

const fs = require('fs');
const util = require('util'); const readfile = util.promisify(fs.readFile); readfile('/some/file') .then((data) => { /* ... / }) .catch((err) => { / ... */ });

3. Buffer Improvements

The Node.js Buffer API witnessed a lot of changes. Most notable amongst these changes is:


  • Zero-filling new instances of Buffer(num) by default will have a negative significant impact on performance. The positive side of zero-filling Buffer is that it helps to prevent information leaks.

You want Buffer instances with uninitialized memory? No problem! Use the Buffer.allocUnsafe(num) API.

// Zero-filled Buffers
const safeBuffer1 = Buffer.alloc(20);
const safeBuffer2 = new Buffer(20); // Uninitialized Buffer
const unsafeBuffer = Buffer.allocUnsafe(20);

Note: Developers should be very careful when using the Buffer.allocUnsafe. Only use it when you are aware of the risks and how to avoid it.

4. Stable WHATWG URL Parser

This release makes the WHATWG URL parser fully supported. No more hiding behind the experimental flag. It's a URL API implementation that matches the URL implementation in modern web browsers like Firefox, Edge, Chrome, and Safari allowing code using URLs to be shared across environments. The URL implementation will be handled equally on these modern browsers.

const myURL = new URL('/foo', 'https://example.org/'); // result
https://example.org/foo const myURL = new URL('https://example.org/foo#bar');
console.log(myURL.hash);
// returns #bar console.log(myURL.href);
// returns https://example.org/foo#baz

5. asynchooks

The experimental asynchooks module otherwise known as async_wrap has received a major bump in Node.js 8.

This API gives developers the ability to register callbacks tracking the lifetime of asynchronous resources created inside a Node.js application. An asynchronous resource represents an object with an associated callback. Some of the API methods can be found below:

const asynchooks = require('asynchooks'); const cid = asynchooks.currentId();
// returns the ID of the current execution context. const tid = asynchooks.triggerId();
// returns the ID of the handle responsible for triggering the callback of the current execution scope to call. // Create a new AsyncHook instance. All of these callbacks are optional.
const asyncHook = async_hooks.createHook({ init, before, after, destroy });

Look at this example below:

const fs = require('fs');
const asynchooks = require('asynchooks'); asynchooks.createHook({ init(asyncId, type, triggerId) { const cId = asynchooks.currentId(); fs.writeSync(1, ${type}(${asyncId}): trigger: ${triggerId} scope: ${cId}\n); } }).enable(); require('net').createServer((conn) => {}).listen(8080);

Output when hitting the server with nc localhost 8080:

TCPWRAP(2): trigger: 1 scope: 1
TCPWRAP(4): trigger: 2 scope: 0

The first TCPWRAP is the server which receives the connections. The second TCPWRAP is the new connection from the client. When a new connection is made the TCPWrap instance is immediately constructed. This happens outside of any JavaScript stack (side note: a currentId() of 0
means it's being executed from C++, with no JavaScript stack above it). With only that information it would be impossible to link resources together in terms of what caused them to be created, so triggerId is given the task of propagating what resource is responsible for the new resource's existence.

The full documentation can be found here.

6. Stream API Improvements

This release adds new ways for destroying and finalizing Stream instances. Every Stream instance will now inherit a destroy() method, the implementation of which can be customized and extended by providing a custom implementation of the _destroy() method.

myStream.destroy = function (cb) { closeResources(function (err) { cb(err) })
} myStream.destroy();

The destroy() method can take in two arguments, the err and callback function. The callback function takes an optional error argument which is invoked when the stream is destroyed.

From the code above, there is a custom implementation of the _destroy() method. So calling the destroy() method destroys the stream, and emits the passed error.

7. Inspector JavaScript API

Developers have a new way of debugging their Node.js applications via the experimental inspector JavaScript API. This API leverages the debug protocol to inspect various Node.js processes.

The inspector module provides an API for interacting with the V8 inspector.

const inspector = require('inspector'); const session = new inspector.Session();
session.connect(); // Listen for inspector events
session.on('inspectorNotification', (message) => { // Do whatever
}); // Send messages to the inspector
session.post(message); session.disconnect();

There are other events such as the Debugger.paused and Debugger.resumed events that you can listen to with this module.

Check out how to inspect your node.js scripts and also use Chrome DevTools to debug your Node.js apps

If you are curious about other changes and additions in Node.js 8.0.0 release, you can check out the full list of changes here.

Note: Node.js 8.0.0 ships with npm 5.

Let's highlight major changes in npm 5.

npm@5

npm's latest version is npm@5. What's new in npm@5?

1. Wicked Fast Install

I bumped my npm version to npm 5 using npm install npm@latest -g and the first thing I discovered was that my module installs were insanely fast!

Speed improvements
Installing react-native


Tag cloud