Build desktop apps with Electron

@h6165

Abhishek Yadav

ப்ரோக்ராமர்

Co-organizer: Chennai.js

Build desktop apps with Electron

Using Javascript

🤘

Electron


const { app, BrowserWindow } = require('electron');

app.on('ready', () => {
  var mainWindow = new BrowserWindow()
  mainWindow.loadURL('http://chennai-js.org')
}

Electron

my-app
|
|-- index.js
|
|-- package.json
|
|-- index.html

{
  "name"    : "my-app",
  "version" : "0.1.0",
  "main"    : "index.js"
}

electron .

Electron

Electron

Points to note

Electron

  • Its a node.js application
  • Electron is an npm package. 
    • Gives the electron executable
  • It loads a url in the window
  • The Window is like a browser (actually Chromium)
  • Electron is combining Node.js and Chrome somehow

Points to note

Electron


const { app, BrowserWindow } = require('electron');

app.on('ready', () => {
  var mainWindow = new BrowserWindow()
  mainWindow.loadURL('http://chennai-js.org')
}

1. node.js require

2. app has events

3. window opens here

4. window can open a url

The Big Picture

Electron

Credit: http://jlord.us/essential-electron/#how-even-

Essential Electron : great summary by @jllord

Electron

A Little more code

Electron


const { app, BrowserWindow } = require('electron');

let mainWindow;

app.on('ready', () => {
  mainWindow = new BrowserWindow()
  mainWindow.loadURL('file://' + __dirname + '/index.html')
}

A Little more code

Electron

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    <div id='the-size'></div>

    <script>
      const fs = require('fs');
      var size = fs.statSync('./index.html').size;

      var el = document.getElementById('the-size');
      el.innerHTML = "The size is: " + size;
    </script>

  </body>
</html>

Electron

Take another look

Electron

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    <div id='the-size'></div>

    <script>
      const fs = require('fs');
      var size = fs.statSync('./index.html').size;

      var el = document.getElementById('the-size');
      el.innerHTML = "The size is: " + size;
    </script>

  </body>
</html>

node.js in browser

DOM manipulation

Chrome devtools

Electron

node.js in browser

Cmd Shift i

The two process model

Electron

  • Electron starts a separate process for the browser window - the renderer process
  • There is one separate main node.js process
  • There is one more process (for GPU handling etc), (that are not relevant here)
  • This is similar to Chrome's process model

The two process model

Electron

Renderer

HTML CSS JS

Renderer

HTML CSS JS

Renderer

HTML CSS JS

Main

Native API

IPC

IPC

IPC

The two process model

Electron

The two process model

Electron

  • Renderer process handles the UI.
  • Only a subset of Electron APi is available to renderer
  • Main process handles the native API calls
    • Things like opening windows, dialogs etc
  • Main enables communication between renderers
  • Node.js APIs are available to both

Create multiple windows

Electron


const { app, BrowserWindow } = require('electron');
let windows = [];

function createWindow(url, shift){
  var rand = Math.floor(Math.random()*500);
  const w = new BrowserWindow({x: rand, y: rand})
  w.loadURL(url)
  windows.push(w)
}

app.on('ready', () => {
  createWindow('file://' + __dirname + '/index.html')
  createWindow('http://www.chennai-js.org')
});

Electron

Standard Api features

  • Clipboard integration
  • Desktop Capture
  • Crash reporting
  • Dock integration (Mac)
  • JumpList integration (Win)
  • Printing to PDF
  • Chrome debugger integration
    •  
  • The main process can be debugged with
    • VS Code
    • node-inspector

Electron

win.webContents.debugger.sendCommand('Network.enable')

Standard Api features

  • Creating asar archives (archive with obfuscation)
  • ffmpeg support
  • <webview> for guest content (eg code snippets)
  • locale support with Indian languages
  • Global shortcuts
  • Drop upload
  • Flameless windows
  • Drag files to app
  • Download management
  • ContentTracing for finding performance bottlenecks

Electron

Tools and Libraries

  • UI Kits
  • Debugging
  • Testing and CI
  • Packaging and releasing

Electron

UI Kits - Photon

  • Provides markup, css, fonts to help make beautiful UI
  • Just link the CSS, and add the elements

Electron

Electron

      <header class="toolbar toolbar-header">
        <h1 class="title">Header with actions</h1>

        <div class="toolbar-actions">
          <div class="btn-group">
            <button class="btn btn-default">
              <span class="icon icon-home"></span>
            </button>
            <button class="btn btn-default">
              <span class="icon icon-folder"></span>
            </button>
            <button class="btn btn-default active">
              <span class="icon icon-cloud"></span>
            </button>
            <button class="btn btn-default">
              <span class="icon icon-popup"></span>
            </button>
            <button class="btn btn-default">
              <span class="icon icon-shuffle"></span>
            </button>
          </div>

          <button class="btn btn-default btn-dropdown pull-right">
            <span class="icon icon-megaphone"></span>
          </button>
        </div>
      </header>

UI Kits - Photon

Electron

UI Kits - Photon

Electron

UI Kits/libraries - Others

React PhotonKit Photon components built with React. 
React Desktop UI toolkit for macOS and Windows built with React. 
chrome-tabs Chrome like tabs. 
electron-positioner Position windows at common spots.
electron-drag Improved dragging

Debugging - devtron

Electron

Debugging - extensions

Electron

The following extensions work -

  • Ember Inspector
  • React Developer Tools
  • Backbone Debugger
  • jQuery Debugger
  • AngularJS Batarang
  • Vue.js devtools
  • Cerebral Debugger
  • Redux DevTools Extension

Debugging - others

Electron

debug-menu Chrome like 'inspect element'
electron-debug keyboard shortcuts for devtools
electron-is-dev check if we are in dev mode
electron-detach Restart an Electron app as a detached process. 
electron-log Logging

Packaging/release

Electron

  • Challenges -
    • Package the code for various OS. From various OS
    • Distribution - installers, App Store submission
    • Release and updates
  • Everything is covered

Packaging/release

Electron

electron-packager Package and distribute
electron-builder Create installers
electron-gh-release Auto-update by releasing on GitHub
electron-release Publish a new release to GitHub
electron-updater Auto-updater leveraging npm to deploy updates
nuts Releases server with auto-updater
electron-release-server Self-hosted release server with front-end
electron-installer-debian Create a Debian package
electron-installer-redhat Create a Red Hat package
electron-installer-windows Create a Windows package

Testing/CI

Electron

  • spectron - Testing framework
  • electron-mocha - Mocha tests
  • bozon - boilerplate (includes build, test, etc)
  • CI: use xvfb

Testing/CI

Electron

  it('opens a window', function () {
    return this.app.client.waitUntilWindowLoaded()
      .getWindowCount().should.eventually.equal(1)
      .browserWindow.isMinimized().should.eventually.be.false
      .browserWindow.isDevToolsOpened().should.eventually.be.false
      .browserWindow.isVisible().should.eventually.be.true
      .browserWindow.isFocused().should.eventually.be.true
      .browserWindow.getBounds().should.eventually.have.property('width').and.be.above(0)
      .browserWindow.getBounds().should.eventually.have.property('height').and.be.above(0)
  })

spectron - example

Other libraries

Electron

electron-dl manage downloads (without boilerplate)
electron-localshortcut shortcuts without menu
auto-launch Auto launch the app at startup
NeDB Embedded persistent or in memory database. 
menubar Create menubar apps with ease

The coolest thing: menubar

Electron

var menubar = require('menubar')

var mb = menubar()

mb.on('ready', function ready () {
  console.log('app is ready')
})

The coolest thing: menubar

Electron

Problems / Gotchas

Electron

  • Symbol clash with libraries
    • Jquery, Angular, Meteor define some symbols used by node - module, exports, require
    • There is a fix
  • People have complained Electron apps are memory heavy (Slack, Atom etc)

Thanks

Made with Slides.com