developing desktop apps
w/ electron + ember
fitc: web unleashed (sep 25 2017)
© Isle of Code Inc.@anulman - #WEBU17
why write hybrid apps?
• app store distribution
• decouple a long-lived app from browser tabs
• use system ui, like alerts & menu / task bars
• use system resources, like fs & gpu
2
© Isle of Code Inc.@anulman - #WEBU17
notable examples
• atom
• slack
• brave
• ghost
• visual studio code
• gitkraken
3
© Isle of Code Inc.@anulman - #WEBU17
things we will learn
• intro to electron
• what it is + why you’d use it
• architecture
• disclaimers
• spa frameworks + electron
• intro to electron-forge
• what it is + why you’d use it
• spa frameworks + electron-forge
4
© Isle of Code Inc.@anulman - #WEBU17
things we will learn (cont’d)
• building an app with ember-electron
• init
• livereload shell
• packaging / distributing
• testing
• extending your electron app
• global shortcuts + dialogs
• app icon
• app signing + autoupdate
• useful libs for electron apps
• render-vendor
• fs-storage-utils (beta!)
5
© Isle of Code Inc.@anulman - #WEBU17
plug: corber.io
• this presentation = desktop apps
• mobile hybrid w/ spas should use corber.io (beta):
• currently for ember, vue, glimmer apps + cordova
• handles framework + app build & validations, w/o
affecting existing web flows
• includes on-device livereload, + utility functions for
icons & plugins
• when needed, can proxy to the cordova cli
6
© Isle of Code Inc.@anulman - #WEBU17
btw hi i’m aidan
• partner & polyglot @ isle of code
• @anulman on twitter, github, etc
• maintainer w/ember-electron
• + contribs on electron-forge, electron-installer-debian…
• when not hacking, i’m:
• on my bicycle
• at a concert
• cooking
7
intro to electron
© Isle of Code Inc.@anulman - #WEBU17
what it is + why you’d use it
• oss framework to compose cross-platform desktop
apps from node.js apis + chromium windows
• originally extracted from github’s atom editor
• learned from predecessors:
• chromium embedded framework
• nw.js
10
© Isle of Code Inc.@anulman - #WEBU17
electron architecture
• offers simultaneous control of node.js & chromium runtimes
• comes pre-packaged with js wrappers for several common
host os apis:
• system tray
• autoupdate
• keyboard shortcuts w/ & w/o focus
• many pre-packaged js wrappers are available only in the node
runtime / are sandboxed from chromium (renderer) procs
11
© Isle of Code Inc.@anulman - #WEBU17
disclaimers re: electron / hybrid
• “serves” via fs, so paths should not start with `/`
• architecture should minimize platform-specific code
• be careful! you have full privileges of host OS
• e.g. remote code execution is hecka dangerous
• memory leaks are a major issue, as no req / response cycle to
refresh state:
• unresolved / rejected promises
• lingering refs to dom nodes…
12
© Isle of Code Inc.@anulman - #WEBU17
spa frameworks + electron
• spa frameworks offer shared context to ui code
• enforces clear divide between renderer + main
proc code
• benefit from upstream perf + feature work
13
intro to electron-forge
© Isle of Code Inc.@anulman - #WEBU17
what it is + why you’d use it
• wraps best community build tools (e.g. for
livereload, packaging, generating distributables)
• init’ed oct 2016; first major / stable releases dec
2016
15
© Isle of Code Inc.@anulman - #WEBU17
spa frameworks + electron-forge
• e-forge ships with react + ng templates
• e-forge exposes its apis for consumption by other build
tools / pipelines
• ember-electron 2.x was one of the first build tools to proxy
e-forge’s apis
• ember-electron also provides electron-aware testing env
• h/t @felixrieseberg (slack + electron core) + e-electron
community :)
17
building an app with
ember-electron
© Isle of Code Inc.@anulman - #WEBU17
init
19
© Isle of Code Inc.@anulman - #WEBU17
init
• `ember install ember-electron`
• (or `ember g ember-electron`)
• runs `electron-forge init .`, + some other config
• https://github.com/felixrieseberg/ember-electron/blob/master/blueprints/ember-electron/index.js
20
© Isle of Code Inc.@anulman - #WEBU17
init (cont’d)
21
© Isle of Code Inc.@anulman - #WEBU17
init (cont’d)
• introduces `ember-electron` dir
• inits an `ember-electron/main.js` file
• reads config from `ember-electron/.electron-forge`
• commands will add `ember-electron` dir to broccoli build
• incls merged `resources-` dir
• updates package.json per forge expectations, iff
values dne
22
© Isle of Code Inc.@anulman - #WEBU17
livereload shell
• `ember electron`
• electron equivalent to `ember s`
• proxies api for `electron-forge start`
• https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/electron.js
23
© Isle of Code Inc.@anulman - #WEBU17
livereload shell (cont’d)
24
© Isle of Code Inc.@anulman - #WEBU17
livereload shell (cont’d)
• builds app js to `electron-out/project` & symlinks deps
• runs built js with prebuilt & compiled electron bin via `electron-
forge#start`
• watches ember app + `ember-electron` dir for changes
• installs ember inspector to renderer windows
• useful options:
• —environment
• --output-path
25
© Isle of Code Inc.@anulman - #WEBU17
packaging / distributing
• `ember electron:package`
• `ember electron:make`
• electron equivalent to `ember build`
• proxies apis for `electron-forge [package|make]`
• all inherits from generic e-electron build cmd
• https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/build.js
• https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/package.js
• https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/make.js
26
© Isle of Code Inc.@anulman - #WEBU17
packaging / distributing
(cont’d)
27
© Isle of Code Inc.@anulman - #WEBU17
packaging / distributing
(cont’d)
• `ember build`s app (incl electron) to tmp dir
• installs package.json deps (n.b. no devDeps)
• passes built tmp dir to specified forge api
• cleans up tmp dir
28
© Isle of Code Inc.@anulman - #WEBU17
packaging / distributing
(cont’d)
• useful options:
• --environment
• --arch, --platform
• --output-path
• --skip-package
• --targets
29
© Isle of Code Inc.@anulman - #WEBU17
testing
• `ember electron:test`
• electron equivalent to `ember test`
• https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/electron-test.js
30
© Isle of Code Inc.@anulman - #WEBU17
testing (cont’d)
31
© Isle of Code Inc.@anulman - #WEBU17
testing (cont’d)
• passes args to ember test cmd + task to load
runner in electron shell
• permits acceptance testing main proc behaviour
32
extending your electron app
© Isle of Code Inc.@anulman - #WEBU17
global shortcuts + dialogs
• shortcuts & dialogs are restricted to main proc
• preference is to handle in `main.js`
• if handling in `BrowserWindow`:
`require(‘electron’).remote.globalShortcut(…)`
• dialogs have several types:
• `showOpenDialog`
• `showSaveDialog`
• `showMessageBox`
• `showErrorBox`
34
© Isle of Code Inc.@anulman - #WEBU17
global shortcuts + dialogs
(cont’d)
35
© Isle of Code Inc.@anulman - #WEBU17
app icon
• create icon files
• mac: *.icns
• win: *.ico
• linux: *.png
• add config to forge’s packager options (mac / win)
• add `icon: ‘path/to/icon’` to `BrowserWindow` init in electron.js
(linux)
• omit extension to auto-configure ext by platform
36
© Isle of Code Inc.@anulman - #WEBU17
app icon (cont’d)
37
© Isle of Code Inc.@anulman - #WEBU17
app signing + autoupdates
• signing apps is strongly encouraged, though not technically req’d
• configure app signing:
• mac: `osxSign` param of `electronPackagerConfig`
• win: `electronWinstallerConfig`
• linux: pray to cthulhu
• make executable:
• `ember electron:make`
• publish executable, e.g. via github release / s3
38
© Isle of Code Inc.@anulman - #WEBU17
app signing + autoupdates
(cont’d)
• mac + win apps can autoupdate with squirrel
• deploy & configure nuts server: https://github.com/GitbookIO/
nuts
• proxies & caches distributable assets
• exposes api for e.g.
• `/download/latest`
• `/download/latest/:os`
• `/download/:version`
39
© Isle of Code Inc.@anulman - #WEBU17
app signing + autoupdates
(cont’d)
• in main proc,
`electron.autoUpdater.checkForUpdates()`
• n.b. this checks & downloads in one op
• if win, must handle squirrel events immediately on
boot
• e.g. `require(‘electron-squirrel-startup’)`
40
useful libs for electron apps
© Isle of Code Inc.@anulman - #WEBU17
render-vendor
• custom point-of-sale app needed to print receipts,
stickers, hangtags
• ideal pipeline: html => pdf => printer
• traditional js pdf tooling: 2-3s latency between user
action + print output
• 90+% of latency due to html => pdf step
43
© Isle of Code Inc.@anulman - #WEBU17
render-vendor (cont’d)
44
© Isle of Code Inc.@anulman - #WEBU17
render-vendor (cont’d)
• render-vendor “renderers” load html templates into
long-lived “pages”
• can be used as cli app, or `require` into .js files
• after initial boot + render, jobs take < 50ms
• html => pdf => printer output now feels
instantaneous
45
© Isle of Code Inc.@anulman - #WEBU17
fs-storage-plus (beta)
• app needed to sign into third party services
• ideal solution would store cookies + user creds for
reuse between boots
• fs-storage-plus implements localstorage API with fs
storage backend
• encrypted storage class (constructor) extends
base with crypto + node-keytar libs to generate,
cycle, and securely persist encryption keys
46
© Isle of Code Inc.@anulman - #WEBU17
tl;dr
• electron is a popular and proven lib / framework to
create hybrid desktop applications
• electron-forge (+ ember-electron) offers a painless
cli integration
• any system / server node module (e.g. fs) is
available in electron processes
• leverage native features (e.g. parallel procs,
networked printing, keychain) for better ux
47
© Isle of Code Inc.@anulman - #WEBU17
links
• https://electron.atom.io
• https://github.com/felixriesberg/ember-electron
• https://github.com/electron-userland/electron-forge
• http://render-vendor.com
• https://www.npmjs.com/package/fs-storage-plus
49

