• New Node.js 12 features will see it disrupt AI, IoT and more surprising areas
  • By Adam Polak
  • Translation from: The Gold Project
  • This article is permalink: github.com/xitu/gold-m…
  • Translator: Badd
  • Proofreader: Alfxjx, CYZ980908

New node.js features will disrupt AI, the Internet of Things, and many more amazing areas

The new version of Node.js features are not the same as the platform’s previous selling points. Node.js mainly uses itsQuick and conciseIs famous for. This is why so many companies are willing to try Node.js. However, with the latest LTS (Long-term Support) release, Node.js will bring many new features that will make every Node.js developer ecstatic. Why is that? Because the new features and possibilities of Node.js 12 are amazing!

Multithreading tends to stabilize!

In the last LTS release, we have been able to use multithreading. Admittedly, this is an experimental feature that requires a flag called –experimental-worker.

In the upcoming LTS version (Node 12), multi-threading is still experimental, but it no longer relies on the experimental-worker flag. Stable version is coming to us!

Support for ES module

We need to recognize the fact that ES modules are currently the only way to develop JavaScript. We use it in front-end applications. We use it in desktop and mobile applications. In node.js, however, we’re stuck with common.js.

Of course, we still have Babel and TypeScript available, but since Node.js is a back-end technology, all we should care about is whether the version of Node installed on the server is up to date. We don’t have to worry about the various browsers and node.js support for them, so what’s the point of installing tools (Babel, Webpack, etc.) designed specifically for this purpose?

In Node 10, we are finally able to experiment with the ES module (the current LTS version has a pilot implementation of the module), but we need to use a specific file extension –.mjs (the module JavaScript code file).

Using the ES module is a little easier in Node 12. Just as in Web apps, we can use a proprietary property type to define whether a piece of code should be treated as common.js or as an ES module.

To use all files as modules, you simply add the type attribute to package.json and assign the value module.

{
  "type": "module"
}
Copy the code

From now on, if the package.json file closest to the.js file has the type attribute, those.js files will exist as modules. Goodbye you, MJS (you can still use it if you want to)!

So, what if we want to use common.js style modules?

As long as the nearest package.json does not contain the module attribute type, it will be considered code that follows the common.js specification.

In addition, we can use a new type of extension file called CJS — which stands for a common.js file.

Each MJS file is an ES module, and each CJS file is a common.js file.

If you haven’t tried this spoonful yet, try it now!

JavaScript and private variables

When it comes to JavaScript, there is always a need to prevent data leakage in a class or function.

JavaScript is known for its Monkey patching, which means we always have access to all the data through some sort of gateway.

We have tried to simulate private variables with closures, symbols, and so on. Node 12 is loaded with a new version of the V8 engine, so we have the opportunity to use a cool feature — private properties in classes.

I’m sure you all remember the old way of implementing privacy in Node:

class MyClass {
  constructor() {
    this._x = 10
  }
  
  get x() {
    return this._x
  }
}
Copy the code

We all know that this is not really private — we can always get our hands on it — but most ides treat it as a private field, and most Node developers know this convention. Now we can finally put that behind us.

class MyClass {
  #x = 10
  
  get x() {
    return this.#x
  }
}
Copy the code

Can you see the difference? Yes, we use # to tell Node that the variable is private and can only be accessed from within the class.

If you try to access it directly, you will see an error message saying that the variable does not exist.

Sadly, some ides do not currently recognize such private variables.

Flat and flatMap

In Node 12, we can enjoy the new features of JavaScript.

First, we can use the new methods of arrays – flat and flatMap. The former is similar to Lodash’s mathematical depth approach.

If you pass a nested array into a method, you get an expanded array.

[10[20.30], [40.50[60.70]]].flat() // => [10, 20, 30, 40, 50, [60, 70]]
[10[20.30], [40.50[60.70]]].flat(2) // => [10, 20, 30, 40, 50, 60, 70]
Copy the code

As you can see, this method also has a special parameter — depth. This parameter determines the depth at which the nested array will be reduced in dimension.

The second new feature, flatMap, acts like the map method is executed first, followed by the flat. 🙂

Optional Catch binding

Another new feature is the Optional Catch Binding. Previously, we always needed to define an error variable for a try-catch.

try {
  someMethod()
} catch(err) {
  // The err variable is required
}
Copy the code

In Node 12, we can’t completely get rid of try-catch statements, but we can get rid of error variables.

try {
  someMethod()
} catch {
  // The err variable is optional
}
Copy the code

Object.fromEntries

Another new feature is the object.fromentries method. Its primary purpose is to create an object from a Map or an array of key-value pairs.

