A program embeds its files, so it works offline and loads nothing from
elsewhere. assets.New serves them at
PREFIX/VERSION/NAME, where the version is a hash of every file. A new
build serves its files at new addresses, so a browser can keep each one for
good.
files := fstest.MapFS{
"app.css": {Data: []byte("body { margin: 0 }")},
"css/a.css": {Data: []byte("a {}")},
"css/b.css": {Data: []byte("b {}")},
"css/c.json": {Data: []byte("{}")},
}
a, err := assets.New(files, "/static/", assets.Options{})
if err != nil {
fmt.Println(err)
return
}
hide := func(s string) string { return strings.ReplaceAll(s, a.Version(), "VERSION") }
fmt.Println(len(a.Version()))
fmt.Println(hide(a.URL("app.css")))
for _, u := range a.URLs("css/*.css") {
fmt.Println(hide(u))
}
mux := http.NewServeMux()
mux.Handle("GET /static/", a)
w := httptest.NewRecorder()
mux.ServeHTTP(w, httptest.NewRequest(http.MethodGet, a.URL("app.css"), nil))
fmt.Println(w.Code)
fmt.Println(w.Header().Get("Content-Type"))
fmt.Println(w.Header().Get("Cache-Control"))12
/static/VERSION/app.css
/static/VERSION/css/a.css
/static/VERSION/css/b.css
200
text/css; charset=utf-8
private, max-age=31536000, immutablelocalweb/assets/example_test.go. CI runs it and checks its output.A page links to a file with URL, such as from a template function:
<link rel="stylesheet" href="{{asset "app.css"}}">
With Options.Dev, the files are read again for each request from a
directory that the program names, and the browser checks them each time.
Use it to work on the files without building the program again.