Копирование папок desktop и desktop-angular из ветки main

This commit is contained in:
2025-10-03 16:53:13 +06:00
parent 7909ec619e
commit fbb530c619
70 changed files with 33414 additions and 1 deletions

297
desktop-angular/HOW_TO.md Normal file
View File

@@ -0,0 +1,297 @@
# Пошаговый гайд: как “поднять” существующий Angular-проект из `ui/` внутри нового Electron-проекта `desktop-angular/` (без копирования собранного кода)
Ниже — практичный сценарий: вы создаёте папку `desktop-angular/` с каркасом Electron, подключаете туда исходники Angular (те, что уже лежат в `ui/`), настраиваете общий запуск в dev-режиме и сборку prod-пакета. Никаких переносов уже собранных файлов, всё работает от исходников Angular.
## Что получится в итоге
- Dev-режим: одновременно запускается `ng serve` из `ui/` и Electron, который открывает `http://localhost:4200`.
- Prod-режим: сначала билдится Angular в `ui/dist/...`, затем Electron упаковывает приложение и грузит `index.html` из собранного Angular.
---
## 1) Создаём новый проект `desktop-angular/` для Electron
- В корне репозитория создайте папку `desktop-angular/`:
```bash
mkdir /home/su/projects/articles/embed-gui-article/desktop-angular
cd /home/su/projects/articles/embed-gui-article/desktop-angular
npm init -y
```
- Устанавливаем зависимости Electron и утилиты для дев-сценария:
```bash
npm i -D electron electron-builder concurrently wait-on cross-env
```
Рекомендуемая структура (минимум):
- `desktop-angular/package.json` — скрипты для dev/prod.
- `desktop-angular/src/main/main.js` — основной процесс Electron.
- `desktop-angular/src/preload/preload.js` — безопасный мост.
- (Без `renderer/` — рендерером будет ваш Angular из `ui/`.)
Создайте папки и файлы:
```bash
mkdir -p src/main src/preload
touch src/main/main.js src/preload/preload.js
```
---
## 2) Подключаемся к уже существующему Angular-проекту в `ui/`
Предполагаем, что Angular уже установлен и запускается из `/home/su/projects/articles/embed-gui-article/ui/` стандартными командами:
- Dev: `npm start` (или `ng serve`)
- Build: `npm run build`
Если нет `npm start`, добавьте его в `ui/package.json`:
```json
{
"scripts": {
"start": "ng serve --port 4200 --disable-host-check",
"build": "ng build"
}
}
```
---
## 3) Код `main.js` для Electron (dev: URL, prod: файл из dist)
Создайте простой `BrowserWindow`, который:
- в dev грузит `http://localhost:4200`
- в prod грузит файл `../ui/dist/project-front/browser/index.html`
Обратите внимание на относительные пути: мы опираемся на реальную структуру вашего репо и текущие выходные пути Angular (`ui/dist/project-front/browser` у вас уже есть).
```javascript
// desktop-angular/src/main/main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
const isDev = process.env.NODE_ENV !== 'production';
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
show: false,
webPreferences: {
preload: path.join(__dirname, '../preload/preload.js'),
contextIsolation: true,
nodeIntegration: false,
sandbox: true
}
});
win.on('ready-to-show', () => win.show());
if (isDev) {
win.loadURL('http://localhost:4200');
// win.webContents.openDevTools(); // включите по желанию
} else {
// В PROD грузим из собранного Angular
const indexPath = path.resolve(
__dirname,
'../../../ui/dist/project-front/browser/index.html'
);
win.loadFile(indexPath);
}
}
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
```
---
## 4) Код `preload.js` (минимальная безопасная заготовка)
```javascript
// desktop-angular/src/preload/preload.js
const { contextBridge } = require('electron');
contextBridge.exposeInMainWorld('env', {
isElectron: true
});
```
В Angular вы сможете проверять наличие `window.env?.isElectron`.
---
## 5) Скрипты в `desktop-angular/package.json`
Добавим удобные команды:
- `dev`: параллельно запускает Angular dev-сервер в `ui/` и Electron (ждём порт 4200).
- `build:ui`: сборка Angular.
- `start`: старт Electron в prod-режиме (если нужно локально проверить загрузку собранного Angular без упаковки).
- `dist`: упаковка Electron (electron-builder).
```json
{
"name": "desktop-angular",
"version": "1.0.0",
"private": true,
"main": "src/main/main.js",
"scripts": {
"dev": "concurrently -k -n UI,ELECTRON -c green,cyan \"cd ../ui && npm start\" \"wait-on http://localhost:4200 && cross-env NODE_ENV=development electron .\"",
"build:ui": "cd ../ui && npm run build",
"start": "cross-env NODE_ENV=production electron .",
"dist": "npm run build:ui && cross-env NODE_ENV=production electron-builder"
},
"devDependencies": {
"concurrently": "^9.0.0",
"cross-env": "^7.0.3",
"electron": "^31.0.0",
"electron-builder": "^24.13.3",
"wait-on": "^7.2.0"
}
}
```
---
## 6) Конфигурация упаковки Electron (electron-builder)
Добавьте секцию `build` в `desktop-angular/package.json`. Мы не копируем Angular внутрь `desktop-angular` — Electron будет брать собранный Angular прямо из `ui/dist/...` при упаковке (через `extraResources`). Это удобно и прозрачно.
```json
{
"build": {
"appId": "com.yourcompany.knocker",
"productName": "Knocker Desktop Angular",
"files": [
"src/main/**/*",
"src/preload/**/*",
"package.json"
],
"extraResources": [
{
"from": "../ui/dist/project-front/browser",
"to": "ui-dist",
"filter": ["**/*"]
}
],
"linux": {
"target": ["AppImage"],
"category": "Utility",
"artifactName": "Knocker-Desktop-Angular-${version}.${ext}"
}
}
}
```
И соответствующее изменение в `main.js` на prod, если хотите грузить из `resources/ui-dist` у упакованного приложения:
- В упакованном `.AppImage` ваши ресурсы оказываются в `process.resourcesPath`.
- Тогда путь до `index.html` будет: `path.join(process.resourcesPath, 'ui-dist', 'index.html')`.
Адаптированный prod-фрагмент:
```javascript
// ... в main.js, в ветке !isDev:
const indexPath = app.isPackaged
? path.join(process.resourcesPath, 'ui-dist', 'index.html')
: path.resolve(__dirname, '../../../ui/dist/project-front/browser/index.html');
win.loadFile(indexPath);
```
Так вы покроете оба случая: локальный prod-запуск и реальный упакованный билд.
---
## 7) CORS, безопасность и доступ к файлам
- В dev Angular грузится по `http://localhost:4200` — обычно проблем нет.
- В prod Angular грузится с `file://` — убедитесь, что никакие запросы не завязаны на абсолютные HTTP-URL без необходимости.
- По умолчанию оставляем `contextIsolation: true`, `nodeIntegration: false`, `sandbox: true`. Для доступа к нативному коду используйте IPC и `preload.js`.
---
## 8) Локальный запуск dev
```bash
cd /home/su/projects/articles/embed-gui-article/desktop-angular
npm run dev
```
- Скрипт поднимет `ng serve` из `ui/` и откроет Electron, который загрузит `http://localhost:4200`.
---
## 9) Локальная проверка prod без упаковки
```bash
# Собираем Angular
cd /home/su/projects/articles/embed-gui-article/ui
npm run build
# Запускаем Electron в prod-режиме
cd /home/su/projects/articles/embed-gui-article/desktop-angular
npm run start
```
---
## 10) Упаковка приложения
```bash
cd /home/su/projects/articles/embed-gui-article/desktop-angular
npm run dist
```
- Angular соберётся.
- Electron-упаковщик положит содержимое `ui/dist/project-front/browser` в `resources/ui-dist`.
- Приложение загрузит `index.html` из `resources/ui-dist`.
---
## 11) Советы по интеграции Angular и Electron
- Детект среды в Angular:
```typescript
// пример: app.component.ts
isElectron = typeof (window as any).env?.isElectron === 'boolean';
```
- Статические пути: В Angular используйте относительные пути к ассетам, чтобы они работали и в `http://localhost:4200`, и в `file://` в prod.
- IPC: если потребуется обмен с main-процессом, расширяйте `preload.js` и опишите чёткий API через `contextBridge`.
---
## 12) Итоговая структура (ключевые узлы)
- `ui/` — как есть, исходники Angular.
- `desktop-angular/`
- `package.json` — скрипты `dev`, `build:ui`, `start`, `dist`, секция `build` (electron-builder).
- `src/main/main.js` — создаёт окно, грузит URL в dev и файл в prod.
- `src/preload/preload.js` — мост в рендерер.
- Ничего из `ui/` внутрь `desktop-angular/` мы не копируем; работаем поверх исходников.
---
## Что делать, если вы хотите переиспользовать текущую папку `desktop/`?
Можно; у вас уже есть `desktop/` с Electron. Тогда:
- Либо перенести логику оттуда в `desktop-angular/` (описано выше).
- Либо в существующем `desktop/` заменить рендерер на Angular из `ui/` по тем же принципам: dev — `loadURL('http://localhost:4200')`, prod — `loadFile(...)` на `ui/dist/...`.