A Leiningen plugin to generate fingerprinted files suitable for use in browser cache-busting.
It was designed with the specific usecase of fingerprinting CLJS files that are
bundled as part of an uberjar alongside other clojure code in mind.
lein-buster
provides either auto-run hooks that invoke it after
leiningen.compile
or a task to invoke it manually from a project.
Once run, lein-buster
will output two types of artifacts:
<output-base>/<filepath-diff-minus-filename>/<filename>-<fingerprint>.<extension>
.JSON
format so that you can map the filename you know to
the generated one.Buster needs to know which files you want to fingerprint and where to write a
manifest to. You can supply this configuration inside a :buster
map like so:
:buster {;; A vector of files and dirs as strings or as regex patterns.
;; If any regex, then all file paths in project are listed once, and any regex is matched against the loaded list.
;; If any string or regex matches a directory then all files in that directory are "busted"
:files ["resources/build/out/main.js"
"no-existent-file.txt"
"resources/build/images"
#"resources/build/stylesheets/.+\.css$"]
;; This part will be stripped away from the file path, and the remainder - lets call it "filepath-diff" -
;; is used in both manifest as well as appended to <output-base> when writing renamed files.
;; Defaults to <project-dir>.
:files-base "resources/build"
;; Renamed files are written to <output-base>/<filepath-diff>.
;; Defaults <source-base>.
:output-base "release"
;; Defaults to <output-base>/rev-manifest.json
:manifest "release/rev-manifest.json"
;; If true, merges updated/new files to existing manifest file.
;; If false, replaces an existing manifest with an new file.
;; Defaults to false.
:merge true}
If you're not feeling picky, you can stick that configuration at the
project.clj
's top level. Otherwise, you can put it at the top level of a
relevant profile (example below).
Buster also supplies a hook to run itself post-compile with. You can add that to
your project.clj
like so:
:hooks [leiningen.buster]
If you're using a hook from another plugin that generates the static files you
want fingerprinted (e.g. [lein-cljsbuild
] lein-cljsbuild), you should make
sure that hook comes before buster's:
:hooks [leiningen.cljsbuild leiningen.buster]
Add [no.terjedahl/lein-buster "0.2.0-SNAPSHOT"]
to the :plugins
vector of your project.clj
.
You can invoke lein-buster
manually from your project like so:
$ lein buster
This is probably not that useful, outside of making sure you've configured things properly. The auto-run configuration outlined above is probably closer to what you're looking for.
If you want to have lein-buster
run only as part of your jar compilation
(which is likely), your buster config in your project.clj
can be nested under
the relevant profile like so:
:profiles {:uberjar {:hooks [leiningen.buster]
:buster {:files ["resources/public/scripts/awesome.js"]
:manifest "resources/manifest.json"}}}
You'll want to parse the generated manifest file and expose the mappings to your
views so that you can substitute the file name you know (e.g. application.js
)
to the fingerprinted version (e.g. application-acbd18db4c.js
).
In my current project, we use cheshire
to parse the JSON from clojure
and construct our views using selmer
. We added a custom selmer
tag
to help with this translation:
(defn load-revision-manifest
[path]
(when-let [manifest (io/resource path)]
(-> manifest slurp chesh/parse-string)))
(def revision-manifest
(memoize load-revision-manifest))
;; Returns the fingerprinted asset name for a file listed in the revision manifest.
(selmer/add-tag! :asset-name
(fn [args context-map]
(let [asset (first args)
manifest (revision-manifest "manifest.json")]
(or (get manifest asset) asset))))
Subsequent use in a Selmer template looks like this:
<script type="text/javascript" src="/scripts/{% asset-name application.js %}"></script>
If you're using a different templating engine or a completely different
approach, please add how you're integrating lein-buster
to the wiki!
Copyright © 2016-2019 Stephen Caudill, Terje Dahl
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close