Reputation: 1335
I've been working on a Svelte 3 + Electron 12.0.5 project. I am using the svelte-spa-router package for hash routing. My project structure looks like this:
node_modules/
public/
build/
bundle.css
bundle.js
index.html
src/
Components/
Pages/
Home.svelte
Settings.svelte
...
Sidebar.svelte
Titlebar.svelte
App.js
App.svelte
...
index.js // <-- Electron entry point
rollup|svelte|tailwind // <-- config files
Since I was using a router, electron's window.loadFile()
was not working; To solve this, I used the sirv-cli along with concurrently. Now my start script looks like this:
"start": "concurrently \"sirv public --no-clear --port=40072\" \"electron .\""
Now I used window.loadURL("https://localhost:40072")
to get this working. .svelte
files, inside the <script>
tags, I tried to do import * as electron from "electron"
; but that resulted in a error saying fs
is not defined. So for now, I created an express server inside index.js
and am using using fetch
to make POST
request to the server and do the stuffs which I could've easily done using ipcMain
and ipcRenderer
...I don't know if I am doing anything wrong (nodeIntegration is already set to true). I'm kinda new to Svelte so do anyone know of any other way to use electron methods inside the script tags?
Upvotes: 5
Views: 1041
Reputation: 1335
So, I finally solved my problem. I'm posting this as an answer so that others having the same problem can solve it. First of all, we don't need express anymore (you can also use it if you want). The start script is same i.e.
"start": "concurrently \"sirv public --no-clear --port=40072\" \"electron .\""
So instead of using nodeIntegration
, we will be using preload
. For e.g. lets consider a scenario of custom titlebar!
--- preload.js ---
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld(
"api", { // "api" --> rename it to anything you want
titlebar: action => {
ipcRenderer.send("titlebar", action);
}
}
);
--- index.js ---
const { app, ipcMain } = require("electron");
...
ipcMain.on("titlebar", (event, arg) => {
if(arg === "destroy") window.destroy();
else if(arg === "kill") app.quit();
else if(arg === "minimize") window.minimize();
else if(arg === "resize") {
if(window.isMaximized()) window.unmaximize();
else window.maximize();
}
})
And finally your svelte file; consider Titlebar.svelte
<button on:click={() => window.api.titlebar("destroy")}>Destroy</button>
<button on:click={() => window.api.titlebar("kill")}>Kill</button>
<button on:click={() => window.api.titlebar("minimize")}>Minimize</button>
<button on:click={() => window.api.titlebar("resize")}>Resize</button>
This was my use-case actually. I hope it helps! Advices are appreciated!
Upvotes: 5