|
| 1 | +# Recipes |
| 2 | + |
| 3 | +## Icons |
| 4 | + |
| 5 | +> Customize your app's launcher and tray icon |
| 6 | +
|
| 7 | +[Example Repo](https://github.com/nklayman/electron-icon-example) |
| 8 | + |
| 9 | +#### Install Required Deps |
| 10 | + |
| 11 | +First, add [electron-icon-builder](https://www.npmjs.com/package/electron-icon-builder) as a `devDependency`: |
| 12 | + |
| 13 | +With Yarn: |
| 14 | + |
| 15 | +`yarn add --dev electron-icon-builder` |
| 16 | + |
| 17 | +or with NPM: |
| 18 | + |
| 19 | +`npm install --save-dev electron-icon-builder` |
| 20 | + |
| 21 | +#### Add Icon to App |
| 22 | + |
| 23 | +Place your square icon in `public/icon.png`. |
| 24 | + |
| 25 | +#### Add Generation Script |
| 26 | + |
| 27 | +Add the following script to your `package.json`: |
| 28 | + |
| 29 | +```json |
| 30 | +"electron:generate-icons": "electron-icon-builder --input=./public/icon.png --output=build --flatten" |
| 31 | +``` |
| 32 | + |
| 33 | +#### Generate Icons |
| 34 | + |
| 35 | +Run the new script: |
| 36 | + |
| 37 | +With Yarn: |
| 38 | + |
| 39 | +`yarn electron:generate-icons` |
| 40 | + |
| 41 | +or with NPM: |
| 42 | + |
| 43 | +`npm run electron:generate-icons` |
| 44 | + |
| 45 | +#### Set Tray Icon |
| 46 | + |
| 47 | +Edit your background file (`src/background.(js|ts)` by default): |
| 48 | + |
| 49 | +```js |
| 50 | +// Import path module (at the top of your file, below 'use-strict') |
| 51 | +import path from 'path' |
| 52 | + |
| 53 | +// Replace |
| 54 | +win = new BrowserWindow({ width: 800, height: 600 }) |
| 55 | +// With |
| 56 | +win = new BrowserWindow({ |
| 57 | + width: 800, |
| 58 | + height: 600, |
| 59 | + icon: path.join(__static, 'icon.png') |
| 60 | +}) |
| 61 | +``` |
| 62 | + |
| 63 | +:::tip |
| 64 | +If you get the linting error `'__static' is not defined`, add `/* global __static */` in your background file above your imports. |
| 65 | +::: |
| 66 | + |
| 67 | +## Multiple Pages |
| 68 | + |
| 69 | +> Create multiple Electron windows for each [page](https://cli.vuejs.org/config/#pages) |
| 70 | +
|
| 71 | +[Example Repo](https://github.com/nklayman/electron-multipage-example) |
| 72 | + |
| 73 | +#### Add Your Pages |
| 74 | + |
| 75 | +Follow [Vue CLI's instructions](https://cli.vuejs.org/config/#pages) for adding pages to your app. |
| 76 | + |
| 77 | +#### Create Variable for Second Page |
| 78 | + |
| 79 | +Add the `secondWin` and `createdAppProtocol` variables to your background file (`src/background.(js|ts)` by default): |
| 80 | + |
| 81 | +```js |
| 82 | +// Already in file |
| 83 | +let win |
| 84 | +// Add these below |
| 85 | +let secondWin |
| 86 | +let createdAppProtocol = false |
| 87 | +``` |
| 88 | + |
| 89 | +#### Accept Page Arguments for `createWindow` Function |
| 90 | + |
| 91 | +In your background file, update the `createWindow` function to take arguments about the page: |
| 92 | + |
| 93 | +Replace: |
| 94 | + |
| 95 | +```js |
| 96 | +function createWindow() { |
| 97 | + // Create the browser window. |
| 98 | + win = new BrowserWindow({ width: 800, height: 600 }) |
| 99 | + |
| 100 | + if (process.env.WEBPACK_DEV_SERVER_URL) { |
| 101 | + // Load the url of the dev server if in development mode |
| 102 | + win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) |
| 103 | + if (!process.env.IS_TEST) win.webContents.openDevTools() |
| 104 | + } else { |
| 105 | + createProtocol('app') |
| 106 | + // Load the index.html when not in development |
| 107 | + win.loadURL('app://./index.html') |
| 108 | + } |
| 109 | + |
| 110 | + win.on('closed', () => { |
| 111 | + win = null |
| 112 | + }) |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +With: |
| 117 | + |
| 118 | +```js |
| 119 | +function createWindow(winVar, devPath, prodPath) { |
| 120 | + // Create the browser window. |
| 121 | + winVar = new BrowserWindow({ width: 800, height: 600 }) |
| 122 | + |
| 123 | + if (process.env.WEBPACK_DEV_SERVER_URL) { |
| 124 | + // Load the url of the dev server if in development mode |
| 125 | + winVar.loadURL(process.env.WEBPACK_DEV_SERVER_URL + devPath) |
| 126 | + if (!process.env.IS_TEST) winVar.webContents.openDevTools() |
| 127 | + } else { |
| 128 | + if (!createdAppProtocol) { |
| 129 | + createProtocol('app') |
| 130 | + createdAppProtocol = true |
| 131 | + } |
| 132 | + // Load the index.html when not in development |
| 133 | + winVar.loadURL(`app://./${prodPath}`) |
| 134 | + } |
| 135 | + |
| 136 | + winVar.on('closed', () => { |
| 137 | + winVar = null |
| 138 | + }) |
| 139 | +} |
| 140 | +``` |
| 141 | + |
| 142 | +#### Create Both Windows on App Launch |
| 143 | + |
| 144 | +Create both windows inside the `app.on('ready')` callback in your background file: |
| 145 | + |
| 146 | +```js |
| 147 | +app.on('ready', async () => { |
| 148 | + if (isDevelopment && !process.env.IS_TEST) { |
| 149 | + // Install Vue Devtools |
| 150 | + try { |
| 151 | + await installVueDevtools() |
| 152 | + } catch (e) { |
| 153 | + console.error('Vue Devtools failed to install:', e.toString()) |
| 154 | + } |
| 155 | + } |
| 156 | + // Replace |
| 157 | + createWindow() |
| 158 | + // With |
| 159 | + createWindow(win, '', 'index.html') |
| 160 | + createWindow(secondWin, 'subpage', 'subpage.html') |
| 161 | +}) |
| 162 | +``` |
| 163 | + |
| 164 | +#### Recreate Both Windows When Dock Icon is Clicked |
| 165 | + |
| 166 | +Create both windows inside the `app.on('activate')` callback in your background file: |
| 167 | + |
| 168 | +```js |
| 169 | +app.on('activate', () => { |
| 170 | +// On macOS it's common to re-create a window in the app when the |
| 171 | +// dock icon is clicked and there are no other windows open. |
| 172 | + |
| 173 | +// Replace |
| 174 | +if (win === null) { |
| 175 | + createWindw() |
| 176 | +} |
| 177 | +// With |
| 178 | +if (win === null) { |
| 179 | + createWindow(win, '', 'index.html') |
| 180 | +} |
| 181 | +if (secondWin === null) { |
| 182 | + createWindow(secondWin, 'subpage', 'subpage.html') |
| 183 | +} |
| 184 | +``` |
| 185 | +
|
| 186 | +## Debugging With VSCode |
| 187 | +
|
| 188 | +> Debug the Main and Renderer process with [Visual Studio Code](https://code.visualstudio.com/) |
| 189 | +
|
| 190 | +[Example Repo](https://github.com/nklayman/electron-vscode-debug-example) |
| 191 | +
|
| 192 | +Read [Visual Studio Code's docs on debugging](https://code.visualstudio.com/docs/editor/debugging) before following this guide. |
| 193 | +
|
| 194 | +#### Enable Sourcemaps |
| 195 | +
|
| 196 | +Enable sourcemaps in your `vue.config.js`: |
| 197 | +
|
| 198 | +```js |
| 199 | +module.exports = { |
| 200 | + configureWebpack: { |
| 201 | + devtool: 'source-map' |
| 202 | + } |
| 203 | +} |
| 204 | +``` |
| 205 | +
|
| 206 | +#### Add Debug Task |
| 207 | +
|
| 208 | +Add the `electron-debug` task to `.vscode/tasks.json`, which will start the Electron dev server in debug mode: |
| 209 | +
|
| 210 | +```json |
| 211 | +{ |
| 212 | + // See https://go.microsoft.com/fwlink/?LinkId=733558 |
| 213 | + // for the documentation about the tasks.json format |
| 214 | + "version": "2.0.0", |
| 215 | + "tasks": [ |
| 216 | + { |
| 217 | + "label": "electron-debug", |
| 218 | + "type": "process", |
| 219 | + "command": "node", |
| 220 | + "isBackground": true, |
| 221 | + "args": [ |
| 222 | + "./node_modules/.bin/vue-cli-service", |
| 223 | + "electron:serve", |
| 224 | + "--debug" |
| 225 | + ], |
| 226 | + "problemMatcher": { |
| 227 | + "owner": "custom", |
| 228 | + "pattern": { |
| 229 | + "regexp": "" |
| 230 | + }, |
| 231 | + "background": { |
| 232 | + "beginsPattern": "Starting development server\\.\\.\\.", |
| 233 | + "endsPattern": "Not launching electron as debug argument was passed\\." |
| 234 | + } |
| 235 | + } |
| 236 | + } |
| 237 | + ] |
| 238 | +} |
| 239 | +``` |
| 240 | +
|
| 241 | +#### Add Debugging Configurations |
| 242 | +
|
| 243 | +Add `Electron: Main`, `Electron: Renderer`, and `Electron: All` debug configurations to `.vscode/launch.json`: |
| 244 | +
|
| 245 | +```json |
| 246 | +{ |
| 247 | + "version": "0.2.0", |
| 248 | + "configurations": [ |
| 249 | + { |
| 250 | + "name": "Electron: Main", |
| 251 | + "type": "node", |
| 252 | + "request": "launch", |
| 253 | + "protocol": "inspector", |
| 254 | + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", |
| 255 | + "windows": { |
| 256 | + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" |
| 257 | + }, |
| 258 | + "preLaunchTask": "electron-debug", |
| 259 | + "args": ["--remote-debugging-port=9223", "./dist_electron"], |
| 260 | + "outFiles": ["${workspaceFolder}/dist_electron/**/*.js"] |
| 261 | + }, |
| 262 | + { |
| 263 | + "name": "Electron: Renderer", |
| 264 | + "type": "chrome", |
| 265 | + "request": "attach", |
| 266 | + "port": 9223, |
| 267 | + "urlFilter": "http://localhost:*", |
| 268 | + "timeout": 30000, |
| 269 | + "webRoot": "${workspaceFolder}/src", |
| 270 | + "sourceMapPathOverrides": { |
| 271 | + "webpack:///./src/*": "${webRoot}/*" |
| 272 | + } |
| 273 | + } |
| 274 | + ], |
| 275 | + "compounds": [ |
| 276 | + { |
| 277 | + "name": "Electron: All", |
| 278 | + "configurations": ["Electron: Main", "Electron: Renderer"] |
| 279 | + } |
| 280 | + ] |
| 281 | +} |
| 282 | +``` |
| 283 | +
|
| 284 | +#### Add Some Breakpoints |
| 285 | +
|
| 286 | +Add "red dot" [breakpoints](https://code.visualstudio.com/docs/editor/debugging#_breakpoints) by clicking VSCode's gutter in your Vue app or background file. |
| 287 | +
|
| 288 | +#### Launch Debug Mode |
| 289 | +
|
| 290 | +Run the `Electron: All` launch configuration. Execution should stop upon reaching one of your breakpoints, and VSCode will allow you to debug your code. |
| 291 | +
|
| 292 | +:::warning |
| 293 | +Breakpoints will not be detected in your Vue app during the initial launch of Electron. Reload the window to stop on these breakpoints. |
| 294 | +::: |
0 commit comments