In my electron app I expose several preload methods via a preload script. When I first load the application, these methods work fine.
However, when I reload the page (via the browser tools, refresh, without restarting the application) the preload methods are no longer found, and the globalThis
equivalents do not immediately show up.
In my react /renderer application, I import the preload scripts like this:
import { getTheme } from '#preload';
if, after that line, I write this:
console.log(getTheme)
console.log(globalThis.__electron_preload__getTheme)
setTimeout(()=> {
console.log('from timeout', getTheme)
console.log('from timeout', globalThis.__electron_preload__getTheme)
}, 100)
When I first launch the app, the browser output is:
ƒ () { [native code] }
ƒ () { [native code] }
from timeout ƒ () { [native code] }
from timeout ƒ () { [native code] }
However, if I go into the chrome dev tools and refresh (CTRL+R), I then see this:
undefined
undefined
from timeout undefined
from timeout ƒ () { [native code] }
Which shows that it takes some time (at least 100ms) for globalThis
to get populated, but even when it does, the #preload script never actually works.
I suspect this might be a loading order issue. But I don't see a way to control this. When I create the electron window, I am setting webPreferences.preload to this:
preload: join(app.getAppPath(), 'packages/preload/dist/index.mjs'),
edit: sample preload function
here is a sample method exported from the preload package:
export function getTheme(): Promise<string> {
return ipcRenderer.invoke('state:theme:get');
}
The problem you get is a race-condition issue with preloads that use ESM. The preload script is supposed to block the page load when the latter has a content (and so loads before the page), but it doesn't always work with the reload system of webpack/vite.
There is no real workaround, other than rewriting your code to make sure it doesn't ask anything to the preload before it's loaded, or just not using ESM.
You can also wait for the bug to be fixed: there is an open issue about it. Note that this problem probably only occurs in dev mode.