Documentation
¶
Overview ¶
Package assets fingerprints a file system of static files, such as an embed.FS of vendored packages, and serves it with caching that suits versioned URLs.
Fingerprint hashes every file once. URL then gives a file's address with its version (?v=...), Integrity its Subresource Integrity value, and ServeFile serves a file with a strong ETag: a request for the current version may be cached for a year, any other request revalidates.
manifest, err := assets.Fingerprint(static)
manifest.WithURLFunc(func(file string) string { return "/static/" + file })
mux.HandleFunc("GET /static/{file...}", func(w http.ResponseWriter, r *http.Request) {
manifest.ServeFile(w, r, r.PathValue("file"))
})
The files must not change once fingerprinted; fingerprint again to pick up new content, or, while developing, fingerprint with Reload, which notices changed, added and removed files by their names, sizes and modification times:
manifest, err := assets.Fingerprint(os.DirFS("static"), assets.Reload())
Index ¶
- func Integrity(data []byte) string
- func ScriptTag(src, integrity string, attrs ...string) (template.HTML, error)
- func StylesheetTag(href, integrity string, attrs ...string) (template.HTML, error)
- func Versioned(rawURL, version string) string
- type Manifest
- func (m *Manifest) Files() []string
- func (m *Manifest) Has(file string) bool
- func (m *Manifest) Integrity(file string) string
- func (m *Manifest) PlainURL(file string) string
- func (m *Manifest) Reloads() bool
- func (m *Manifest) ServeFile(w http.ResponseWriter, r *http.Request, file string)
- func (m *Manifest) Stylesheet(file string, attrs ...string) (template.HTML, error)
- func (m *Manifest) TagIntegrity(file string) string
- func (m *Manifest) URL(file string) string
- func (m *Manifest) Version(file string) string
- func (m *Manifest) WithURLFunc(fn func(file string) string) *Manifest
- type Option
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Integrity ¶
Integrity returns the Subresource Integrity value of data ("sha384-..."), as Manifest.Integrity gives for a file.
func ScriptTag ¶
ScriptTag returns a <script> tag that loads src, with the Subresource Integrity value integrity ("sha384-...") and crossorigin="anonymous" when integrity is not empty, so the browser refuses a file whose content changed. attrs are more attributes as name and value pairs, such as "type", "module" or "defer", ""; an empty value renders the name alone. A crossorigin attribute among attrs replaces the default one; src and integrity cannot be set through attrs.
tag, err := assets.ScriptTag(manifest.URL("app.js"), manifest.Integrity("app.js"), "type", "module")
func StylesheetTag ¶
StylesheetTag returns a <link rel="stylesheet"> tag for href, with the Subresource Integrity value integrity and crossorigin="anonymous" when integrity is not empty. attrs are more attributes as name and value pairs, such as "media", "print"; rel, href and integrity cannot be set through attrs. See ScriptTag.
Types ¶
type Manifest ¶
type Manifest struct {
// contains filtered or unexported fields
}
Manifest is the fingerprint of every file in a file system. It is safe for concurrent use once configured (WithURLFunc).
func Fingerprint ¶
Fingerprint hashes every file in fsys with SHA-384, or the files of Only. Hidden files and directories, whose name starts with a dot, are left out unless Only names them.
func MustFingerprint ¶
MustFingerprint is Fingerprint for a file system that is known to be readable, such as an embed.FS; it panics on an error.
func (*Manifest) Integrity ¶
Integrity returns the Subresource Integrity value of file ("sha384-..."), or "" for an unknown file.
func (*Manifest) PlainURL ¶
PlainURL returns the address of file without its version: from WithURLFunc, or "/" followed by the file name.
func (*Manifest) ServeFile ¶
ServeFile answers a GET or HEAD request for file, for routers that take the file name from a path parameter. Responses carry a strong ETag, so browsers revalidate cheaply. A request whose v parameter is the file's current version may be cached for a year; any other one must revalidate. Unknown files are not found.
A file whose size or modification time differs from when it was fingerprinted, such as one edited on disk since, is hashed again before it is served, so its ETag and version are always those of the content sent: a request for the old version then must revalidate instead of caching the new content for a year under the old version.
func (*Manifest) Stylesheet ¶
Stylesheet returns a <link rel="stylesheet"> tag for file at its versioned URL, with its Subresource Integrity, as StylesheetTag writes it. While the manifest reloads (Reload) the tag has no integrity, as TagIntegrity explains. An unknown file is an error.
func (*Manifest) TagIntegrity ¶
TagIntegrity returns the Subresource Integrity a page should carry for file, as Stylesheet writes it: Integrity, or "" while the manifest reloads (Reload). A reloading file changes under pages that may be cached, by the browser or a server, and a stale integrity makes the browser refuse the new content. An unknown file gives "".
func (*Manifest) URL ¶
URL returns the address of file with its version, such as "/htmx/htmx.esm.min.js?v=3f2a...". An unknown file gets its address without a version.
type Option ¶
type Option func(*Manifest)
Option changes how Fingerprint fingerprints; see Reload.
func Only ¶
Only fingerprints the named files of the file system alone, such as one stylesheet in a folder that also holds templates, rather than every file. Names are slash-separated paths in the file system, such as "css/site.css"; a leading slash is ignored. Fingerprint fails when one of them is not a regular file. The manifest knows, versions and serves those files only. Calls add to each other.
manifest, err := assets.Fingerprint(module.Files, assets.Only("static/module.css"))
func Reload ¶
func Reload() Option
Reload makes the manifest look at the file system again on every use, cheaply, by the names, sizes and modification times of its files, and fingerprint it again when any of them changed or a file was added or removed. Edited files so get new versions without a restart. It is meant for development with a file system on disk, such as os.DirFS; an embed.FS never changes. A change that keeps a file's size and modification time goes unnoticed.