Node.js 10.x released - What's NEW?

By: (plus.google.com) +David Herron; Date: April 24, 2018

Tags: Node.JS

After a year of development Node.js 10 has been released. It represents a huge step forward because of some high profile features and fixes. In October Node.js 10 will become the active Long Term Support branch, with 11.x becoming the new experimental branch. Let's take a look at what's been included.

Async/Await functions and ES6 Modules

For me these are the prominent features achieved in Node.js 10. I've spent the last 6+ months updating my book, Node.js Web Development, to the 4th edition, with the primary motivation being these two features. Which means that for the last 6 months I've been explaining to my future readers the importance of these two features. Please be understanding that I'm leading with this.

With the addition of ES6 modules in 9.x and async/await functions in 8.x, the adoption of ES2015/2016 features is pretty much complete. See the full status at (node.green) http://node.green/

The advantage of async functions is turning a "callback hell" situation like this:

router.get('/path/to/something', (req, res, next) => {
    doSomething(arg1, arg2, (err, data1) => {
       if (err) return next(err);
       doAnotherThing(arg3, arg2, data1, (err2, data2) => {
         if (err2) return next(err2);
         somethingCompletelyDifferent(arg1, arg42, (err3, data3) => {
           if (err3) return next(err3);
           doSomethingElse((err4, data4) => {
             if (err4) return next(err4);
             res.render('page', { data });
           });
         });
       });
    });
});

Into this:

router.get('/path/to/something', async (req, res, next) => {
    try {
        let data1 = await doSomething(req.query.arg1, req.query.arg2);
        let data2 = await doAnotherThing(req.query.arg3, req.query.arg2, data1);
        let data3 = await somethingCompletelyDifferent(req.query.arg1, req.query.arg42);
        let data4 = await doSomethingElse();
        res.render('page', { data1, data2, data3, data4 });
    } catch(err) {
        next(err); 
    }
});

Which would you rather maintain and debug?

The try/catch is required here because it is an Express router function, and these functions do not know an async function from a regular function. Instead you inform Express of errors with next(err), so we must use the try/catch block to make it work.

As for ES6 modules, the advantage is that all JavaScript programmers now share the same module format. ES6 modules work in both browsers and on Node.js. Well ...

Whether these modules or any other ES2015/2016/2017 feature works in browsers depends on the newness of the browser. Obviously there are still lots of old computers with old web browsers installed on which ES5 is the supported JavaScript.

In any case, what's an ES6 module look like?

var count = 0;
export function next() { return ++count; }
function squared() { return Math.pow(count, 2); }
export function hello() {
    return "Hello, world!";
}
export default function() { return count; }
export const meaning = 42;
export let nocount = -1;
export { squared };

Node.js has traditionally used CommonJS modules where things are exported by assigning them to the module.exports object. We have nearly 10 years experience with CommonJS modules in Node.js. The code snippet here shows several variations of ES6 module export syntax.

A thing is exported from a ES6 module with the export statement. The export default statement defines the default export from the module, while the others are all named exports.

If that module were named simple2.mjs then it could be used as so:

import * as simple2 from './simple2.mjs';
console.log(simple2.hello());
console.log(`${simple2.next()} ${simple2.squared()}`);
console.log(`${simple2.next()} ${simple2.squared()}`);
console.log(`${simple2.default()} ${simple2.squared()}`);
console.log(`${simple2.next()} ${simple2.squared()}`);
console.log(`${simple2.next()} ${simple2.squared()}`);
console.log(`${simple2.next()} ${simple2.squared()}`);
console.log(simple2.meaning);

And it executes like so:

$ node --experimental-modules simpledemo.mjs
(node:63937) ExperimentalWarning: The ESM module loader is experimental. Hello, world!
11
24
24
39
4 16
5 25
42

See: (nodejs.org) https://nodejs.org/dist/latest-v10.x/docs/api/esm.html

Promise.finally

The Promise object came with Node.js 4.x, and helped us begin our journey out of callback hell.

Initially Promise had two methods, then and catch to deal with whether a Promise resolved to a success state or rejection state. But there are other possible processing patterns that can be implemented on the Promise object. The continued use of the Bluebird library demonstrates that other needs are required. Promise.finally is one such need.

The idea here is a pattern similar to

try {
    some code
} catch (e) {
    handle errors
} finally {
    code that always executes whether or not an error is thrown
}

With Promise.finally we get:

let isLoading = true;

fetch(myRequest).then(function(response) {
    var contentType = response.headers.get("content-type");
    if(contentType && contentType.includes("application/json")) {
      return response.json();
    }
    throw new TypeError("Oops, we haven't got JSON!");
  })
  .then(function(json) { /* process your JSON further */ })
  .catch(function(error) { console.log(error); })
  .finally(function() { isLoading = false; });

