Understanding Features in Node.js v15.0.0

Understanding Features in Node.js v15.0.0

I am sure all of you who are reading this blog are undoubtedly excited to learn all new features as early as possible. And we need to be excited about the new version changes and features because NodeJs got a new improvement in the race of server-side languages. NodeJs undoubtedly grab the large user base in a really very short span of time.

I am also excited to make you understand the all-important ones in a single blog. So, Let's start learning the new features of Node.js.

So, the newly delivered features in Node.js v15.0.0 are: -

  • QUIC (Experimental)
  • V8 Engine 8.6
  • Throw on unhandled rejections previously in warn state by default
  • npm 7
  • N-API Version 7
  • AbortController

Let's understand what is QUIC first and how to use it.

QUIC (Experimental)

Basically, QUIC is a protocol used for general-purpose communication. And it is similar to the HTTP/2 protocol but with more advanced features. As we all know that the HTTP/2 protocol was based on TCP. And TCP is required to establish the connection before transmitting the packet between the server and the client. TCP needs to pass the handshaking process of establishing the connection. And after which TCP sends data through the single-stream channel but HTTP/2 does support multiplexing for downloading and uploading multiple things concurrently.

TCP Based HTTP/2 protocol Issues

If a packet loss between the network then TCP check the checksum and sequence number and send ARQ (automatic repeat request) packet to the server that packet is missing the sequence and that process is a little bit slower and block the all multiplexed stream pipes. And TCP also has one more issue like when the network changes at the client-side then TCP starts again establishing the new connection by doing a slow handshaking process and closing all old connection streams.

But In the case of QUIC protocol, It uses the UDP in the background, and when the packet losses then it uses forward error correction (FEC) which is similar to ARQ in TCP. But it does not block all the multiplexed stream pipelines another stream pipeline will still be able to send data to the client without blocking other stream pipelines.

Now, the major lead comes for QUIC protocol when establishing connection because it can able to establish just by sending a message. QUIC was created for faster and parallel transfer of data compared to TCP which is blocking in nature when a packet fails. And when the network change at the client-side then QUIC uses a connection ID which helps to establish connection just by sending a packet.

Now, we will know what is QUIC protocol is so, how we can create the QUIC protocol-based server let's understand the code.

const { createQuicSocket } = require('net');

For creating a QUIC protocol-based server, you need to import the createQuicSocket from the core net module of node.js v15.0.0. And you need to compile node.js binary with the experimental flag --experimental-quic.

'use strict';

const key = getTLSKeySomehow();
const cert = getTLSCertSomehow();

const { createQuicSocket } = require('net');

// Create the QUIC UDP IPv4 socket bound to local IP port 1234
const socket = createQuicSocket({ endpoint: { port: 1234 } });

socket.on('session', async (session) => {
  // A new server side session has been created!

  // The peer opened a new stream!
  session.on('stream', (stream) => {
    // Let's say hello
    stream.end('Hello World');

    // Let's see what the peer has to say...
    stream.setEncoding('utf8');
    stream.on('data', console.log);
    stream.on('end', () => console.log('stream ended'));
  });

  const uni = await session.openStream({ halfOpen: true });
  uni.write('hi ');
  uni.end('from the server!');
});

// Tell the socket to operate as a server using the given
// key and certificate to secure new connections, using
// the fictional 'hello' application protocol.
(async function() {
  await socket.listen({ key, cert, alpn: 'hello' });
  console.log('The socket is listening for sessions!');
})();

V8 Engine 8.6

We all know NodeJs is build on top of the V8 Engine. So, what new features come up in the V8 (8.6 version). As you maybe noticed that NodeJs doesn't support some new operators but is supported in a modern browser.

So, I want to let you aware that V8 gives some new javascript syntax as compiler support without that V8 doesn't know how to compile the new Syntax.

So, the first new Syntax support is Promise.any()

const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));

const promises = [promise1, promise2, promise3];

Promise.any(promises).then((value) => console.log(value));

// expected output: "quick"

What Promise.any() does is expect the array of promises as an argument. And it will return the first resolved promise as an output otherwise if all fail then it will reject the promise.

AggregateError

The second supported syntax is AggregateError

Promise.any([
  Promise.reject(new Error("some error")),
]).catch(e => {
  console.log(e instanceof AggregateError); // true
  console.log(e.message);                   // "All Promises rejected"
  console.log(e.name);                      // "AggregateError"
  console.log(e.errors);                    // [ Error: "some error" ]
});

What AggregateError does is when many errors occurred by an operator then it will be used to create an aggregated one Error as result.

Note- I have used Promise.any() for rejecting multiple values or Error by a single operator.

String.prototype.replaceAll()

This syntax is created for a more understandable syntax for finding all matching patterns and replacing all with the text.

const p = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';

const regex = /dog/gi;

console.log(p.replaceAll(regex, 'ferret'));
// expected output: "The quick brown fox jumps over the lazy ferret. If the ferret reacted, was it really lazy?"

console.log(p.replaceAll('dog', 'monkey'));
// expected output: "The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?"

Logical assignment operators &&=, ||=, and ??=

The logical AND assignment (a &&= b) operator only assigns if a is true.

let a = 1;
let b = 0;

a &&= 2;
console.log(a);
// expected output: 2

b &&= 2;
console.log(b);
// expected output: 0

The logical OR assignment (a ||= b) operator only assigns if a is false.

const a = { quantity: 50, title: '' };

a.quantity ||= 10;
console.log(a.quantity);
// expected output: 50

a.title ||= 'a.title is empty';
console.log(a.title);
// expected output: "a.title is empty"

The logical nullish assignment (a ??= b) operator only assigns if a is nullish (null or undefined).

const a = { duration: 50 };

a.duration ??= 10;
console.log(a.duration);
// expected output: 50

a.speed ??= 25;
console.log(a.speed);
// expected output: 25

And other V8-related changes are related to WebAssembly compiler supports. You can learn more from this blog.

Throw on unhandled rejections

From this Node.js v15.0.0 release, Node.js default mode for unhandledRejection is changed to "throw" from the "warn" state. From this version, unhandledrejection raises the uncaught exception in the absence of unhandledRejection hook. But you can still switch modes like throw, warn by using --unhandled-rejections=mode.

npm 7

Now the Node.js V15.0.0 comes with npm 7 which has many features like npm workspaces and new package.json format and now it also supports yarn.lock file. And npm 7 installs all peer dependencies by default.

N-API Version 7

In the N-API module NodeJs now gives some more new methods for working with ArrayBuffers. And N-API is used for building native Addons. And It is independent of the Javascript runtime (V8 Engine). You can learn more about this API in this NodeJs official blog.

AbortController

AbortController is used for aborting the promise-based web APIs by rejecting promise by raising the abort event. Still, this API is in the Experimental phase, but to know the understanding of that API you can check the browser-based example on MDN.

const ac = new AbortController();

ac.signal.addEventListener('abort', () => console.log('Aborted!'),
                           { once: true });

ac.abort();

console.log(ac.signal.aborted);  // Prints True

The above example is the Node.js official documentation example which you can learn in detail on that official blog.

So, that was the overview of some of the new features of Node.js V15.0.0.