What's new in Node.js 10?

null

Node.js bravely enabled JavaScript to go to places its creators never intended the language to go. Many well-liked features seen in new ECMAScript revisions started out as features added to Node.js – sadly, the standardised APIs were often incompatible with the ones thought up by the Node.js developer team.

Thus, one of the recurring topics of the Node.js world revolves around reconciling differences between 'web development' and 'node development'. For example, the module subsystem of Node.js does not work according to ECMAScript standards. Node.js 10 updates the versions of various core components used in the product, thereby enabling developers to harness speed and security improvements.

Furthermore, work on HTTP/2 speeds up delivery of content in bandwidth- and/or latency-constrained scenarios. A change in the native interface will simplify the life of Node.js plugin developers, leading to a more vibrant extension ecosystem. The highly detailed technical nature of the changes makes providing individual examples difficult. However, in this post we've rounded up 20 short tidbits of information that will help you get to grips with Node.js 10.

Should you feel like always staying on top of the latest developments in Node.js, head to this GitHub page. It provides an intimate level of detail on changes in the product.

01. Update your environment

Node.js can be compiled by hand. However, most Linux distros are able to run an automatic installer. The code here shows the installation process on Ubuntu 14.04 LTS. If your operating system shows up in Fig. 1, find a similar process here.

tamhan@TAMHAN14:~$ sudo apt-get remove nodejs
tamhan@TAMHAN14:~$ curl -sL https://deb.
nodesource.com/setup_10.x | sudo -E bash -
tamhan@TAMHAN14:~$ sudo apt-get install -y
nodejs

02. Sniff out errors…

Developers have performed string comparisons to find errors ever since Node.js 1.0. Version 9.0 started to shift to easier-to-handle constants, however. The code accompanying this step is immune to spelling mistakes and is resistant to attempts 'to improve usability by reformulating error messages'.

try {
// foo
} catch (err) {
if (err.code === 'ERR_ASSERTION') { . . . }
else { . . . }
}

03. …understand them…

Process computer programmers baulk at the idea of using strings to transmit error states – Node.js 10 does not break this tradition. Instead, the framework defines a few dozen strings, which will serve as a 'magic constant' and can be returned in the code field of the 'Error' object.

04. …and describe them properly

The introduction of error codes does not deprecate traditional error messages. Code based on the presence of the '.message' field continues to perform just as it did – should you need to present a message end users can understand, you can trust the field just as you did before.

const err = new Error('The message');
console.error(err.message);

05. Speed comes with V8 updates

Node.js always used the V8 runtime for JavaScript execution. As with most project collaborations, Node.js usually lags behind V8's progress. Node.js 10 is based on version 6.6 of V8, which brings significant improvements in caching and array-handling performance.

06. Headless try-catch!

Try-catch blocks are the bane of Java programmers: finding one marked with a comment instructing to shut the compiler up is common. V8 6.6 reduces the burden of unwanted try-catches by letting developers omit the exception object from the catch block.

try {
 doSomethingThatMightThrow();
} catch {
 handleException(); }

07. Improved detail in function reflection

One little-known detail of JavaScript concerns functions: they can be considered objects, too. So far, the toString() method just returned the method name. In Node.js 10, the program returns the whole first line – as can be seen in the figure, the return value even extends to all kinds of comment

function /* demo */ sayHurz()
{
console.log(“Hurz!”);
}
console.log(sayHurz.toString());

08. Remedy failed updates

Should your workstation be unable to run the new version of Node.js, check the package manager configuration. Yours truly had to delete the two files mentioned in the following code before normal program operation could resume:

tamhan@TAMHAN14:/etc/apt/sources.list.d$ sudo
rm nodesource.list
tamhan@TAMHAN14:/etc/apt/sources.list.d$ sudo
rm nodesource.list.save

09. ECMAScript modules

While Node.js influenced the idea of JavaScript modules, the ECMAScript implementation is not compatible with Common.js. While the --experimental-modules flag has been around for quite some time, Node.js 10 brings along a few new features intended to let ECMAScript-based modules work in Node environments.

tamhan@TAMHAN14:~/workspace$ node
--experimental-modules index