Object.fromEntries(new Map([['key'.'value'], ['otherKey'.'otherValue']]));
// { key: 'value', otherKey: 'otherValue' }


Object.fromEntries([['key'.'value'], ['otherKey'.'otherValue']]);
// { key: 'value', otherKey: 'otherValue' }
Copy the code

V8 engine changes

As I mentioned, the new version of Node comes with a V8 engine. This allows Node to support not only private variables, but also some performance tuning features.

Await will run as fast as Javascript parsing.

With support for stack tracing, our application will load faster and the Async code will be easier to debug.

In addition, the size of the Heap is changing. Previously, it was 700MB (on 32-bit systems) or 1400MB (on 64-bit systems). As the new version brings changes, the heap size will depend on the amount of available memory!

Node 12 is here!

I don’t know if you’re looking forward to it, but I’m looking forward to it. We’re still a few months away from the official LTS release of Version 12 (the release date is set for October 2019), but the list of new features we’ll be getting is definitely promising.

Only a few months!

One of the biggest things about the new Version of Node.js is multithreading!

Each programming language has its pros and cons, which we all can’t argue with. Most popular technologies have their place in the tech world. Node.js is no exception.

We’ve been saying for years that Node.js is suitable for API Gateways and real-time dashboards (such as WebSocket-based). In fact, Node’s design forces us to rely on a microservice architecture to compensate for its common flaws.

Over time, we’ve learned that because of its single-threaded design, Node.js is not suited for tasks that are time-consuming, cpu-heavy, or blocking operations. This is a problem with the event loop itself.

If there is a complex synchronization operation that blocks the event loop, nothing else can be done until the operation is complete. This is why we often use Async or move time-consuming logic into a separate microservice.

With the new features in Node.js 10, this stopgap will no longer be necessary. The magic tool is Worker Thread. Because of this, Node.js will be able to shine in areas where we would normally use other languages.

Artificial intelligence, machine learning, or big data are good examples of this. At the moment, these areas of research require a lot of CPU power, leaving us no choice but to build more services or change to a more appropriate language. But with the new version of Node.js, everything is different.

Support multi-threading? How did you do that?

This new feature is still experimental — it’s not ready for use in production. But we can still play around. So where to start?

Starting with Node 12 and beyond, we no longer need to use a specific feature flag –experimental-worker. The Worker will be activated by default!

node index.js

Now we can make full use of the worker_Threads module. Let’s write a simple HTTP server with two methods:

  • GET /hello (returns a JSON object with a “Hello World” message),
  • GET /compute (use a synchronous method to repeatedly load a large JSON file).
const express = require('express');
const fs = require('fs');

const app = express();

app.get('/hello', (req, res) => {
  res.json({
    message: 'Hello world! '})}); app.get('/compute', (req, res) => {
  let json = {};
  for (let i=0; i<100; i++) { json =JSON.parse(fs.readFileSync('./big-file.json'.'utf8'));
  }

  json.data.sort((a, b) = > a.index - b.index);

  res.json({
    message: 'done'})}); app.listen(3000);
Copy the code

The results of this code are easy to predict. When GET /compute and /hello are called at the same time, we have to wait for the compute call to complete before we GET a response from Hello. The event loop is blocked until the file is loaded.

Let’s use multithreading to optimize!

const express = require('express');
const fs = require('fs');
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');

if (isMainThread) {
  console.log("Spawn http server");

  const app = express();

  app.get('/hello', (req, res) => {
    res.json({
      message: 'Hello world! '})}); app.get('/compute', (req, res) => {

    const worker = new Worker(__filename, {workerData: null});
    worker.on('message', (msg) => {
      res.json({
        message: 'done'
      });
    })
    worker.on('error'.console.error);
	  worker.on('exit', (code) => {
		if(code ! =0)
          console.error(new Error(`Worker stopped with exit code ${code}`))}); }); app.listen(3000);
} else {
  let json = {};
  for (let i=0; i<100; i++) { json =JSON.parse(fs.readFileSync('./big-file.json'.'utf8'));
  }

  json.data.sort((a, b) = > a.index - b.index);

  parentPort.postMessage({});
}
Copy the code

Obviously, this syntax is very similar to what we know about Node.js cluster extensions. But here’s where it gets interesting.

You can try to call both paths at once. Notice anything? . Yes, the event loop is no longer blocked, so we can call /hello during file loading.

Now, this is what we’ve all been waiting for! All that’s left is to wait for a stable version of the API.

Itching for more new Node.js features? This N-API is capable of building C/C++ modules!

