Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Cross-Platform Desktop Apps with Electron

Building Cross-Platform Desktop Apps with Electron

Despite the phenomenal popularity of web applications, there’s still a need for desktop applications that fit a certain class of functionality.

The fine folks at Github have developed a framework that allows developers the ability to build cross platform desktop applications using JavaScript. Join me as we take a whirlwind tour of Electron and discover what is possible today, on the desktop, using JavaScript.

We've seen JS in the browser, and then on the server and even on mobile. Is it finally time for JS on the desktop?

Gabriel Fortuna

July 16, 2016
Tweet

More Decks by Gabriel Fortuna

Other Decks in Programming

Transcript

  1. Electron // JSinSA 2016 • I am a JavaScript expert

    Gabriel Fortuna Chief Electron Officer Zero One About me
  2. Electron // JSinSA 2016 • I am a JavaScript expert

    • You can trust everything I tell you Gabriel Fortuna Chief Electron Officer Zero One About me
  3. Electron // JSinSA 2016 • I am a JavaScript expert

    • You can trust everything I tell you • I am an electron guru Gabriel Fortuna Chief Electron Officer Zero One About me
  4. Electron // JSinSA 2016 • I am a JavaScript expert

    • You can trust everything I tell you • I am an electron guru • I work for a small, but awesome dev company; Zero One Gabriel Fortuna Chief Electron Officer Zero One About me
  5. Electron // JSinSA 2016 Chromium’s rendering engine, and multi-process architecture

    V8’s speed, and ES6 compliance Node’s server-side capabilities and vast ecosystem The best of both all worlds 51.0.2704.106 * 6.1.0 5.1.281.65
  6. Electron // JSinSA 2016 Wait… why would I want to

    build a desktop app in electron in the first place?
  7. Electron // JSinSA 2016 Y Q When you need to

    initiate connections to services. Arbitrary APIs, etc. Direct access to APIs o z Sometimes users need to write to an actual filesystem on their local machines. File system access You require access to a local hardware device, e.g. scanners, joysticks, card readers, bluetooth Access to local hardware Why desktop? Utility that runs in the task tray (Win) or menu bar (macOS) Background apps
  8. Electron // JSinSA 2016 Y Q Firewalls get in the

    way, and doesn't make sense to run a web application. On premise access Offline data entry, editors, time management, media players, collab, mail Some apps just feel right o z When you need to make non-HTTP calls to remote services. Binary protocol access Desktop still the predominant place to run games Games Why desktop? (continued)
  9. Electron // JSinSA 2016  Only need to learn one

    framework Skip Cocoa, Win32, etc. Plus, you already know JS, HTML, and CSS. OS integration Native notifications, multi-windows, multi-monitor, global shortcuts, task switching, menus Code reuse Reuse frontend code. Reuse backend code if your backend is node* OK, but *why* in electron? What does electron bring to the table?  
  10. Electron // JSinSA 2016  0s latency app experience Read

    from a local db, and serialise thousands of objects with no latency. A new frontier Uncharted territory for traditional web developers. Debugging Did someone say Chrome dev tools? What does electron bring to the table?   OK, but *why* in electron?
  11. Electron // JSinSA 2016 cd my_awesome_electron_app npm init npm install

    electron-prebuilt —global # or npm install electron-prebuilt --save-dev { "name": "my_awesome_electron_app", "productName": "My Awesome Electron App", "version": "0.1.0", "main": "./main.js", "scripts": { "start": "electron ." }, "devDependencies": { "electron-prebuilt": "^1.2.6" } } 1. Initialise 2. Configure
  12. Electron // JSinSA 2016 const electron = require('electron'); const {app}

    = electron; const {BrowserWindow} = electron; let win; // Create a top level ref to the window, so it doesn't get garbage collected function createWindow() { win = new BrowserWindow({width: 800, height: 600}); // Create the browser window. win.loadURL(`file://${__dirname}/index.html`); // and load the index.html of the app. win.webContents.openDevTools(); // Open the DevTools. win.on('closed', () => { win = null; }); } app.on('ready', createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { // On macOS it is common for applications and their menu bar app.quit(); // to stay active until the user quits explicitly with Cmd + Q } }); app.on('activate', () => { if (win === null) { // On macOS it's common to re-create a window in the app when the createWindow(); // dock icon is clicked and there are no other windows open. } });
  13. Electron // JSinSA 2016 The UI <!DOCTYPE html> <html> <head>

    <meta charset="UTF-8"> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> We are using node <script>document.write(process.versions.node)</script>, Chrome <script>document.write(process.versions.chrome)</script>, and Electron <script>document.write(process.versions.electron)</script>. </body> </html>
  14. Electron // JSinSA 2016 Interprocess Comms const {ipcMain} = require('electron');

    ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg); // prints "ping" event.sender.send('asynchronous-reply', 'pong'); }); ipcMain.on('synchronous-message', (event, arg) => { console.log(arg); // prints "ping" event.returnValue = 'pong'; }); const {ipcRenderer} = require('electron'); console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong" ipcRenderer.send('asynchronous-message', 'ping'); ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg); // prints "pong" }); main process renderer process
  15. Electron // JSinSA 2016 Interprocess Comms const {ipcMain} = require('electron');

    ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg); // prints "ping" event.sender.send('asynchronous-reply', 'pong'); }); ipcMain.on('synchronous-message', (event, arg) => { console.log(arg); // prints "ping" event.returnValue = 'pong'; }); const {ipcRenderer} = require('electron'); console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong" ipcRenderer.send('asynchronous-message', 'ping'); ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg); // prints "pong" }); main process renderer process 1 2 3 4
  16. Electron // JSinSA 2016 Packaging npm install electron-packager -g electron-packager

    . my_awesome_electron_app --platform=darwin --arch=x64 --overwrite # or electron-packager . --all electron/grunt-electron-installer for Windows rakuten-frontend/grunt-appdmg for macOS
  17. Electron // JSinSA 2016 USEFUL CONCEPTS, TIPS, TRICKS & MINDSETS

    IT’S JUST LIKE THE WEB IT’S SO MUCH MORE THAN JUST THE WEB GHETTO PARALLELISM Traditional browser techniques still work, ergo: Responsive Desktop Apps! Require and use native modules from within a browser context! Exploit render processes to circumvent JS’ single- threadedness
  18. Electron // JSinSA 2016 Some things to be aware of…

    Your code isn't protected Old tutorials are old You’re firing up a chromium instance Tiny app doing 1 simple thing? > 50MB, #tyvm
  19. Electron // JSinSA 2016 Where to from here? Electron guides

    & official tutorial http://electron.atom.io/docs/guides/
  20. Electron // JSinSA 2016 Where to from here? Awesome Electron

    https://github.com/sindresorhus/awesome-electron
  21. Electron // JSinSA 2016 Where to from here? Apple Human

    Interface Guidelines http://apple.co/1BINnZB
  22. Electron // JSinSA 2016 Where to from here? Pair with

    me! http://www.meetup.com/Code-Coffee-JHB/