Asset pipeline¶
The asset pipeline fingerprints assets with a content hash, records the mapping in a manifest, and resolves the view helpers through it so a changed asset gets a new URL. It also builds import maps and serves digested assets with a long cache lifetime.
Fingerprinting and the manifest¶
digest-for($content) is the content hash; digested-name('app.css', $content)
inserts it before the extension (app-<digest>.css). A Manifest maps each
logical path to its digested name:
1 2 3 4 | |
build walks the source tree, digests each file, writes the digested copy to the
output directory, and records the mapping. to-json/from-json persist the
manifest.
Resolving in views¶
The asset helpers take a resolver. manifest-resolver($manifest) resolves a
logical name to its digested /assets/... path, passing absolute and external
URLs through unchanged:
1 2 3 4 | |
set-asset-manifest($manifest) registers a manifest globally, and
digested-resolver is a resolver that consults it, so helpers can resolve without
threading the manifest through each call:
1 2 | |
Serving¶
MVC::Keayl::Assets::Serving::AssetsController serves digested files from the
configured root with Cache-Control: public, max-age=31536000, immutable (safe
because the digest changes when the content does). It rejects path traversal and
returns 404 for unknown assets:
1 | |
Import maps¶
An ImportMap pins module names to URLs. pin adds one (defaulting the URL to
/assets/<name>.js); pin-all-from pins every .js file under a directory:
1 2 3 4 | |
javascript-importmap-tags($importmap) emits the <script type="importmap"> with
the import JSON and a <link rel="modulepreload"> for each preloaded pin. Pass a
manifest to resolve the module URLs to their digested paths:
1 | |
Precompiling¶
keayl assets-precompile builds the manifest and digested files, writing them and
a manifest.json to public/assets:
1 | |
It reads from app/assets and reports the count, or fails when there is no asset
source directory.