Upgrading Electron
When you add the Electron mode in a Quasar project for the first time you will get the latest version of the Electron package. At some point in time, you will want to upgrade the Electron version.
Before upgrading Electron, please consult its release notes. Are there breaking changes?
# from the root of your Quasar project
$ yarn upgrade electron@latest
Upgrading from Quasar v1
The Electron mode for Quasar v2 is an almost complete overhaul of the previous version, significantly improving the developer experience. Some of the changes here are required in order to ensure compatibility with the latest developments in the Electron world (so bulletproofing for upcoming upstream changes).
High overview of the improvements
- Out of the box support for Typescript. Just rename electron-main.js and electron-preload.js to electron-main.ts and electron-preload.ts.
- Support for Electron 11 and preparing out of the box support for upcoming changes in Electron 12+ (without you needing to change anything in the future). One of changes are that we’ll be using
contextIsolation
instead of the deprecatedNode Integration
. - The preload script no longer has the old limitations. You can import other js files with a relative path because the script is now bundled and passed through Babel (so you can use the
import X from Y
syntax too). You can also enable linting for it. - You can enable linting for the main thread and the preload script too.
- We’ve removed the default electron-main.dev.js support as it seems that it’s not needed anymore. However, you can add it back by creating it and referencing it from electron-main (it’s no longer detected by Quasar CLI automatically – because we don’t need to; more on this later).
The /src-electron folder
The old structure was:
The NEW structure is:
Notice that there’s no electron-main.dev.js
file anymore (not needed anymore) and that the electron-preload/main.js
files need to be moved directly under /src-electron
.
The electron-main.js file
In order for us to be forward compatible with future versions of Electron, you’ll need to do some small (but important!) changes:
mainWindow = new BrowserWindow({
// ...
webPreferences: {
nodeIntegration: process.env.QUASAR_NODE_INTEGRATION,
nodeIntegrationInWorker: process.env.QUASAR_NODE_INTEGRATION,
// preload: path.resolve(__dirname, 'electron-preload.js')
}
})
mainWindow = new BrowserWindow({
// ...
webPreferences: {
// we enable contextIsolation (Electron 12+ has it enabled by default anyway)
contextIsolation: true,
// we use a new way to reference the preload script
// (it's going to be needed, so add it and create the file if it's not there already)
preload: path.resolve(__dirname, process.env.QUASAR_ELECTRON_PRELOAD)
}
})
The electron-preload.js file
You will need this file if you don’t have it already. So create it if it’s missing. Without it you won’t be able to use the power of Node.js in your renderer thread.
More info: preload script.
WARNING
You will need to transfer all the Node.js stuff away from your renderer thread (the UI code from /src) and into the preload script. Provide the same functionality through the contextBridge
as seen below.
This is the default content of electron-preload.js
:
/**
* This file is used specifically for security reasons.
* Here you can access Nodejs stuff and inject functionality into
* the renderer thread (accessible there through the "window" object)
*
* WARNING!
* If you import anything from node_modules, then make sure that the package is specified
* in package.json > "dependencies" and NOT in "devDependencies"
*
* Example (injects window.myAPI.doAThing() into renderer thread):
*
* const { contextBridge } = require('electron')
*
* contextBridge.exposeInMainWorld('myAPI', {
* doAThing: () => {}
* })
*/
quasar.config file changes
electron: {
// it's gone now (upcoming upstream breaking change)
// replaced by a change in electron-main.js documented earlier
nodeIntegration: true, // remove me!
// renamed to chainWebpackMain
chainWebpack (chain) { /* ... */ },
// renamed to extendWebpackMain
extendWebpack (cfg) { /* ... */ }
}
electron: {
// was renamed from chainWebpack()
chainWebpackMain (chain) {
// example for its content (adds linting)
chain.plugin('eslint-webpack-plugin')
.use(ESLintPlugin, [{ extensions: ['js'] }])
},
// was renamed from extendWebpack()
extendWebpackMain (cfg) { /* ... */ },
// New!
chainWebpackPreload (chain) {
// example (adds linting)
chain.plugin('eslint-webpack-plugin')
.use(ESLintPlugin, [{ extensions: ['js'] }])
}
// New!
extendWebpackPreload (cfg) { /* ... */ }
}
Renderer thread (/src)
The $q object no longer contains the electron
property. You will need to use the preload script to access it and provide it to the renderer thread.
Furthermore, the openURL util can no longer tap into Electron to open a new window. You will need to provide your own util from the preload script.
WARNING
You will need to transfer all the Node.js stuff away from your renderer thread (the UI code from /src) and into the preload script. Provide the same functionality through the contextBridge
as seen in the preload script section above.
Browser Devtools
You may also want the following code in your electron-main.js to auto-open devtools while on dev mode (or prod with debugging enabled) and to disable devtools on production builds (without debugging enabled):
function createWindow () {
mainWindow = new BrowserWindow({ /* ... */ })
if (process.env.DEBUGGING) {
// if on DEV or Production with debug enabled
mainWindow.webContents.openDevTools()
}
else {
// we're on production; no access to devtools pls
mainWindow.webContents.on('devtools-opened', () => {
mainWindow.webContents.closeDevTools()
})
}
}