Closed RandomEngy closed 2 years ago
Have a look at the Context Bridge docs here: https://www.electronjs.org/docs/latest/api/context-bridge
Use that with the preload script
That looks promising, thanks!
Jumping back into this today.
I figured out the plugin is running in the Main process as it complains about "window" not being defined. I'm having it find the focused window and send a message to it:
export class MyElectronPlugin implements MyLocalPlugin {
async echo(options: { value: string }): Promise<{ value: string }> {
BrowserWindow.getFocusedWindow().webContents.send("echo", options.value);
return options;
}
}
I had to add electron
to the plugin dev dependencies since the example plugin package.json it doesn't import electron
and is only using Node APIs.
Then in the preload script, listen for it:
const { contextBridge, ipcRenderer } = require('electron');
ipcRenderer.on("echo", (event, message) => {
console.info(message);
});
So it ends up hopping over the process boundary a couple times to get back to where it started.
For posterity, I figured things out a bit more. The right answer in this case is to skip the plugin entirely. Plugins run in the main process and you need to use IPC to get back to the render process. The plugins are a bit better for things that can run in the main process (like geolocation or file system access) and not for things that need to run inside a browser context and fiddle with electron windows (like AWS cognito auth).
The part that I was missing was that there are also two separate contexts inside the render process. preload.ts
runs in one context while the main website runs in a different context. They don't share the same window
object so you can't just set up functions in the global scope for the page to call. contextBridge
is what you need to use to expose preload.ts
code to the main website. So all the electron-specific code can go in preload.ts
and a capacitor plugin is not involved.
I haven't quite figured out what I will do for the other platforms but I may be able to also inject some special functions with the same interface into the page.
I've set up my Capacitor project and have an electron folder. I've got the basics working with bundle.js created by webpack referenced by index.html, and both of those are in the electron/app folder.
The boilerplate code serves up this app folder, which has only the pure code from the root web app.
The plugins appear to be running in the main process. How would you run custom electron code in the renderer process? Normally you'd do some ipc and send a message to the render process and tell it to do something. But the page itself is just a copy of the generic web project, so you can't be pulling in electron libraries to listen to those messages.
So far I've gotten this to work:
But that method of running JS code seems limiting. I'm a bit new to both electron and capacitor so I could be missing something obvious here.