In other words, you have code executing in then and catch as we expect currently, and the code in finally is then executed irregardless of errors.

Experimental promisified fs functions

Until now if you wanted sanity with fs module functions you had to use the fs-extra package. That 3rd party package offered a superset of the fs functions, and all its functions returned Promises rather than forcing you to use Callbacks.

We all want the convenience of async functions, which in turn requires widespread conversion from the Callback paradigm to the return-a-Promise paradigm. The Node.js baked-in modules include lots of functions using the Callback paradigm. Switching over to async functions requires switching all the backed-in modules to support returning Promises.

Included in the util module is a util.promisify function that aids with converting functions to return Promises.

Instead of require('fs') you use require('fs/promises'). From there you have the same API as the fs module, but the functions return Promises rather than forcing you to use Callbacks.

See: (nodejs.org) https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_promises_api

HTTP/2 is now stable

HTTP/2 was developed from the earlier SPDY protocol. It supports a large number of improvements like pipelining of requests, compressing headers, multiplexing multiple requests over a single connection, and so on.

See: (nodejs.org) https://nodejs.org/api/http2.html

Improved cryptography

Node.js 10 includes an update to OpenSSL 1.1.0. This lets Node.js support more cipers and authenticators than before. The team expects to update to OpenSSL 1.1.1 before October, which will bring in support for TLS 1.3.

N-API eases burden on native code modules

An issue with native code Node.js modules has been API breakage between Node.js versions. With N-API, which is now non-experimental, that's a thing of the past. The ABI, Application Binary Interface, will remain the same from release to release.

One impact has been that running npm install resulted in a node_modules directory that worked only with a specific Node.js release. With N-API one could presumably use different platform releases on the same node_modules directory.

The N-API support is being back-ported to Node.js 6.x and 8.x release trains as well.

See: (nodejs.org) https://nodejs.org/dist/latest-v10.x/docs/api/n-api.html

Improved error messages

Currently the only way to distinguish one thrown Error from another is to inspect the strings. That leads to situations like:

try {
    execute buggy code
} catch (err) {
    if (err.message === 'This is th message') {
        do something
    } else {
        co something else
    }
}

In other words, we're matching strings, including typos, to distinguish errors. That's bad.

With the new error support we'd instead write:

try {
    execute buggy code
} catch (err) {
    if (err.code === 'ERR_INVALID_URL_SCHEME') {
        do something
    } else {
        co something else
    }
}

This is far more consistent and expressive.

See: (medium.com) https://medium.com/the-node-js-collection/node-js-errors-changes-you-need-to-know-about-dc8c82417f65

See: (nodejs.org) https://nodejs.org/dist/latest-v10.x/docs/api/errors.html

A new npm is promised soon

While Node.js 10.0 ships with npm 5.6.x, the team is promising npm 6.x to arrive soon.

This npm release includes a bunch of improvements.

A new command, npm audit, will incorporate checks for packages with known security problems.

Performance improvements are claimed.

See: (medium.com) https://medium.com/npm-inc/announcing-npm-6-5d0b1799a905

Node.js performance improvements

As always, Node.js releases include updates to the V8 engine, and Google is constantly moving it forward.

This time around they're working to improve performance of async functions and promises.

