Atom Electron – my first experiences

I am thrilled by the spread of the javascript language all over many places. From being a browser language to becoming the most popular language in the world makes me happy. Frameworks like Node.js have really pushed this development, and even Microsoft now sees node.js as a serious player in the world of software development.

Atom Electron – formerly known as Atom Shell

One of the places where javascript is playing a role is in the cross platform scene. Developing using javascript in browser has always been cross platform. Node.js made web servers javascript based and thereby also cross platform. On the desktop scene we have also seen node-webkit (now called NW) which lets you create desktop applications using Node.js and HTML.

Atom Electron is equal to NW, and offers a cross platform

Node.js

, HTML, CSS, Javascript application development platform.

Here I will share my notes from my first go at writing a desktop application using Atom Electron,

Installation – (OSX)

This is how I got Electron up and running on my Mac. I did a NPM install and downloaded rebuild binaries.

NPM

In a terminal window I wrote:
sudo npm install electron-prebuilt -g

Runtime – install and run once using Ctrl-click “open”

Electron requires a runtime, so I downloaded an OS X app – from Electron github releases page. I found out that the version to install on OS X is the “..darwin-x64.zip” file. Simply download and unarchive the zip file. I then moved the Electron.app to the programs/apps folder (in practice installing the app).

As the app is downloaded from an unknown source the app will not run if you click it. You need to Ctrl+click and choose “Open” to execute the file. Using this approach has the advantage that you can also launch apps it from a terminal window without using “sudo” (administrator) command.

Ready for “Hello world”

I almost always do a “hello world”, and simply copy’n’paste any hello world code. Electron has a simple Quick start page which takes you through this start up process.

One thing which I did was to make NPM build the package.son for me. So after I had made the main.js file I ran this command in the terminal:
NPM init
and answered all the question of cause.

Running the application

There are various ways of running your application, it is a matter of taste which one you prefer. You can run it through the terminal, you can open the Electron app and drag your application to the launch window or you can change the system to let you open it from finder.

Launch using terminal

  1. Open a terminal in the folder of your app
  2. If your app is named “main.js” fire this command:

 /Applications/Electron.app/Contents/MacOS/Electron main.js 

Then you app should open a window with your hello world app. You may have to prefix the command with the sudo command.

Convert precompiled Electron.app into your app

Just discovered that the Electron app is actually just a runtime which should be used for your app too. So reading the Application distribution page I tried to do this:

  1. Renamed my app folder to “app
  2. Moved my app folder to “/Applications/Electron.app/Contents/Resources
  3. Renamed the “Electron app” to “HelloWorld.app”.

This makes the Electron app in my application folder into my hello world app, and it can now be started as other native desktop apps! For instance I can Ctrl-Space and type “HelloWorld” + enter and thereby launch my Electron app, cute!

Debugging using console.log – where can I see the log?

In javascript I use heavily console.log  to write out debug information. So I also did in my main.js file, but where did the information goto? It seems that currently you need to run the app from the terminal to see the logged information.
To recap, I launch my app like this: /Applications/HelloWorld.app/Contents/MacOS/Electron main.js

Execute client side javascript from your app

In my hello world app I loaded a website into the window. I wanted to extract images from that page to data-uri (base64 encoded images) and therefore the images should be loaded, but the page had made a trick. They used a data attribute “data-src” as the actual image src. I then needed to do client side javascript which would copy the data-src into the image src.

The BrowserWindow object was used to open a new window, and I then listened on the webContent “did-finish-load” event. After that triggered the web content was loaded, and I could execute some javascript code. Here is my code:

 

// Create the browser window. mainWindow = new BrowserWindow({ width: 800, height: 600 });</p>
<p>mainWindow.webContents.on('did-finish-load', function () { var code = "var img = document.querySelectorAll(\"img[data-src]\");"; code += "[].forEach.call(img, function (ele) {"; code += " ele.src = ele.getAttribute(\"data-src\")"; code += "})"; this.executeJavaScript(code); });</p>
<p>mainWindow.loadUrl("http://www.dr.dk");

This is not beautiful – the way that the javascript is added to a string and the executed, however it is okay at a first-go, and it actually works! :-)

Of cause! Loading a file is as simple as using node.js fs package

 

var fs = require('fs'); // Include Node.js file system package mainWindow.webContents.on('did-finish-load', function () { var code = "var img = document.querySelectorAll(\"img[data-src]\");"; code += "[].forEach.call(img, function (ele) {"; code += " ele.src = ele.getAttribute(\"data-src\")"; code += "})"; this.executeJavaScript(code); var webcontent = this; // Save webContents for later use fs.readFile(__dirname + '/lib/imagesSideBySideInSVGBase64.js', 'utf8', function (err, data) { if (err) { return console.log("ERROR" + err); } var imagesSideBySideInSVGBase64 = data; // The external JS code found in file webcontent.executeJavaScript(imagesSideBySideInSVGBase64); }); });

So, I forgot – we are in a node.js context so all the nice packages can be used inside your app. So I put a JS file inside a lib folder, and using the global variable “__dirname” I can build the path to the javascript file. Node.js has some global runtime variables for you which are very handy.

 

“Some philosophical point of views

Electron is so great! You can finally build desktop apps using your favorite tools, like you do when doing front-end implementation of webpages. Webpages have transformed into full blown native cross platform applications! Did you know that Slack app is written in that manner? That is according to “Build on Electron” page on the Electron github page.

With Electron (and NW.js) w

ebpages have transformed into full blown native cross platform applications!

Which makes me think: Should we consist distinguish between front-end and back-end developers? I know that often front-end developers are more focused on UI and UX, where as back-end developers tend to be more focused on logic and data structure (said in a simple manner). Anyway this (front-end) developer will try this new field of opportunities doing HTML, CSS and javascript based desktop app development.

I expect that we will see a whole lot of inspiring new cross platform desktop apps when we let out front-end developers to the formerly back-end developer territory. Like when Microsoft released Visual Basic. I for one believe that much of the success of windows platform was because Visual Basic eased the access into desktop app development, and millions of more or less simple windows apps was programmed by new programmer types. Most of the apps were more or less useless, but they were important anyhow, shaking the mindset of all developers on the platform.

Links – resources

US

Leave a Reply