Developing Desktop Apps with Electron & Ember.js

  • 1.
    developing desktop apps w/electron + ember fitc: web unleashed (sep 25 2017)
  • 2.
    © Isle ofCode Inc.@anulman - #WEBU17 why write hybrid apps? • app store distribution • decouple a long-lived app from browser tabs • use system ui, like alerts & menu / task bars • use system resources, like fs & gpu 2
  • 3.
    © Isle ofCode Inc.@anulman - #WEBU17 notable examples • atom • slack • brave • ghost • visual studio code • gitkraken 3
  • 4.
    © Isle ofCode Inc.@anulman - #WEBU17 things we will learn • intro to electron • what it is + why you’d use it • architecture • disclaimers • spa frameworks + electron • intro to electron-forge • what it is + why you’d use it • spa frameworks + electron-forge 4
  • 5.
    © Isle ofCode Inc.@anulman - #WEBU17 things we will learn (cont’d) • building an app with ember-electron • init • livereload shell • packaging / distributing • testing • extending your electron app • global shortcuts + dialogs • app icon • app signing + autoupdate • useful libs for electron apps • render-vendor • fs-storage-utils (beta!) 5
  • 6.
    © Isle ofCode Inc.@anulman - #WEBU17 plug: corber.io • this presentation = desktop apps • mobile hybrid w/ spas should use corber.io (beta): • currently for ember, vue, glimmer apps + cordova • handles framework + app build & validations, w/o affecting existing web flows • includes on-device livereload, + utility functions for icons & plugins • when needed, can proxy to the cordova cli 6
  • 7.
    © Isle ofCode Inc.@anulman - #WEBU17 btw hi i’m aidan • partner & polyglot @ isle of code • @anulman on twitter, github, etc • maintainer w/ember-electron • + contribs on electron-forge, electron-installer-debian… • when not hacking, i’m: • on my bicycle • at a concert • cooking 7
  • 9.
  • 10.
    © Isle ofCode Inc.@anulman - #WEBU17 what it is + why you’d use it • oss framework to compose cross-platform desktop apps from node.js apis + chromium windows • originally extracted from github’s atom editor • learned from predecessors: • chromium embedded framework • nw.js 10
  • 11.
    © Isle ofCode Inc.@anulman - #WEBU17 electron architecture • offers simultaneous control of node.js & chromium runtimes • comes pre-packaged with js wrappers for several common host os apis: • system tray • autoupdate • keyboard shortcuts w/ & w/o focus • many pre-packaged js wrappers are available only in the node runtime / are sandboxed from chromium (renderer) procs 11
  • 12.
    © Isle ofCode Inc.@anulman - #WEBU17 disclaimers re: electron / hybrid • “serves” via fs, so paths should not start with `/` • architecture should minimize platform-specific code • be careful! you have full privileges of host OS • e.g. remote code execution is hecka dangerous • memory leaks are a major issue, as no req / response cycle to refresh state: • unresolved / rejected promises • lingering refs to dom nodes… 12
  • 13.
    © Isle ofCode Inc.@anulman - #WEBU17 spa frameworks + electron • spa frameworks offer shared context to ui code • enforces clear divide between renderer + main proc code • benefit from upstream perf + feature work 13
  • 14.
  • 15.
    © Isle ofCode Inc.@anulman - #WEBU17 what it is + why you’d use it • wraps best community build tools (e.g. for livereload, packaging, generating distributables) • init’ed oct 2016; first major / stable releases dec 2016 15
  • 17.
    © Isle ofCode Inc.@anulman - #WEBU17 spa frameworks + electron-forge • e-forge ships with react + ng templates • e-forge exposes its apis for consumption by other build tools / pipelines • ember-electron 2.x was one of the first build tools to proxy e-forge’s apis • ember-electron also provides electron-aware testing env • h/t @felixrieseberg (slack + electron core) + e-electron community :) 17
  • 18.
    building an appwith ember-electron
  • 19.
    © Isle ofCode Inc.@anulman - #WEBU17 init 19
  • 20.
    © Isle ofCode Inc.@anulman - #WEBU17 init • `ember install ember-electron` • (or `ember g ember-electron`) • runs `electron-forge init .`, + some other config • https://github.com/felixrieseberg/ember-electron/blob/master/blueprints/ember-electron/index.js 20
  • 21.
    © Isle ofCode Inc.@anulman - #WEBU17 init (cont’d) 21
  • 22.
    © Isle ofCode Inc.@anulman - #WEBU17 init (cont’d) • introduces `ember-electron` dir • inits an `ember-electron/main.js` file • reads config from `ember-electron/.electron-forge` • commands will add `ember-electron` dir to broccoli build • incls merged `resources-` dir • updates package.json per forge expectations, iff values dne 22
  • 23.
    © Isle ofCode Inc.@anulman - #WEBU17 livereload shell • `ember electron` • electron equivalent to `ember s` • proxies api for `electron-forge start` • https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/electron.js 23
  • 24.
    © Isle ofCode Inc.@anulman - #WEBU17 livereload shell (cont’d) 24
  • 25.
    © Isle ofCode Inc.@anulman - #WEBU17 livereload shell (cont’d) • builds app js to `electron-out/project` & symlinks deps • runs built js with prebuilt & compiled electron bin via `electron- forge#start` • watches ember app + `ember-electron` dir for changes • installs ember inspector to renderer windows • useful options: • —environment • --output-path 25
  • 26.
    © Isle ofCode Inc.@anulman - #WEBU17 packaging / distributing • `ember electron:package` • `ember electron:make` • electron equivalent to `ember build` • proxies apis for `electron-forge [package|make]` • all inherits from generic e-electron build cmd • https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/build.js • https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/package.js • https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/make.js 26
  • 27.
    © Isle ofCode Inc.@anulman - #WEBU17 packaging / distributing (cont’d) 27
  • 28.
    © Isle ofCode Inc.@anulman - #WEBU17 packaging / distributing (cont’d) • `ember build`s app (incl electron) to tmp dir • installs package.json deps (n.b. no devDeps) • passes built tmp dir to specified forge api • cleans up tmp dir 28
  • 29.
    © Isle ofCode Inc.@anulman - #WEBU17 packaging / distributing (cont’d) • useful options: • --environment • --arch, --platform • --output-path • --skip-package • --targets 29
  • 30.
    © Isle ofCode Inc.@anulman - #WEBU17 testing • `ember electron:test` • electron equivalent to `ember test` • https://github.com/felixrieseberg/ember-electron/blob/master/lib/commands/electron-test.js 30
  • 31.
    © Isle ofCode Inc.@anulman - #WEBU17 testing (cont’d) 31
  • 32.
    © Isle ofCode Inc.@anulman - #WEBU17 testing (cont’d) • passes args to ember test cmd + task to load runner in electron shell • permits acceptance testing main proc behaviour 32
  • 33.
  • 34.
    © Isle ofCode Inc.@anulman - #WEBU17 global shortcuts + dialogs • shortcuts & dialogs are restricted to main proc • preference is to handle in `main.js` • if handling in `BrowserWindow`: `require(‘electron’).remote.globalShortcut(…)` • dialogs have several types: • `showOpenDialog` • `showSaveDialog` • `showMessageBox` • `showErrorBox` 34
  • 35.
    © Isle ofCode Inc.@anulman - #WEBU17 global shortcuts + dialogs (cont’d) 35
  • 36.
    © Isle ofCode Inc.@anulman - #WEBU17 app icon • create icon files • mac: *.icns • win: *.ico • linux: *.png • add config to forge’s packager options (mac / win) • add `icon: ‘path/to/icon’` to `BrowserWindow` init in electron.js (linux) • omit extension to auto-configure ext by platform 36
  • 37.
    © Isle ofCode Inc.@anulman - #WEBU17 app icon (cont’d) 37
  • 38.
    © Isle ofCode Inc.@anulman - #WEBU17 app signing + autoupdates • signing apps is strongly encouraged, though not technically req’d • configure app signing: • mac: `osxSign` param of `electronPackagerConfig` • win: `electronWinstallerConfig` • linux: pray to cthulhu • make executable: • `ember electron:make` • publish executable, e.g. via github release / s3 38
  • 39.
    © Isle ofCode Inc.@anulman - #WEBU17 app signing + autoupdates (cont’d) • mac + win apps can autoupdate with squirrel • deploy & configure nuts server: https://github.com/GitbookIO/ nuts • proxies & caches distributable assets • exposes api for e.g. • `/download/latest` • `/download/latest/:os` • `/download/:version` 39
  • 40.
    © Isle ofCode Inc.@anulman - #WEBU17 app signing + autoupdates (cont’d) • in main proc, `electron.autoUpdater.checkForUpdates()` • n.b. this checks & downloads in one op • if win, must handle squirrel events immediately on boot • e.g. `require(‘electron-squirrel-startup’)` 40
  • 42.
    useful libs forelectron apps
  • 43.
    © Isle ofCode Inc.@anulman - #WEBU17 render-vendor • custom point-of-sale app needed to print receipts, stickers, hangtags • ideal pipeline: html => pdf => printer • traditional js pdf tooling: 2-3s latency between user action + print output • 90+% of latency due to html => pdf step 43
  • 44.
    © Isle ofCode Inc.@anulman - #WEBU17 render-vendor (cont’d) 44
  • 45.
    © Isle ofCode Inc.@anulman - #WEBU17 render-vendor (cont’d) • render-vendor “renderers” load html templates into long-lived “pages” • can be used as cli app, or `require` into .js files • after initial boot + render, jobs take < 50ms • html => pdf => printer output now feels instantaneous 45
  • 46.
    © Isle ofCode Inc.@anulman - #WEBU17 fs-storage-plus (beta) • app needed to sign into third party services • ideal solution would store cookies + user creds for reuse between boots • fs-storage-plus implements localstorage API with fs storage backend • encrypted storage class (constructor) extends base with crypto + node-keytar libs to generate, cycle, and securely persist encryption keys 46
  • 47.
    © Isle ofCode Inc.@anulman - #WEBU17 tl;dr • electron is a popular and proven lib / framework to create hybrid desktop applications • electron-forge (+ ember-electron) offers a painless cli integration • any system / server node module (e.g. fs) is available in electron processes • leverage native features (e.g. parallel procs, networked printing, keychain) for better ux 47
  • 49.
    © Isle ofCode Inc.@anulman - #WEBU17 links • https://electron.atom.io • https://github.com/felixriesberg/ember-electron • https://github.com/electron-userland/electron-forge • http://render-vendor.com • https://www.npmjs.com/package/fs-storage-plus 49