приложение собрано каркасом и вшито в бинарник

- заведён каталог web/ — Vue 3, роутер пятой версии, сборка Vite; собранное
  вшивается через go:embed и раздаётся корневым маршрутом: разметка на
  неизвестном пути вне корней сервиса, отказ контракта внутри корня
- перечень корней сервиса стал единой точкой и порождает регистрацию маршрутов,
  а не описывает её; журнал раздачи пишет исход и длину пути, но не сам путь
- шаг front зовёт Node контейнером docker — Biome, юнит-тесты Vue и сборка
  входят в гейт, а в Dockerfile появилась ступень приложения
This commit is contained in:
av
2026-08-15 18:51:05 +03:00
parent c6ffda9aac
commit 663021f712
46 changed files with 5958 additions and 43 deletions
+44
View File
@@ -0,0 +1,44 @@
// Package web несёт собранное приложение внутри бинарника.
//
// Каталога рядом с бинарником не требуется, и внешнего веб-сервера под раздачу
// не заводится: сервис едет на сервер одним образом, и второй разворачиваемый
// артефакт рядом с ним завёл бы вторую точку, где выкладка расходится с
// собранным.
package web
import (
"embed"
"io/fs"
)
// Вшивается каталог `embed`, а не `embed/dist`: собранное приложение лежит
// этажом ниже метки `embed/.gitkeep`, и очистка выходного каталога перед каждой
// сборкой метки не касается. Без метки каталога не было бы в git вовсе, и
// `go build ./...` отказывал бы у всякого, кто приложение ни разу не собирал.
//
// Приставка `all:` нужна ради самой метки: без неё файлы, чьё имя начинается с
// точки, не вшиваются.
//
//go:embed all:embed
var embedded embed.FS
// distDir — где внутри вшитого лежит собранное приложение.
const distDir = "embed/dist"
// Dist отдаёт собранное приложение файловой системой.
//
// Второе значение говорит, собрано ли оно вообще: пустой каталог — законное
// состояние сборки, прошедшей мимо набора проверок, и сервис обязан сказать о
// нём вслух, а не отдавать пустую страницу.
func Dist() (fs.FS, bool) {
dist, err := fs.Sub(embedded, distDir)
if err != nil {
return nil, false
}
if _, err := fs.Stat(dist, "index.html"); err != nil {
return dist, false
}
return dist, true
}