Skip to content
Generate fingerprinted files from your static assets that are suitable for use in browser cache-busting.
Clojure
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src/leiningen Imporve user feedback Feb 26, 2016
.gitignore First commit, v 0.1.0 Feb 26, 2016
CHANGELOG.md Release 0.1.1 Feb 26, 2016
LICENSE First commit, v 0.1.0 Feb 26, 2016
README.md Add notes about integrating Feb 26, 2016
project.clj Prepare for 0.1.2 development cycle Feb 26, 2016

README.md

lein-buster

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:

  1. A fingerprinted version of your specified files in the format of <filename>-<fingerprint>.<extension>.
  2. A manifest file in JSON format so that you can map the filename you know to the generated one.

Configuration

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 {:files ["resources/public/scripts/awesome.js"]
         :manifest "resources/manifest.json"}

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]

Usage

Add [lein-buster "0.1.0"] 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"}}}

Integrating

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!

License

Copyright © 2016 Stephen Caudill

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

You can’t perform that action at this time.