// 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 }