├── README.md ├── build.clj └── deps.edn /README.md: -------------------------------------------------------------------------------- 1 | # Figwheel enabled build script for Clojure CLI tools 2 | 3 | This serves as an example. 4 | See the [blog post](http://www.functionalbytes.nl/clojure/nodejs/figwheel/repl/clojurescript/cli/2017/12/20/tools-deps-figwheel.html) for more information. 5 | 6 | ## Usage 7 | 8 | 1. Install [Clojure CLI tools](https://clojure.org/guides/deps_and_cli). 9 | 10 | 2. Execute shell commands like `clojure build.clj compile watch` or `clj -R:repl build.clj figwheel`. 11 | -------------------------------------------------------------------------------- /build.clj: -------------------------------------------------------------------------------- 1 | (require '[cljs.build.api :as api] 2 | '[clojure.java.shell :as shell] 3 | '[clojure.string :as string]) 4 | 5 | ;;; Configuration. 6 | 7 | (def source-dir "src") 8 | 9 | (def test-dir "test") 10 | 11 | (def compiler-config {:main 'my-app.core 12 | :output-to "target/my-app/main.js" 13 | :output-dir "target/my-app/main" 14 | :target :nodejs 15 | :optimizations :simple 16 | :source-map "target/my-app/main.js.map"}) 17 | 18 | (def test-config {:main 'my-app.test-runner 19 | :output-to "target/test.js" 20 | :output-dir "target/test" 21 | :target :nodejs 22 | :optimizations :none 23 | :source-map true}) 24 | 25 | (def test-environment {:SOME_ENV_VAR "some-env-value"}) 26 | 27 | (def dev-config (merge compiler-config 28 | {:optimizations :none 29 | :source-map true})) 30 | 31 | 32 | ;;; Tasks mechanism. 33 | 34 | (defmulti task first) 35 | 36 | (defmethod task :default 37 | [args] 38 | (let [all-tasks (-> task methods (dissoc :default) keys sort (->> (interpose ", ") (apply str)))] 39 | (println "unknown or missing task argument. Choose one of:" all-tasks) 40 | (System/exit 1))) 41 | 42 | 43 | ;;; Helper functions. 44 | 45 | (defn run-node-tests [] 46 | (let [{:keys [out err exit]} (shell/sh "node" "target/test.js" :env test-environment)] 47 | (println out err) 48 | (= exit 0))) 49 | 50 | (defn try-require [ns-sym] 51 | (try (require ns-sym) true (catch Exception e false))) 52 | 53 | (defmacro with-namespaces 54 | [namespaces & body] 55 | (if (every? try-require namespaces) 56 | `(do ~@body) 57 | `(do (println "task not available - required dependencies not found") 58 | (System/exit 1)))) 59 | 60 | 61 | ;;; Compiling task. 62 | 63 | (defn compile-once [] 64 | (api/build source-dir compiler-config)) 65 | 66 | (defn compile-refresh [] 67 | (api/watch source-dir compiler-config)) 68 | 69 | (defmethod task "compile" [[_ type]] 70 | (case type 71 | (nil "once") (compile-once) 72 | "watch" (compile-refresh) 73 | (do (println "Unknown argument to compile task:" type) 74 | (System/exit 1)))) 75 | 76 | 77 | ;;; Testing task 78 | 79 | (defn test-once [] 80 | (api/build (api/inputs source-dir test-dir) test-config) 81 | (let [success? (run-node-tests)] 82 | (System/exit (if success? 0 1)))) 83 | 84 | (defn test-refresh [] 85 | (api/watch (api/inputs source-dir test-dir) 86 | (assoc test-config :watch-fn run-node-tests))) 87 | 88 | (defmethod task "test" [[_ type]] 89 | (case type 90 | (nil "once") (test-once) 91 | "watch" (test-refresh) 92 | (do (println "Unknown argument to test task:" type) 93 | (System/exit 1)))) 94 | 95 | 96 | ;;; Figwheeling task 97 | 98 | (defmethod task "figwheel" [[_ port]] 99 | (with-namespaces [figwheel-sidecar.repl-api] 100 | (figwheel-sidecar.repl-api/start-figwheel! 101 | {:figwheel-options (cond-> {} 102 | port (merge {:nrepl-port (some-> port Long/parseLong) 103 | :nrepl-middleware ["cider.nrepl/cider-middleware" 104 | "refactor-nrepl.middleware/wrap-refactor" 105 | "cemerick.piggieback/wrap-cljs-repl"]})) 106 | :all-builds [{:id "dev" 107 | :figwheel true 108 | :source-paths [source-dir] 109 | :compiler dev-config}]}) 110 | (when-not port 111 | (figwheel-sidecar.repl-api/cljs-repl)))) 112 | 113 | 114 | ;;; Build script entrypoint. 115 | 116 | (task *command-line-args*) 117 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {org.clojure/clojurescript {:mvn/version "1.9.946"}} 2 | 3 | :aliases {:repl 4 | {:extra-deps 5 | {;; Figwheel ClojureScript REPL 6 | com.cemerick/piggieback {:mvn/version "0.2.2" 7 | :exclusions [com.google.javascript/closure-compiler]} 8 | figwheel-sidecar {:mvn/version "0.5.14" 9 | :exclusions [com.google.javascript/closure-compiler]} 10 | 11 | ;; CIDER compatible nREPL 12 | cider/cider-nrepl {:mvn/version "0.15.1"} 13 | org.clojure/tools.nrepl {:mvn/version "0.2.12"} 14 | refactor-nrepl {:mvn/version "2.3.1"}}}}} 15 | --------------------------------------------------------------------------------