26.08.2024 г.
Electron, TypeScript и Parcel
Документацията на Electron е изцяло за JavaScript, но това не пречи да си използвате TypeScript, с който да генерира този JavaScript. Трябва да се спазват няколко простички правила, и то основно в пътищата на зареждане на файловете. Подготвил съм и малко допълнение за front-end частта. Вместо стандартната за Electron HTML страница ще направя малка компилация с Parcel.
Проекта
Най-напред ще си организираме проекта. В него ще има 2 подпапки - едната за Electron частта, др. за Browser частта. Създаваме папка electron-typescript-parcel
и я отваряме във VSCode - или който редактор ползвате. Отваряме вградения във VSCode терминал (или друг ако не ползвате VSCode) и изпълнявате:
npm init -y
Това ще създаде package.json
файл в папката electron-typescript-parcel
. Отваряте файла и редактирате полето author
. Като начало е достатъчно. Следва да добавим Electron модула в проекта.
npm install --save-dev electron
Ако ще ползвате GIT, сега е добре да изпълните:
git init
и да добавите .gitignore
файл. В него добавете като начало добавяме node_modules
.
След това добавяме 2 папки - electron
и browser
в папката на проекта. Както подсказват имената - в първата ще живее Electron, а във втората - front-end частта за браузъра.
Electron
През терминала влизаме в папката electron
и изпълняваме:
npm init -y
и веднага след това добавяме и TypeScript модула:
npm install --save-dev typescript
Зареждаме package.json
. В script частта добавяме "build": "tsc"
и махаме "main"
атрибута.
// electron/package.json
{
"name": "electron",
"version": "1.0.0",
"scripts": {
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"typescript": "^5.5.4"
}
}
В конзолата изпълняваме:
npx tsc --init
Това ще създаде tsconfig.json
файл. В него ще трябва да намерите "outDir"
, да премахнете коментираната час на реда и задавате "outDir": "../dist"
.
От тук следваме стандартните за Electron стъпки за създаване на базово приложение, като изпускаме частта за създаване на index.html
файла и renderer.js
файла, които ще добавим чрез Parcel.
Добавяме main.ts
файл в папката electron
и в него пишем:
// electron/main.ts
import { app, BrowserWindow, ipcMain, nativeTheme } from "electron";
import path from "node:path";
/**
* Creates a new window and loads an HTML file.
*/
const createWindow = (): void => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, "./preload.js"),
},
});
mainWindow.loadFile("./dist/index.html");
ipcMain.handle("dark-mode:toggle", () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = "light";
} else {
nativeTheme.themeSource = "dark";
}
return nativeTheme.shouldUseDarkColors;
});
};
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});
Това е примера от Electron документацията, който сменя тъмна или светла темата на приложението.
След това добавяме preload.ts
файл в папката electron
и в него пишем:
// electron/preload.ts
import { contextBridge, ipcRenderer } from "electron/renderer";
contextBridge.exposeInMainWorld("electronAPI", {
toggle: () => ipcRenderer.invoke("dark-mode:toggle"),
});
Browser
През терминала влизаме в папката browser
и изпълняваме:
npm init -y
след което инсталираме Parcel:
npm install --save-dev parcel
Зареждаме package.json
. В script частта добавяме "build": "parcel build index.html --dist-dir ../dist --no-source-maps --public-url ./ --no-optimize"
и махаме "main"
атрибута.
Създаваме index.html
файл в папката browser
и в него пишем:
<!-- browser/index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link rel="stylesheet" type="text/css" href="./styles.css">
</head>
<body>
<h1>Hello World!</h1>
<p>Current theme source: <strong id="theme-source">System</strong></p>
<p><button id="toggle-dark-mode">Toggle Theme Color</button></p>
<script src="./render.ts"></script>
</body>
</html>
Създаваме styles.css
файл в папката browser
и в него пишем:
/* browser/styles.css */
@media (prefers-color-scheme: dark) {
body { background: #333; color: white; }
}
@media (prefers-color-scheme: light) {
body { background: #ddd; color: black; }
}
Добавяме render.ts
файл в папката browser
и в него пишем:
const toggleDarkMode = document.getElementById("toggle-dark-mode");
const themeSource = document.getElementById("theme-source");
if (themeSource && toggleDarkMode) {
toggleDarkMode.addEventListener("click", async () => {
// @ts-expect-error
const isDarkMode = await window.electronAPI.toggle();
themeSource.innerHTML = isDarkMode ? "Dark" : "Light";
toggleDarkMode.innerHTML = `Toggle ${!isDarkMode ? "Dark" : "Light"} Mode`;
});
}
За да 'компилираме' typescript файла с Parcel ще добавим в папката .parcelrc
файл и в него ще напишем:
// browser/.parcelrc
{
"extends": "@parcel/config-default",
"transformers": {
"*.ts": ["@parcel/transformer-typescript-tsc"]
}
}
Старт
Връщаме се обратно в папката на проекта и редактираме в package.json
файла полетата scripts и main :
// package.json
{
"main": "./dist/main.js",
"scripts": {
"start": "npm run build --prefix ./electron && npm run build --prefix ./browser && electron ."
}
}
В .gitignore
файла добавяме dist
и .parcel-cache
папките и в командния ред изпълняваме:
npm start
След старта на приложението, ще се появи папка dist
в папката на проекта и в нея ще е целия код на Electron приложението.
Направил съм репозитори за този проект в GitHub.
Ако имате мнение или въпроси за статията, не се колебайте да ги споделите.
Логване на информация с Web Workers от Vue 3 към сървъра
Web Workers са малки, но мощни скриптове, които работят на 'заден план' в браузъра. И понеже не пречат на рендирането на приложението Ви, може да ги товарите с разни задачи, които да изпълняват.
Vue Router и Main файла
При стартиране на нов Vue проект, използвам Quick Start секцията на сайта на Vue. След това, задължително, правя няколко малки промени, преди да добавя проекта към Source Control банката.