Zurb Foundation && SASS

Add Zurb Foundation or whatever webjars you want to use.

 [org.webjars/foundation "6.2.0"]
 [org.webjars/font-awesome "4.6.2"]

Setup a SASS file

I put these in src/sass/. You can import from webjars like this.

@import 'foundation/scss/foundation';
@import 'foundation/scss/util/mixins';
@import 'font-awesome/scss/font-awesome';

Watching SASS files in dev

Need to add SASS support. Checked out sass4clj. There is a lein plugin, but that didn’t play well with figwheel. I did end up using some ideas from that and the sass4clj project to integrate with figwheel.

I started with this SASS Watcher which was a good starting point, but didn’t load in the webjars. So the next step is replace with sass4clj which does reference webjars.

in dev.clj require these

[sass4clj.core :refer [sass-compile-to-file]]
[watchtower.core :refer :all]

Next create a new component to watch the SASS files and recompile on changes. A lot of these came from the lein-sass4clj project.

(defn- main-file? [file]
  (and (or (.endsWith (.getName file) ".scss")
           (.endsWith (.getName file) ".sass") )
       (not (.startsWith (.getName file) "_"))))

(defn- find-main-files [source-paths]
  (mapcat (fn [source-path]
            (let [file (io/file source-path)]
              (->> (file-seq file)
                   (filter main-file?)
                   (map (fn [x] [(.getPath x) (.toString (.relativize (.toURI file) (.toURI x)))])))))
          source-paths))

(defn watch-sass
  ""
  [input-dir output-dir options]
  (prn (format "Watching: %s -> %s" input-dir output-dir))
  (let [source-paths (vec (find-main-files [input-dir]))
        sass-fn 
        (fn compile-sass [& _]
          (doseq [[path relative-path] source-paths
                  :let [output-rel-path (clojure.string/replace relative-path #"\.(sass|scss)$" ".css")
                        output-path     (.getPath (io/file output-dir output-rel-path))]]
            (println (format "Compiling {sass}... %s -> %s" relative-path output-rel-path))
            (sass4clj.core/sass-compile-to-file
              path
              output-path
              (-> options
                  (update-in [:output-style] (fn [x] (if x (keyword x))))
                  (update-in [:verbosity] (fn [x] (or x 1)))))))
        ]
    (watchtower.core/watcher
       [input-dir]
       (watchtower.core/rate 100)
       (watchtower.core/file-filter watchtower.core/ignore-dotfiles)
       (watchtower.core/file-filter (watchtower.core/extensions :scss :sass))
       (watchtower.core/on-change sass-fn))
    )
  )

(defrecord SassWatcher [input-dir output-dir options]
  component/Lifecycle
  (start [this]
    (prn "Starting SassWatcher Component.")
    (if (not (:sass-watcher-process this))
      (do
        (println "Figwheel: Starting SASS watch process:" input-dir output-dir)
        (assoc this :sass-watcher-process (watch-sass input-dir output-dir options))
        )
      this))
  (stop [this]
    (when-let [process (:sass-watcher-process this)]
      (println "Figwheel: Stopping SASS watch process")
      (future-cancel process))
    this))

Next setup a config for compilation and add the compoent to the dev system.

(def sass-config
  {:input-dir "src/sass" ;location of the sass/scss files
   :output-dir "resources/nspkt/ui/public/css"
   :options 
   {:source-map true
    ;:output-style :nested, :compact, :expanded and :compressed
    ;:verbosity 1, 2
    }
   })

(defn new-system []
  (into (system/new-system config)
        {:figwheel (figwheel/server (:figwheel config))
         :sass (map->SassWatcher sass-config)}
        ))

Now we’re watching the files and updating on change. I think figwheel should pick up those changes and push an reload, but something doesn’t seem to be working there.