The native speed of Node.js is one of the reasons we love this technology. Worker Threads will speed up Node.js even further. But is that enough?

Node.js is a C-based technology. Of course, we use JavaScript as a major programming language. But what if we could do more complicated calculations in C?

Node.js 10 brings us n-API. This is a standardized API for native modules, making it possible to build modules in C/C++ or even Rust. Sounds great, right?

Building native Node.js modules in C/C++ has become much easier.

Here is a very simple example of a native module:

#include <napi.h>
#include <math.h>

namespace helloworld {
    Napi::Value Method(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        return Napi::String::New(env, "hello world");
    }

    Napi::Object Init(Napi::Env env, Napi::Object exports) {
        exports.Set(Napi::String::New(env, "hello"),
                    Napi::Function::New(env, Method));
        return exports;
    }

    NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
}
Copy the code

If you have the basics of C++, writing a custom module is a breeze. Just remember to convert the C++ type to node.js at the end of the module.

Next we need a binding:

{
    "targets": [{"target_name": "helloworld"."sources": [ "hello-world.cpp"]."include_dirs": ["
      ]."dependencies": ["
      ]."defines": [ 'NAPI_DISABLE_CPP_EXCEPTIONS']]}}Copy the code

This simple configuration allows us to build a *.cpp file for later use in node.js applications.

Before we can use the JavaScript code, we have to build and configure the package.json file to find the GYp file (binding file).

{
  "name": "n-api-example"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "install": "node-gyp rebuild"
  },
  "gypfile": true."keywords": []."author": ""."license": "ISC"."dependencies": {
    "node-addon-api": "^ 1.5.0." "."node-gyp": "^ 3.8.0." "}}Copy the code

When the module is ready, we can build it with the Nod-gyp rebuild command and import it into the JavaScript code. The usage is the same as other popular modules!

const addon = require('./build/Release/helloworld.node');

console.log(addon.hello());
Copy the code

N-api and Worker Threads give us powerful tools to help us build high-performance applications. Not to mention apis or dashboards — even complex data processing or machine learning systems will be readily available. How wonderful!

Also see: Swoole — Is it Node in PHP?

Will Node.js fully support HTTP/2? Of course! Why not?

We can do it faster. We can do distributed computing. How about resources and page services?

For years, we’ve been stuck with good but outdated HTTP modules and HTTP/1.1. As the server has more and more resources to provide, we are more and more constrained by the time it takes to load. Each browser has a maximum number of concurrent persistent connections per server or proxy server, especially under HTTP/1.1. With support for HTTP/2, we can kiss this problem goodbye.

So where do we start? Do you remember the basic Node.js example that appears in every tutorial online? Yes, here it is:

const http = require('http');

http.createServer(function (req, res) {
  res.write('Hello World! ');
  res.end();
}).listen(3000);
Copy the code

In Node.js 10, there’s a brand new HTTP2 module that lets us use HTTP/2.0! It’s HTTP/2.0!

const http = require('http2');
const fs = require('fs');

const options = {
  key: fs.readFileSync('example.key'),
  cert: fs.readFileSync('example.crt')}; http.createSecureServer(options,function (req, res) {
  res.write('Hello World! ');
  res.end();
}).listen(3000);
Copy the code

What we have in mind is full support for HTTP/2 in Node.js 10.

These new features should make the future of Node.js bright

The new features of Node.js inject new blood into our technology ecosystem. They’re giving Node.js wings and flying it to new worlds. Do you think this technology could one day be used for image recognition or data science? It never occurred to me.

This version of Node.js also brings many more long-awaited features, such as support for the ES module (though still experimental); And the update to the FS method, which finally allows us to break out of callback hell and embrace Promise heaven.

Want to know more about new Node.js features? Check out this short video.

In the line chart below, we can see that after years of growth, The popularity of Node.js peaked in early 2017. This is not a sign that growth is slowing, but a sign that the technology is maturing.

Either way, it’s clear to me that all of these new improvements and the popularity of Node.js blockchain applications (based on the Trutruffle. Js framework) could give Node.js a further boost, allowing it to thrive in new types of projects, roles and environments.

The NODE.js team at TSH (The Software House) is looking forward to 2020!

If you find any errors in the translation or other areas that need improvement, you are welcome to revise and PR the translation in the Gold Translation program, and you can also get corresponding bonus points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


Diggings translation project is a community for translating quality Internet technical articles from diggings English sharing articles. The content covers the fields of Android, iOS, front end, back end, blockchain, products, design, artificial intelligence and so on. For more high-quality translations, please keep paying attention to The Translation Project, official weibo and zhihu column.