Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Electron: From Beginner to Pro

237 views

Published on

Slides from my talk I was going to give at the 2017 SoCalCodeCamp.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Electron: From Beginner to Pro

  1. 1. ELECTRON: BEGINNER TO PRO BUILD CROSS PLATFORM DESKTOP APPS USING GITHUB’S ELECTRON @chrisgriffith
  2. 2. WHAT IS ELECTRON? Released in July 2013 by Cheng Zhao Foundation for GitHub Atom Editor
  3. 3. BUILT WITH ELECTRON electronjs.org/apps
  4. 4. ELECTRON'S FEATURES Automatic updates Native menus & notifications Crash reporting Debugging & profiling Windows installers just a partial list…
  5. 5. PLATFORM SUPPORT
  6. 6. HOW DOES ELECTRON WORK?
  7. 7. UI?
  8. 8. INSTALLING ELECTRON npm install -g electron
  9. 9. QUICK START git clone https://github.com/electron/electron-quick-start quick-start cd quick-start git init npm start
  10. 10. DEFAULT FILE STRUTURE index.html LICENSE.md main.js package.json README.md renderer.js
  11. 11. REAL WORLD FILE STRUTURE app main.js splash.html splash.png www build dist node_modules package-lock.json package.json
  12. 12. MAIN.JS const electron = require('electron') // Module to control application life. const app = electron.app // Module to create native browser window. const BrowserWindow = electron.BrowserWindow const path = require('path') const url = require('url') let mainWindow
  13. 13. CREATEWINDOW function createWindow () { // Create the browser window. mainWindow = new BrowserWindow({width: 800, height: 600}) // and load the index.html of the app. mainWindow.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true })) …
  14. 14. CREATEWINDOW … // Open the DevTools. mainWindow.webContents.openDevTools() // Emitted when the window is closed. mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null }) }
  15. 15. MAIN.JS // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', createWindow)
  16. 16. INDEX.HTML … <h1>Hello World!</h1> <!-- All of the Node.js APIs are available in this renderer process. --> We are using Node.js <script>document.write(process.versions.node) < /script>, Chromium <script>document.write(process.versions.chrome) < /script>, and Electron <script>document.write(process.versions.electron) < /script>. …
  17. 17. INDEX.HTML … <script> // You can also require other files to run in this process require('./renderer.js') < /script>
  18. 18. WINDOWS
  19. 19. BROWSERWINDOW mainWindow = new BrowserWindow({ show: false, backgroundColor: "#FFF", width: 800, height: 600, minWidth: 800, maxWidth: 1024, minHeight: 600, maxHeight: 768, resizable: true, movable: true })
  20. 20. BROWSERWINDOW ADDTIONAL PROPERTIES mainWindow = new BrowserWindow({ show: false, backgroundColor: "#FFF", width: 800, height: 600, minWidth: 800, maxWidth: 1024, minHeight: 600, maxHeight: 768, resizable: true, movable: true, alwaysOnTop: false, title: "Goodbye, Moon?" })
  21. 21. FRAMELESS WINDOWS mainWindow = new BrowserWindow({ show: false, backgroundColor: '#FFF', transparent: true, width: 800, height: 600, minWidth: 800, maxWidth: 1024, minHeight: 600, maxHeight: 768, resizable: true, movable: true, // frame: false, titleBarStyle: 'hidden' //hidden-inset // title: "Goodbye, Moon?", })
  22. 22. TRANSPARENT WINDOWS mainWindow = new BrowserWindow({ show: false, // backgroundColor: '#FFF', transparent: true, width: 800, height: 600, minWidth: 800, maxWidth: 1024, minHeight: 600, maxHeight: 768, resizable: true, movable: true, frame: false, transparent: true })
  23. 23. APPLICATION MENU
  24. 24. MENUS const Menu = electron.Menu app.on('ready', function () { const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) createWindow() })
  25. 25. MENU TEMPLATES let template = [{ label: 'Menu 1', submenu: [{ label: 'Menu item 1' }] }, { label: 'Menu 2', submenu: [{ label: 'Another Menu item' }, { label: 'One More Menu Item' }] }]
  26. 26. MENU ACCELERATORS & ROLES let template = [{ label: 'Edit App', submenu: [{ label: 'Undo', accelerator: 'CmdOrCtrl+Z', role: 'undo' }, { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo' }, { type: 'separator' }, { ...
  27. 27. CONTEXTUAL MENUS
  28. 28. CONTEXTUAL MENU - RENDERER.JS const { remote } = require('electron') const { Menu } = remote const myContextMenu = Menu.buildFromTemplate ([ { label: 'Cut', role: 'cut' }, { label: 'Copy', role: 'copy' }, { label: 'Paste', role: 'paste' }, { label: 'Select All', role: 'selectall' }, { type: 'separator' }, { label: 'Custom', click() { console.log('Custom Menu') } } ]) window.addEventListener('contextmenu', (event) => { event.preventDefault() myContextMenu.popup() })
  29. 29. INTER-PROCESS COMMUNICATION
  30. 30. INTER-PROCESS COMMUNICATION
  31. 31. IPC SYNC const ipc = require('electron').ipcRenderer syncMsgBtn.addEventListener('click', function () { const reply = ipc.sendSync('synchronous-message', 'Mr. Watson, come here }) const ipc = electron.ipcMain ipc.on('synchronous-message', function (event, arg) { event.returnValue = 'I heard you!' })
  32. 32. IPC ASYNC const ipc = require('electron').ipcRenderer asyncMsgBtn.addEventListener('click', function () { ipc.send('asynchronous-message', ''That's one small step for man') }) ipc.on('asynchronous-reply', function (event, arg) { const message = `Asynchronous message reply: ${arg}` document.getElementById('asyncReply').innerHTML = message }) const ipc = electron.ipcMain ipc.on('asynchronous-message', function (event, arg) { if (arg === 'That’s one small step for man') { event.sender.send('asynchronous-reply', ', one giant leap for mankind. } })
  33. 33. NATIVE DIALOGS
  34. 34. DIALOG TYPES File Open File Save Message Box Error Box
  35. 35. FILE OPEN const dialog = electron.dialog ipc.on('open-directory-dialog', function (event) { dialog.showOpenDialog({ properties: ['openDirectory'] }, function (files) { if (files) event.sender.send('selectedItem, files) }) })
  36. 36. DIALOG PROPERTIES openFile openDirectory multiSelections createDirectory showHiddenFiles promptToCreate (Windows Only)
  37. 37. MESSAGE BOXES
  38. 38. MESSAGE BOX dialog.showMessageBox({ type: info, buttons: ['Save', 'Cancel', 'Don't Save'], defaultId: 0, cancelId: 1, title: 'Save Score', message: 'Backup your score file?', detail: 'Message detail' })
  39. 39. DIALOG TYPES info error question none
  40. 40. CUSTOM ICONS const nativeImage = electron.nativeImage let warningIcon= nativeImage.createFromPath('images/warning.png') dialog.showMessageBox({ type: info, buttons: ['Save', 'Cancel', 'Don't Save'], defaultId: 0, cancelId: 1, title: 'Save Score', message: 'Backup your score file?', detail: 'Message detail', icon: warningIcon })
  41. 41. WEBCONTENTS EVENTS before-input-event certificate-error context-menu crashed cursor-changed destroyed devtools-closed devtools-focused devtools-opened devtools-reload-page did-change-theme-color did-fail-load did-finish-load did-frame-finish-load did-get-response-details did-get-redirect-request did-navigate did-navigate-in-page did-start-loading did-stop-loading dom-ready found-in-page login media-started-playing media-paused new-window page-favicon-updated paint plugin-crashed select-client-certificate select-bluetooth-device update-target-url will-attach-webview will-navigate will-prevent-unload
  42. 42. DEBUGGING YOUR ELECTRON APPLICATION Chromium’s Dev Tools
  43. 43. DEBUGGING RENDERER PROCESS Chromium’s Dev Tools
  44. 44. DEBUGGING MAIN PROCESS VS Code's Tools node-inspector
  45. 45. DEVTRON An Electron DevTools extension to help you inspect, monitor, and debug your app.
  46. 46. TESTING WITH SPECTRON
  47. 47. INSTALLATION npm install --save-dev spectron
  48. 48. TEST SCRIPT npm install electron-builder --save-dev
  49. 49. BUILDING YOUR APPLICATION
  50. 50. INSTALLATION npm install electron-builder --save-dev
  51. 51. ADJUSTING YOUR BUILD DIRECTORIES
  52. 52. Build Platforms Descriptions --mac, -m, -o, --macos Build for macOS --win, -w, --windows Build for Windows --linux, -l Build for Linux Build Architectures Descriptions --x64 Build for x64 --ia32 Build for ia32
  53. 53. UPDATING THE PACKAGE.JSON FILE "scripts": { "start": "electron .", "dist": "build -mwl --x64 --ia32" }
  54. 54. UPDATING THE PACKAGE.JSON FILE "build": { "appId": "com.your-company.electron-app-name", "copyright": "Copyright © 2017 YOUR-NAME", "productName": "My Electron App", "electronVersion": "1.4.1", "mac": { "category": "public.app-category.developer-tools" }, "win": { "target": [ "nsis" ] }, "linux": { "target": [ "AppImage", "deb"] } }
  55. 55. UPDATING THE PACKAGE.JSON FILE "main": "./app/main.js"
  56. 56. APP ICONS 16px 32px 128px 256px (OS X 10.5+) 512px (OS X 10.5+) 1024px (OS X 10.7+)
  57. 57. CONFIGURING THE MACOS DMG
  58. 58. CONFIGURING THE WINDOWS INSTALLER
  59. 59. AUTO-UPDATING
  60. 60. BUILT-IN Platform Update Method macOS Squirrel.Mac Windows Squirrel Linux None
  61. 61. ELECTRON-UPDATER Install electron-updater as an app dependency. Use autoUpdater from electron-updater instead of electron npm i electron-updater import { autoUpdater } from "electron-updater"
  62. 62. UPDATE EVENTS autoUpdater.on('checking-for-update', () => { }) autoUpdater.on('update-available', () => { }) autoUpdater.on('update-not-available', () => {}) autoUpdater.on('update-downloaded', () => {}) autoUpdater.on('error', (event, error) => {})
  63. 63. ELECTRON FORGE A complete tool for building modern Electron applications. https://github.com/electron-userland/electron-forge
  64. 64. THANK YOU! Chris Griffith San Diego, CA @chrisgriffith http://chrisgriffith.wordpress.com https://github.com/chrisgriffith

×