Add electron

This commit is contained in:
2026-04-16 08:04:32 +02:00
parent 13a6c24cd1
commit 602348c934
6 changed files with 4100 additions and 3 deletions

View File

@@ -36,6 +36,40 @@ ng build
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
## Electron desktop app
This project can also run as an Electron desktop app using the same Angular frontend.
### Run Electron with a production build
```bash
npm run electron
```
This command runs `npm run build:electron` internally to emit a file-based build for Electron.
### Run Electron against the Angular dev server
Start Angular in one terminal:
```bash
npm start
```
Then start Electron in another terminal:
```bash
npm run electron:dev
```
### Package a Linux desktop build
```bash
npm run electron:pack
```
The packaged app is created in the `release/` directory.
## Running unit tests
To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command:

50
electron/main.cjs Normal file
View File

@@ -0,0 +1,50 @@
const { app, BrowserWindow, shell } = require('electron');
const path = require('path');
function createMainWindow() {
const mainWindow = new BrowserWindow({
width: 1400,
height: 900,
minWidth: 1000,
minHeight: 700,
autoHideMenuBar: true,
backgroundColor: '#060910',
webPreferences: {
preload: path.join(__dirname, 'preload.cjs'),
contextIsolation: true,
nodeIntegration: false,
sandbox: true,
},
});
const devUrl = process.env.ELECTRON_RENDERER_URL;
if (devUrl) {
mainWindow.loadURL(devUrl);
mainWindow.webContents.openDevTools({ mode: 'detach' });
} else {
mainWindow.loadFile(path.join(__dirname, '..', 'dist', 'website', 'browser', 'index.html'));
}
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url);
return { action: 'deny' };
});
}
app.whenReady().then(() => {
createMainWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createMainWindow();
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

6
electron/preload.cjs Normal file
View File

@@ -0,0 +1,6 @@
const { contextBridge } = require('electron');
contextBridge.exposeInMainWorld('desktop', {
isElectron: true,
});

3981
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,17 @@
{
"name": "website",
"version": "0.0.0",
"main": "electron/main.cjs",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"build:electron": "ng build --base-href ./",
"watch": "ng build --watch --configuration development",
"test": "ng test"
"test": "ng test",
"electron": "npm run build:electron && electron .",
"electron:dev": "ELECTRON_RENDERER_URL=http://localhost:4200 electron .",
"electron:pack": "npm run build:electron && electron-builder --linux"
},
"private": true,
"packageManager": "npm@11.12.1",
@@ -24,9 +29,29 @@
"@angular/build": "^21.2.6",
"@angular/cli": "^21.2.6",
"@angular/compiler-cli": "^21.2.0",
"electron": "^36.4.0",
"electron-builder": "^24.13.3",
"jsdom": "^28.0.0",
"prettier": "^3.8.1",
"typescript": "~5.9.2",
"vitest": "^4.0.8"
},
"build": {
"appId": "com.kaintim.website",
"productName": "Website",
"directories": {
"output": "release"
},
"files": [
"dist/website/browser/**/*",
"electron/**/*",
"package.json"
],
"linux": {
"target": [
"AppImage"
],
"category": "Utility"
}
}
}

View File

@@ -1,5 +1,5 @@
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter, withInMemoryScrolling } from '@angular/router';
import { provideRouter, withHashLocation, withInMemoryScrolling } from '@angular/router';
import { routes } from './app.routes';
@@ -8,6 +8,7 @@ export const appConfig: ApplicationConfig = {
provideBrowserGlobalErrorListeners(),
provideRouter(
routes,
withHashLocation(),
withInMemoryScrolling({
anchorScrolling: 'enabled',
scrollPositionRestoration: 'enabled',