Kendall
Kendall

Reputation: 5255

reloading from clojure file

I'm new to clojure and I'm trying to wrap my head around live reload in in clojure I want to be able to monitor/ watch all/ any project file and update the browser automatically

So far I have the following

(defproject app2 "0.1.0-SNAPSHOT"
  :description "FIXME: write this!"
  :url "http://exampl.com/FIXME"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.9.89"]
                 [ring "1.5.0"]
                 [stasis "2.2.0"]
                 [hiccup "1.0.5"]
                 [clj-tagsoup "0.3.0"]
                 [optimus "0.18.5"]
                 [ring/ring-jetty-adapter "1.5.0"]
                 [cljs-ajax "0.5.8"]
                 [enfocus "2.1.1"]]
  :plugins [[lein-cljsbuild "1.1.3"]
            [lein-ring "0.9.7"]]
  :cljsbuild {:builds [

    {:id "dev"
    :incremental true
    :source-paths ["src/cljs"]
                        :compiler {
                          :main "scripts.client"
                          :output-to "resources/public/js/main.js"
                          :output-dir "resources/public/js/out"
                          :asset-path "js/out"
                          }}]}
  :aliases {
    "start-dev" ["pdo" ["cljsbuild" "auto"] ["ring" "server-headless"]]
  }
  :source-paths ["src"]
  :resource-paths ["resources"]
  :main app2.server
  :repl-options {
                :prompt (fn [ns] (str "your command for <" ns ">, master? " ))
                :welcome (println "Welcome to the magical world of the repl!")
                :init-ns app2.hawk
                :init (app2.hawk/init)
                :caught clj-stacktrace.repl/pst+
                :skip-default-init false
                :host "0.0.0.0"
                :port 9000
                :timeout 40000
              }
  :ring {
    :init app2.hawk/init
    :handler app2.server/app
    :auto-reload? true :auto-refresh? true :reload-paths ["resources/public"]
    :refresh-paths ["resrouces/public"]
  }
  :profiles {
    :dev {
          :repl-options {
            :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]
          }
          :source-paths ["src"]
            :ring {
              :nrepl {
                :start? true
                :port 9000
                :host "0.0.0.0"
              }
            }
            :dependencies [
              [ring-refresh "0.1.1"]
              [http-kit "2.0.0"]
              [org.clojure/tools.nrepl "0.2.11"]
              [com.cemerick/piggieback "0.2.1"]
              [hawk "0.2.10"]
            ]
            :plugins [
              [lein-pdo "0.1.1"]
            ]
          }
        }

)

for my handler I have

(ns app2.server
  (:use [ring.middleware.resource :only [wrap-resource]]
        [ring.middleware.file-info :only [wrap-file-info]]
        [ring.middleware.file :only [wrap-file]]
        [ring.middleware.reload :refer [wrap-reload]]
        [ring.middleware.content-type :refer [wrap-content-type]]
        [ring.middleware.refresh :refer [wrap-refresh]]
        [ring.util.response :refer [file-response]]
       )

(defn wrap-utf-8
  "This function works around the fact that Ring simply chooses the default JVM
  encoding for the response encoding. This is not desirable, we always want to
  send UTF-8."
  [handler]
  (fn [request]
    (when-let [response (handler request)]
      (if (.contains (get-in response [:headers "Content-Type"]) ";")
        response
        (if (string? (:body response))
          (update-in response [:headers "Content-Type"] #(str % "; charset=utf-8"))
          response)))))


(defn handler [request]
            (file-response (:uri request) {:root "resources/public"}))

(def app (-> handler
             wrap-content-type
             wrap-reload
             wrap-refresh []
             wrap-utf-8))

And then I am running hawk from repl

(ns app2.hawk
(:require [hawk.core :as hawk])
(:require [app2.server :refer [export-pages]]))

(defn init
  []
  (export-pages)
  (hawk/watch! [{:paths ["src/app2/templates" "resources/templates"]
               :filter hawk/modified?
               :handler (fn [ctx e]
                          (export-pages) ;; i'm compiling html pages dynamically to the server root but how do I then notify browser than html has changed? can i force server to reload from here?
                          ctx)}]))

Upvotes: 0

Views: 336

Answers (2)

Daniel Szmulewicz
Daniel Szmulewicz

Reputation: 3961

If you don't mind using Boot instead of Leiningen, the system project will give you all the reload goodness you can expect from a Lisp, with plenty of examples.

Be sure to check the Holy Grail demo, which leverages system, to get started with minimal fuss.

Upvotes: 2

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91554

It sounds like you have put together a great setup so far. and for managing this workflow Figwheel is the logical next step. If you are doing any Clojurescript + clojure-web stuff you almost certainly should start with figwheel, you will have a much more pleasant experience.

Upvotes: 0

Related Questions