From 0a888284c7d1621da714879effb55480c4f818f4 Mon Sep 17 00:00:00 2001 From: Sven Walter Date: Fri, 20 Sep 2024 12:35:37 +0200 Subject: [PATCH] add migration docs M0005 for streamlining templates and assets --- migrations.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/migrations.md b/migrations.md index bfb4e03..49d9c23 100644 --- a/migrations.md +++ b/migrations.md @@ -3,6 +3,106 @@ This file contains a list of tasks that are either required or at least strongly recommended to align projects using this SDK. +## M0005 2024-09-20 Streamline templates and assets + +### Reasoning + +Defining the `fs.FS` types for assets and templates for prod and dev is always a bit cumbersome, because the paths for +devs are always relative to the project root and the paths for the prod ones need to do an additional `fs.Sub` with +respective error handling. This gets a little more severe with dependency injection, since we would have to wrap this into functions. + +The package structure also is not optimal, since the templates are currently nested into the handlers package, which is +one level below all other directories. Generally, the package structure is not defined properly yet. + +To make our lives easier with dependency injection, we should also define distinct types for the asset `fs.FS` and the +template `fs.FS`. + +### Package structure + +* `pkg/app/handlers` — Should include all HTTP handlers. +* `pkg/app/templates` — Should include all HTML templates. +* `web` — Should include the frontend assets. Mostly generated by Yarn. + +### File `web/web.go` + +The file is more or less static and would only differ in the generate statements, if you are not using Yarn. + +```go +package web + +import ( + "embed" + "io/fs" + "os" +) + +//go:generate yarn install +//go:generate yarn build + +//go:embed all:dist/* +var embedded embed.FS + +type FS fs.FS + +func DevFS() FS { + return os.DirFS("web/dist") +} + +func ProdFS() FS { + result, err := fs.Sub(embedded, "dist") + if err != nil { + panic(err) + } + + return result +} +``` + +### File `pkg/app/templates/fs.go` + +This file should look the same everywhere and should be the only `.go` file in that directory, because the other ones +are HTML templates. + +```go +package templates + +import ( + "embed" + "io/fs" + "os" +) + +//go:embed all:* +var embedded embed.FS + +type FS fs.FS + +func DevFS() FS { + return os.DirFS("pkg/app/templates") +} + +func ProdFS() FS { + return embedded +} +``` + +### Dependency injection hints + +When already using dependency injection, the definitions in the `root.go` would look simple as follows, for production +and development respectively: + +```go + c.Provide(templates.ProdFS) + c.Provide(web.ProdFS) +``` + +```go + c.Provide(templates.DevFS) + c.Provide(web.DevFS) +``` + +Afterward, they can be simply requested by requesting `web.FS` or `templates.FS`. + ## M0004 2024-09-13 Isolate HTTP handlers ### Reasoning