Back to articles

Electron. Asynchrony, Modules and C/C++

There are a lot of posts about NodeJS describing innovative solutions for JavaScript on the server side. However, there is another place where JavaScript, V8 and Chrome HTML engines can be applied. That place is your desktop, and Electron is a technology that makes it possible to create desktop applications with JavaScript/HTML. I’m sure most of us already have experience in Electron. I’m sure that everybody who is reading has at least one Electron based application on this desktop. And some of that applications are really awesome. For example, Visual Studio Code, Slack, and Atom were the beginning of the Electron platform. So I’m a little late with this post, but let me share some of my problems and the way to solve them.

What is Electron?

According to documentation Electron is NodeJS and Chromium turning on the same V8 engine. As a result, we have something like the possibility to run node modules in the browser. That allows us to access the local file system or use any C/C++ modules.

Any Electron application has at least two processes, one main process, and one or more renderers. The main process is a pure NodeJS process and entry point of the application. The main process is responsible for the creation of windows and every window has it’s own renderer process.

In the renderer process, you are inside the Chrome browser but with the power of NodeJS.

You can easily communicate between processes with IPC. Electron gives you a very simple API for this.

I think that is more than enough about Electron to have a general picture of it. You can try it with this tutorial http://electron.atom.io/docs/tutorial/quick-start/.

Asynchronous operations

It is very hard to imagine modern desktop operations without asynchronous operations. We need to show progress while loading something, we need to perform background calculations and many other features like these. However, Electron is not so good in asynchronous operations.

One of the first ideas to do something in an async way is to send IPC message to the main window and wait for results. You may not believe me if I say that this may freeze your UI, but consider the following sample:

https://github.com/peleshenko/freezing_node_sample

Clone it runs npm install and execute run.sh.

When we are trying to freeze UI with a long running loop you can not type in the input field but css animation is working, and you can close the window. But when we are trying to freeze the application with a long-running loop in the main process even css animation is frozen, and you can not close the window.

Amazing!

You can review the corresponding discussion on Electron page on github https://github.com/electron/electron/issues/3363

Short answer:

... a blocking operation in main process is easy to block all other processes... ...it is required to put IO and CPU-bound operations in new threads to avoid this...

So the first lesson learns — forget about the main process, live it alone, this process is for Chromium not for you, use your own.

Next idea is to use WebWorkers. Electron supports WebWorkers. But unfortunately in WebWorkers you have no access to NodeJS. You can use the usual browser API, or calculate something, but not NodeJS. That fact makes WebWorkers useless in Electron because most operations that require async execution are related to file systems or other external things.

So there is only one way to start something in a parallel thread using JavaScript is child_process.fork. Not very simple but working way.

Alternatively, you can create C/C++ addons and do anything you want inside this addon with C++, start any number of threads and dispatch results to Electron’s message loop with the callback. But that is another story…

C/C++ Addons

As you can see, addons is not something unusual, even a simple async operation may require addon creation. An additional reason that may enforce you to implement your own addon with C/C++ is the quality of existing addons in npm. Some of them are really terrible.

After my last word, I think you recall your last attempt at npm module installation on Windows. You had to install a specific version of VisualStudio and Python 2.7. My first reaction was: “What? The module author is crazy, he is going to mix C++, Python and NodeJS. Give me another module…”. But all modules that have C/C++ code inside will require Python and VisualStudio and sometimes a specific version of VisualStudio.

You need all this software to install the module because NodeJS builds a system node-gyp. That is the only way to include C/C++ addon to your npm module. That is a strange thing, but if you take a look a little deeper you will understand the reason. But let me leave this topic for another post.

OK, finally you installed VisualStudio and Python and installed the module. Starting your Electron application and see the following in the dev tools console (numbers may differ):

Module version mismatch. Expected 48, got 47"

The source of that problem is that the node addon is only compatible with exactly the same node version that this addon has been built for. And you just have built it for your NodeJS, but Electron has a little different NodeJS version inside. Doh!!!

To solve the problem, you can use electron-rebuild. Follow the instruction and you will be able to rebuild the required module for NodeJS version used in Electron.

And the last…

That is it about Electron and problems with it in general. We have more and more projects with Electron in Tesseris Pro. So I hope to share my experience in C/C++ addons and React in Electron in the next posts.

And once more. Electron is Chromium + NodeJS, thus it already has NodeJS module system and that system is not so bad. And as for me, it looks very strange when people try to use system.js or require.js or any other JavaScript module system to load modules in Electron. Electron is not a browser! It is NodeJS + browser! Use it as NodeJS!

It also could be interesting to You

How do we achieve the highest efficiency in software development in Kvinivel

As many of our clients already know, we are doing fixed-price projects. Starting from requirements preparation and finishing with delivery and initial support. We have a lot of success stories, and all our customers are…

Why do I like fixed-price projects?

We have been delivering software development services at Kvinivel for more than 8 years. During this time, I learned one interesting thing. We tried different kinds of cooperation namely outstaffing, outsourcing, some mixed things, time…