Reputation: 1824
I have an electron app that builds and runs in development, but when packaging the app with electron-builder, the preload script is not packaged in the right location.
This is a well documented issue and there are very similar questions here and here for example, but none of the replies or solutions are working in my case.
From my electron.js file:
function createWindow() {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(app.getAppPath(), 'src/preload.js'),
contextIsolation: true,
},
});
// In production, set the initial browser path to the local bundle generated
// by the Create React App build process.
// In development, set it to localhost to allow live/hot-reloading.
const appURL = app.isPackaged
? url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true,
})
: 'http://localhost:3000';
mainWindow.loadURL(appURL);
mainWindow.webContents.openDevTools();
}
My preload script:
const { contextBridge, shell } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
openBrowserWindow: (url) => shell.openExternal(url)
}
)
And my Electron app package.json:
"build": {
"extends": null,
"appId": "com.app",
"productName": "App",
"directories": {
"output": "dist"
},
"mac": {
"target": {
"target": "pkg",
"arch": [
"universal"
]
},
"darkModeSupport": "true",
"extendInfo": "app"
},
"pkg": {
"installLocation": "/Applications",
"overwriteAction": "upgrade"
},
"files": [
"**",
"../app/src/*",
"src/preload.js"
],
"extraResources": [
"../app/src/*",
"src/preload.js"
],
"extraFiles": [
"../app/src/*",
"src/preload.js"
]
}
Above I have tried to make sure the "src/preload.js" file is copied over in different ways, but I still get the error:
Unable to load preload script: ...app/Contents/Resources/app.asar/src/preload.js
Error: Cannot find module '...app/Contents/Resources/app.asar/src/preload.js'
The preload script is in fact copied over, but it is not part of the app.asar file. It is copied in to a src folder outside of the Resources folder which contains the app.asar file:
How do I correctly configure electron-builder so this file is in the right location and can be accessed at package runtime?
Upvotes: 4
Views: 4349
Reputation: 15882
I solved this problem by adding "preload.js"
directly to the build -> files
list in my package.json
- I don't know why that was necessary since it already had "*.json"
in it but it fixed the problem for me.
Upvotes: 1
Reputation: 15214
First, add console logs for testing.
console.log({dirname: __dirname})
console.log({getAppPath: app.getAppPath()})
console.log({resourcesPath: process.resourcesPath})
const mainWindow = new BrowserWindow({ ... })
Second, you have to add contextIsolation: true
.
If you are using electron-builder
and for some reason you cannot add contextIsolation: true
you can use this workaround:
package.json
"build": {
...
"extraResources": [
...
"app/preload.js" // <---- add your path
],
}
electron.js
const preloadPath =
process.env.NODE_ENV === 'development'
? path.join(__dirname, '../preload.js') // <---- add your path
: path.join(process.resourcesPath, '/app/preload.js'); // <---- add your path
const mainWindow = new BrowserWindow({
...
webPreferences: {
contextIsolation: false,
preload: preloadPath,
...
}
})
What is path.join(process.resourcesPath, '/app/preload.js')
?
After building your app you can find your extra resources here
C:\Users\<user>\AppData\Local\Programs\<app>\resources
- for Windows
.
For MacOS
you can right click
on your app and click on Show Package Contents
> Resources
Upvotes: 2
Reputation: 4854
preload: path.join(app.getAppPath(), 'src/preload.js'),
As you are not packaging the preload.js
into the app package file (asar default), this won't work like this. app.getAppPath()
will indicate the app package file(or directory, in case you are setting asar
as false)
Your code is indicating /xxx.app/Contents/Resources/app.asar/src/preload.js
or /xxx.app/Contents/Resources/app/src/preload.js
Your preload script file is not there but in the 2nd parent's directory.
So here is the correct path in your case,
path.join(app.getAppPath(), '..', '..', 'src', 'preload.js');
Upvotes: 2
Reputation: 134
If you do:
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.resolve(app.getAppPath(), 'preload.js'),
contextIsolation: true,
},
});
Does it works ? (worked for me with electron-webpack and electron-builder)
Upvotes: 2