« Avoid killing performance with asynchronous ES7 JavaScript async/await functions Use Bash-like command-line environment variables on Windows in Node.js npm scripts »
2016 Election 2018 Elections Acer C720 Ad block Air Filters Air Quality Air Quality Monitoring AkashaCMS Amazon Amazon Kindle Amazon Web Services America Amiga and Jon Pertwee Android Anti-Fascism AntiVirus Software Apple Apple Hardware History Apple iPhone Apple iPhone Hardware April 1st Arduino ARM Compilation Artificial Intelligence Astronomy Astrophotography Asynchronous Programming Authoritarianism Automated Social Posting AWS DynamoDB AWS Lambda Ayo.JS Bells Law Big Brother Big Data Big Finish Big Science Bitcoin Mining Black Holes Blade Runner Blockchain Blogger Blogging Books Botnets Cassette Tapes Cellphones China China Manufacturing Christopher Eccleston Chrome Chrome Apps Chromebook Chromebox ChromeOS CIA CitiCards Citizen Journalism Civil Liberties Climate Change Clinton Cluster Computing Command Line Tools Comment Systems Computer Accessories Computer Hardware Computer Repair Computers Conservatives Cross Compilation Crouton Cryptocurrency Curiosity Rover Currencies Cyber Security Cybermen Cybersecurity Daleks Darth Vader Data backup Data Formats Data Storage Database Database Backup Databases David Tenant DDoS Botnet Department of Defense Department of Justice Detect Adblocker Developers Editors Digital Nomad Digital Photography Diskless Booting Disqus DIY DIY Repair DNP3 Do it yourself Docker Docker MAMP Docker Swarm Doctor Who Doctor Who Paradox Doctor Who Review Drobo Drupal Drupal Themes DVD E-Books E-Readers Early Computers eGPU Election Hacks Electric Bicycles Electric Vehicles Electron Eliminating Jobs for Human Emdebian Encabulators Energy Efficiency Enterprise Node EPUB ESP8266 Ethical Curation Eurovision Event Driven Asynchronous Express Face Recognition Facebook Fake News Fedora VirtualBox Fifth Doctor File transfer without iTunes FireFly Flash Flickr Fraud Freedom of Speech Front-end Development G Suite Gallifrey git Github GitKraken Gitlab GMAIL Google Google Chrome Google Gnome Google+ Government Spying Great Britain Green Transportation Hate Speech Heat Loss Hibernate High Technology Hoax Science Home Automation HTTP Security HTTPS Human ID I2C Protocol Image Analysis Image Conversion Image Processing ImageMagick In-memory Computing InfluxDB Infrared Thermometers Insulation Internet Internet Advertising Internet Law Internet of Things Internet Policy Internet Privacy iOS Devices iPad iPhone iPhone hacking Iron Man iShowU Audio Capture iTunes Janet Fielding Java JavaFX JavaScript JavaScript Injection JDBC John Simms Journalism Joyent Kaspersky Labs Kext Kindle Kindle Marketplace Large Hadron Collider Lets Encrypt LibreOffice Linux Linux Hints Linux Single Board Computers Logging Mac Mini Mac OS Mac OS X Machine Learning Machine Readable ID Macintosh macOS macOS High Sierra macOS Kext MacOS X setup Make Money Online March For Our Lives MariaDB Mars Mass Violence Matt Lucas MEADS Anti-Missile Mercurial MERN Stack Michele Gomez Micro Apartments Microsoft Military AI Military Hardware Minification Minimized CSS Minimized HTML Minimized JavaScript Missy Mobile Applications Mobile Computers MODBUS Mondas Monetary System MongoDB Mongoose Monty Python MQTT Music Player Music Streaming MySQL NanoPi Nardole NASA Net Neutrality Network Attached Storage Node Web Development Node.js Node.js Database Node.js Performance Node.js Testing Node.JS Web Development Node.x North Korea npm NVIDIA NY Times Online advertising Online Community Online Fraud Online Journalism Online Photography Online Video Open Media Vault Open Source Open Source and Patents Open Source Governance Open Source Licenses Open Source Software OpenAPI OpenJDK OpenVPN Palmtop PDA Patrick Troughton PayPal Paywalls Personal Flight Peter Capaldi Peter Davison Phishing Photography PHP Plex Plex Media Server Political Protest Politics Postal Service Power Control President Trump Privacy Production use Public Violence Raspberry Pi Raspberry Pi 3 Raspberry Pi Zero ReactJS Recaptcha Recycling Refurbished Computers Remote Desktop Removable Storage Republicans Retro Computing Retro-Technology Reviews RFID Rich Internet Applications Right to Repair River Song Robotics Robots Rocket Ships RSS News Readers rsync Russia Russia Troll Factory Russian Hacking Rust SCADA Scheme Science Fiction SD Cards Search Engine Ranking Season 1 Season 10 Season 11 Security Security Cameras Server-side JavaScript Serverless Framework Servers Shell Scripts Silence Simsimi Skype SmugMug Social Media Social Media Networks Social Media Warfare Social Network Management Social Networks Software Development Software Patents Space Flight Space Ship Reuse Space Ships SpaceX Spear Phishing Spring Spring Boot Spy Satellites SQLite3 SSD Drives SSD upgrade SSH SSH Key SSL Stand For Truth Strange Parts Swagger Synchronizing Files Tegan Jovanka Telescopes Terrorism The Cybermen The Daleks The Master Time-Series Database Tom Baker Torchwood Total Information Awareness Trump Trump Administration Trump Campaign Twitter Ubuntu Udemy UDOO US Department of Defense Virtual Private Networks VirtualBox VLC VNC VOIP Vue.js Walmart Weapons Systems Web Applications Web Developer Resources Web Development Web Development Tools Web Marketing Webpack Website Advertising Weeping Angels WhatsApp William Hartnell Window Insulation Windows Windows Alternatives Wordpress World Wide Web Yahoo YouTube YouTube Monetization