10. Understand native module architecture...

While JavaScript can do a lot of things, some jobs require the use of C++. So far, developers seeking tighter integration have usually placed their trust in the V8 API – leading to plugin rewriting whenever the version of V8 used in Node.js was changed.

11. ...and see N-API improvements

Thankfully, N-API solves this problem by providing a new abstraction layer. Any changes made to the underlying platform and tooling are no longer exposed to developers working on plugins, thereby lowering maintenance burdens and, hopefully, making Node.js upgrades smoother.

12. Learn about the API

As far as C APIs go, the N-API is clearly among the better-designed ones. As shown in excruciating detail here, the API comes equipped with methods for handling object creation, callbacks and more. Furthermore, the header contains a 'lock' permitting you to disable features not found in older versions of the NAPI for compatibility reasons.

#define NAPI_VERSION 3
#include <node_api.h>

13. Use ChaCha20 and Poly1305

Cryptography always was of significant importance on the web. Node.js 10 updates the underlying version of OpenSSL to 1.1.0, thereby enabling developers to use new encryption algorithms, which are expected to be more robust. This is especially helpful when seeking to implement AEAD-type encryption schemes.

14. Targeted tracing

Node.js 10 emits a set of additional tracing parameters, thereby letting developers zero in on performance problems. Trace objects can furthermore be enabled and disabled at will via the functions shown in the snippet accompanying this step – pinpoint accuracy is now at every developer's fingertips.

const trace_events = require('trace_events');
const t1 = trace_events.createTracing({
categories: ['node', 'v8']
});
const t2 = trace_events.createTracing({
categories: ['node.perf', 'node']
});
t1.enable();
t2.enable();
t2.disable();

15. Find out more about tracing

As of this writing, Node.js supports a total of eight trace types. In addition to V8 events, developers can also register themselves for bootstrap, async_hook and file system sync information at the command line or via the trace object.

const trace_events = require('trace_events');
const tracing = trace_events.createTracing({
categories: ['node.perf'] });
tracing.enable();

16. HTTP/2 is now official…

While the API stability indicator in the Node.js documentation still shows HTTP/2 support as being experimental, the API can be considered stable.

const http2 = require('http2');
const fs = require('fs');
const server = http2.createSecureServer({
 key: fs.readFileSync('localhost-privkey.
pem'),
 cert: fs.readFileSync('localhost-cert.pem')
});
server.on('error', (err) => console.
error(err));

17. …but do mind the encryption

When implementing a Node.js server which uses HTTP/2, do bear in mind that the unencrypted version of the protocol is not supported by any web browser as the time of writing. Because of this, you should be prepared to deal with significant processor overhead when transmitting and receiving data in proxyless configurations.

server.on('stream', (stream, headers) =>
{
 // stream is a Duplex
 stream.respond({
   'content-type': 'text/html',
   ':status': 200
 });
 stream.end('<h1>Hello World</h1>');
});
server.listen(8443);

18. File system API with promises

Promises are all the rage in JavaScript. So far, developers have usually had to make do without promise-based file system APIs – a problem that's been remedied in Node.js 10. While the module fs/promises is still experimental, it is already providing a nice alternative to 'traditional' file system accesses.

require('fs/promises')

19. More work has been done on async hooks

Node.js is single-threaded by default. Async hooks enable code to keep an eye on asynchronously-executed resources in a more comfortable fashion – while the API is far from stable, Node.js 10 provides significant improvements over the barely-working implementations found in previous versions.

const async_hooks = require('async_hooks');
const eid = async_hooks.executionAsyncId();
const tid = async_hooks.triggerAsyncId();
const asyncHook =  async_hooks.createHook
({
init, before, after, destroy, promiseResolve
});

20. Turbo-NPM

While NPM is usually seen as constitutent part of the Node.js distribution, it is actually a standalone product. Current versions of Node.js 10 come with NPM 6, which offers significant speed increases when installing and deploying packages. On this writer's machine, some processes saw tenfold speed increases.

This article was originally published in creative web design magazine Web Designer. Buy issue 279 or subscribe.

Read more: