Electron: From Beginner to Pro

Post on 21-Jan-2018

69 views 3 download

Transcript of Electron: From Beginner to Pro

ELECTRON:BEGINNER TO PRO

BUILD CROSS PLATFORM DESKTOP APPS USINGGITHUB’S ELECTRON

@chrisgriffith

WHAT IS ELECTRON?Released in July 2013 by Cheng ZhaoFoundation for GitHub Atom Editor

BUILT WITH ELECTRON

electronjs.org/apps

ELECTRON'S FEATURES

Automatic updatesNative menus & notificationsCrash reportingDebugging & profilingWindows installersjust a partial list…

PLATFORM SUPPORT

HOW DOES ELECTRON WORK?

UI?

INSTALLING ELECTRONnpm install -g electron

QUICK STARTgit clone https://github.com/electron/electron-quick-start quick-start

cd quick-start

git init

npm start

DEFAULT FILE STRUTURE index.html LICENSE.md main.js package.json README.md renderer.js

REAL WORLD FILE STRUTURE � app main.js splash.html splash.png � www � build � dist � node_modules package-lock.json package.json

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

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 })) …

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 }) }

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)

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>. …

INDEX.HTML… <script> // You can also require other files to run in this process require('./renderer.js') < /script>

WINDOWS

BROWSERWINDOW mainWindow = new BrowserWindow({ show: false, backgroundColor: "#FFF", width: 800, height: 600, minWidth: 800, maxWidth: 1024, minHeight: 600, maxHeight: 768, resizable: true, movable: true })

BROWSERWINDOWADDTIONAL 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?" })

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?", })

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 })

APPLICATION MENU

MENUS const Menu = electron.Menu

app.on('ready', function () { const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) createWindow() })

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' }] }]

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' }, { ...

CONTEXTUAL MENUS

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() })

INTER-PROCESSCOMMUNICATION

INTER-PROCESS COMMUNICATION

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!' })

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. } })

NATIVE DIALOGS

DIALOG TYPESFile OpenFile SaveMessage BoxError Box

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) }) })

DIALOG PROPERTIESopenFileopenDirectorymultiSelectionscreateDirectoryshowHiddenFilespromptToCreate (Windows Only)

MESSAGE BOXES

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' })

DIALOG TYPESinfoerrorquestionnone

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 })

WEBCONTENTS EVENTSbefore-input-eventcertificate-errorcontext-menucrashedcursor-changeddestroyeddevtools-closeddevtools-focuseddevtools-openeddevtools-reload-pagedid-change-theme-colordid-fail-loaddid-finish-loaddid-frame-finish-loaddid-get-response-detailsdid-get-redirect-requestdid-navigatedid-navigate-in-page

did-start-loadingdid-stop-loadingdom-readyfound-in-pageloginmedia-started-playingmedia-pausednew-windowpage-favicon-updatedpaintplugin-crashedselect-client-certificateselect-bluetooth-deviceupdate-target-urlwill-attach-webviewwill-navigatewill-prevent-unload

DEBUGGING YOUR ELECTRONAPPLICATION

Chromium’s Dev Tools

DEBUGGING RENDERERPROCESS

Chromium’s Dev Tools

DEBUGGING MAIN PROCESSVS Code's Toolsnode-inspector

DEVTRONAn Electron DevTools extension to help you inspect,

monitor, and debug your app.

TESTING WITH SPECTRON

INSTALLATION npm install --save-dev spectron

TEST SCRIPT npm install electron-builder --save-dev

BUILDING YOUR APPLICATION

INSTALLATION npm install electron-builder --save-dev

ADJUSTING YOUR BUILD DIRECTORIES

Build Platforms Descriptions--mac, -m, -o, --macos Build for macOS--win, -w, --windows Build for Windows--linux, -l Build for LinuxBuild Architectures Descriptions--x64 Build for x64--ia32 Build for ia32

UPDATING THE PACKAGE.JSONFILE

"scripts": { "start": "electron .", "dist": "build -mwl --x64 --ia32" }

UPDATING THE PACKAGE.JSONFILE

"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"] } }

UPDATING THE PACKAGE.JSONFILE

"main": "./app/main.js"

APP ICONS16px32px128px256px (OS X 10.5+)512px (OS X 10.5+)1024px (OS X 10.7+)

CONFIGURING THE MACOS DMG

CONFIGURING THE WINDOWS INSTALLER

AUTO-UPDATING

BUILT-INPlatform Update MethodmacOS Squirrel.MacWindows SquirrelLinux None

ELECTRON-UPDATERInstall electron-updater as an app dependency.

Use autoUpdater from electron-updater instead ofelectron

npm i electron-updater

import { autoUpdater } from "electron-updater"

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) => {})

ELECTRON FORGEA complete tool for building modern Electron

applications.

https://github.com/electron-userland/electron-forge

THANK YOU!Chris Griffith

San Diego, CA

@chrisgriffith

http://chrisgriffith.wordpress.com

https://github.com/chrisgriffith