ends article branch
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
# Встраиваем веб-GUI в консольную утилиту: практический гайд
|
||||
|
||||
```metadata
|
||||
id: 10
|
||||
id: 2
|
||||
title: "Встраиваем веб-GUI в консольную утилиту: практический гайд"
|
||||
readTime: 15-20 минут
|
||||
date: 2025-09-10 18:00
|
||||
author: Direct-Dev (aka Антон Кузнецов)
|
||||
author: Direct-Dev (Антон)
|
||||
level: Средний
|
||||
tags: #go #angular #spa #embed #static #cli #webui #devops
|
||||
version: 1.0.2
|
||||
@@ -15,7 +16,7 @@ version: 1.0.2
|
||||
- [Встраиваем веб-GUI в консольную утилиту: практический гайд](#встраиваем-веб-gui-в-консольную-утилиту-практический-гайд)
|
||||
- [Содержание](#содержание)
|
||||
- [Введение](#введение)
|
||||
- [Как быстро повторить (клонируем, собираем, запускаем)](#как-быстро-повторить-клонируем-собираем-запускаем)
|
||||
- [Клонируем, собираем, запускаем](#клонируем-собираем-запускаем)
|
||||
- [Структура проекта](#структура-проекта)
|
||||
- [Идея и архитектура](#идея-и-архитектура)
|
||||
- [Минимальный GUI](#минимальный-gui)
|
||||
@@ -28,18 +29,27 @@ version: 1.0.2
|
||||
|
||||
## Введение
|
||||
|
||||
Давайте по‑простому. Хотим к консольной утилите прикрутить небольшой веб‑интерфейс, чтобы не гонять команды вручную. Собрали один раз — и отдаем статику прямо из Go‑бинарника (или из рядом лежащей папки). В примере оставим только самое нужное:
|
||||
Допустим есть желание к консольной Go утилите прикрутить небольшой веб‑интерфейс, чтобы не гонять команды вручную в терминале или расширить круг пользователей.
|
||||
Как вариант добавляем api в утилиту, делаем SPA на ангуляре, например, дальше кидаем в проект api скомпилированное spa, cобрали бинарь и отдаем статику прямо из Go‑бинарника (или из рядом лежащей папки).
|
||||
|
||||
В качестве утилиты берем go-knocker - утилиту чтобы постучаться по портам ( такая штука повышающая безопасность серверов и устройств). Проект утилиты можно найти тут: <https://github.com/Direct-Dev-Ru/port-knocker.git>
|
||||
|
||||
в данном упрощенном интерфейсе используем только следующие поля и inline режим работы утилиты:
|
||||
|
||||
на форме будут следующие поля
|
||||
|
||||
- Targets (строка вида `tcp:host:port;udp:host:port...`)
|
||||
- Delay (например `1s`)
|
||||
- Флаг Wait connection
|
||||
- Кнопка Execute
|
||||
|
||||
Если нужен «боевой» вариант — всегда можно нарастить поля и логику. Но начнем с минимума.
|
||||
Если нужен более «продвинутый» вариант — всегда можно нарастить поля и логику.
|
||||
|
||||
## Как быстро повторить (клонируем, собираем, запускаем)
|
||||
## Клонируем, собираем, запускаем
|
||||
|
||||
1 Клонируем репозиторий и переключаемся на ветку для статьи:
|
||||
Источник репозитория: [`https://direct-dev.ru/gitea/GiteaAdmin/knock-gui`](https://direct-dev.ru/gitea/GiteaAdmin/knock-gui)
|
||||
|
||||
1 Клонируем репозиторий и переключаемся на ветку for-article:
|
||||
|
||||
```bash
|
||||
# HTTPS клон
|
||||
@@ -50,9 +60,7 @@ cd knock-gui
|
||||
git checkout for-article
|
||||
```
|
||||
|
||||
Источник репозитория: [`https://direct-dev.ru/gitea/GiteaAdmin/knock-gui`](https://direct-dev.ru/gitea/GiteaAdmin/knock-gui)
|
||||
|
||||
2 Ставим зависимости фронта и собираем UI:
|
||||
2 переходим в папку фронта, ставим зависимости и собираем UI:
|
||||
|
||||
```bash
|
||||
cd ui
|
||||
@@ -63,6 +71,7 @@ npm ci
|
||||
cd ..
|
||||
|
||||
# или через make
|
||||
cd ..
|
||||
make embed-ui
|
||||
```
|
||||
|
||||
@@ -285,6 +294,7 @@ npx ng build --configuration production \
|
||||
```
|
||||
|
||||
Что это даёт:
|
||||
|
||||
- В `dist/.../browser/index.html` будет `<base href="/ui/simple/">`.
|
||||
- Все ссылки на бандлы/ассеты будут начинаться с `/ui/simple/`.
|
||||
|
||||
@@ -298,12 +308,14 @@ npx ng build --configuration production \
|
||||
Важно: закрывающий слеш обязателен, иначе роутинг может «ехать».
|
||||
|
||||
Настройка бэкенда:
|
||||
- Сервируйте содержимое собранной папки по маршруту `/ui/simple` (или скопируйте артефакты в `back/cmd/public/ui/simple/`).
|
||||
|
||||
- Отгружайте содержимое собранной папки по маршруту `/ui/simple` (или скопируйте артефакты в `back/cmd/public/ui/simple/`).
|
||||
- SPA‑фоллбэк должен отдавать `index.html` при запросах внутри префикса, если это не файловые ресурсы.
|
||||
|
||||
Если у вас универсальный обработчик (как в `setupStaticRoutes`) на корне, два простых подхода:
|
||||
- Хранить файлы в `public/ui/simple/...` — тогда запросы к `/ui/simple/...` будут удовлетворены корректно.
|
||||
- Либо сделать отдельный хендлер, который для путей с префиксом `/ui/simple` читает файлы из подкаталога, а на несуществующие файлы отвечает содержимым `public/ui/simple/index.html`.
|
||||
|
||||
- Хранить файлы в `public/ui/simple/...` — тогда запросы к `/ui/simple/...` будут отработаны корректно.
|
||||
- Сделать отдельный хендлер, который для путей с префиксом `/ui/simple` читает файлы из подкаталога, а на несуществующие файлы отвечает содержимым `public/ui/simple/index.html`.
|
||||
|
||||
Пример маппинга структуры в `public/`:
|
||||
|
||||
@@ -318,10 +330,6 @@ public/
|
||||
└── ...
|
||||
```
|
||||
|
||||
Проверка:
|
||||
```text
|
||||
http://localhost:8888/ui/simple
|
||||
```
|
||||
Если при прямом заходе на вложенный роут `/ui/simple/some/child` видите 404 — значит фоллбэк не отрабатывает. Проверьте, что при отсутствии файла по этому пути сервер возвращает `public/ui/simple/index.html`.
|
||||
|
||||
## FAQ и типичные ошибки
|
||||
|
Reference in New Issue
Block a user