Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Build tooling with Boot 
Juho Teperi / Metosin 
ClojuTRE 
25.11.2014
Contents 
• Example project 
• Challenges with Leiningen 
• Solutions using Boot 
• Summary
Example project 
• “(Typical) full-stack Clojure project” 
• src/clj, backend code 
• src/cljs 
• src/cljx, shared code 
•...
Leiningen 
• Configuration over code 
• Great with pure Clojure 
projects 
• Plugins provide additional 
tasks
Example project using Lein 
• Uses multiple lein plugins 
• lein cljx auto 
• lein cljsbuild auto (or figwheel) 
• lein le...
Lein, problem #1 
• Each lein command starts a JVM 
• Most commands fork another for the task 
• 7 JVMs 
• much GB 
• Slow...
Lein, problem #2 
• Plugins are not composable 
• Descriptive configuration doesn’t help 
• Each lein plugin implements th...
Lein, problem #3 
• Target directory is in effect a temporary 
directory 
• Lein uberjar 
• Uses different cljs compiler o...
:source-paths ["src/clj" "target/generated/clj"] 
:test-paths ["test/clj"] 
:cljsbuild {:builds {:app {:source-paths ["src...
Boot (2) 
• Alternative build tool 
• Boot 1 is the old version 
• Boot 2 is the new one. It’s a significantly 
different ...
Boot, solution #1 
• “Lein launches multiple JVMs and uses lots of memory” 
• All tasks run in the same JVM 
• Separate cl...
Boot, solution #2 
• “Lein tasks are not composable, each plugin implements 
e.g. file watching themselves” 
• Tasks are f...
Boot, solution #3 
• “Dev and production tasks interfere because they use 
same directories” 
• Tasks create temporary dir...
(set-env! 
:src-paths #{"src/clj" "src/cljs" "src/cljx"} 
:rsc-paths #{"resources"} 
:dependencies '[[adzerk/boot-cljs "0....
Challenges with Boot 
• IDE Support 
• Editors using nrepl work (fireplace, cider) 
• Keep project.clj around for Cursive ...
Summary 
Lein Boot 
Task envs Forks new JVMs Multiple classloaders in 
one JVM 
Configuration Configuration over 
code 
Co...
Questions?
Links 
• http://boot-clj.com/ 
• https://github.com/Deraen/saapas 
• #hoplon @ Freenode
Upcoming SlideShare
Loading in …5
×

ClojuTRE - Build tooling with Boot

1,067 views

Published on

Leiningen is great for pure Clojure projects. So why would one be interested in other Clojure build tools?

I've been working with full-stack Clojure project for some months now. Figwheel provides nice workflow with live reloading for ClojureScript projects but from the start of the project I felt Lein leaves some things to be desired.

Boot is a new build tool for Clojure. And I'll show how it improves on some areas in comparision to Leiningen.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

ClojuTRE - Build tooling with Boot

  1. 1. Build tooling with Boot Juho Teperi / Metosin ClojuTRE 25.11.2014
  2. 2. Contents • Example project • Challenges with Leiningen • Solutions using Boot • Summary
  3. 3. Example project • “(Typical) full-stack Clojure project” • src/clj, backend code • src/cljs • src/cljx, shared code • src/less (or sccs, garden etc.)
  4. 4. Leiningen • Configuration over code • Great with pure Clojure projects • Plugins provide additional tasks
  5. 5. Example project using Lein • Uses multiple lein plugins • lein cljx auto • lein cljsbuild auto (or figwheel) • lein less auto • lein repl • + unit tests • Several of these plugins watch for file changes • There are ways to combine all into one command
  6. 6. Lein, problem #1 • Each lein command starts a JVM • Most commands fork another for the task • 7 JVMs • much GB • Slow start up
  7. 7. Lein, problem #2 • Plugins are not composable • Descriptive configuration doesn’t help • Each lein plugin implements the file watching themselves • Each implementation works differently…
  8. 8. Lein, problem #3 • Target directory is in effect a temporary directory • Lein uberjar • Uses different cljs compiler options • Probably uses same target path • First thing to try if you have problems: lein clean
  9. 9. :source-paths ["src/clj" "target/generated/clj"] :test-paths ["test/clj"] :cljsbuild {:builds {:app {:source-paths ["src/cljs" "target/generated/cljs"] :compiler {:output-to "resources/public/js/bootcamp.js" :output-dir "resources/public/js/out" :source-map "resources/public/js/out.js.map" :preamble ["react/react.min.js"] :externs ["react/externs/react.js"] :optimizations :none :pretty-print true}}}} :profiles {:dev {:plugins [[lein-figwheel "0.1.5-SNAPSHOT"] [lein-cljsbuild "1.0.3"] [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]]] :figwheel {:http-server-root "public" :port 3449 :css-dirs ["resources/public/css"]} :cljx {:builds [{:rules :clj :source-paths ["src/cljx"] :output-path "target/generated/clj"} {:rules :cljs :source-paths ["src/cljx"] :output-path "target/generated/cljs"}]} :cljsbuild {:builds {:app {:source-paths ["dev-src/cljs"]}}}} + This is missing e.g. uberjar settings for optimized cljs build
  10. 10. Boot (2) • Alternative build tool • Boot 1 is the old version • Boot 2 is the new one. It’s a significantly different as the old one. • Alpha • API changes are imminent etc. • Active development
  11. 11. Boot, solution #1 • “Lein launches multiple JVMs and uses lots of memory” • All tasks run in the same JVM • Separate classloaders to prevent deps leaking • Btw. this is the same technique which is used by the app servers • Disclaimer: I have not tested the memory consumption.
  12. 12. Boot, solution #2 • “Lein tasks are not composable, each plugin implements e.g. file watching themselves” • Tasks are functions • New tasks are composed from existing tasks using regular methods: comp • File watching is a task • Which can be composed together with other tasks
  13. 13. Boot, solution #3 • “Dev and production tasks interfere because they use same directories” • Tasks create temporary directories as needed • Tasks use Boot API to find sources and publish their results • Cljx uses API to create temp dir, writes results to the dir... • Cljs asks for source files using the API -> sources include those written by cljx task • Processes don’t interfere with each other • running boot package to create production jar shouldn’t leave around files which break dev build • No need for clean-task
  14. 14. (set-env! :src-paths #{"src/clj" "src/cljs" "src/cljx"} :rsc-paths #{"resources"} :dependencies '[[adzerk/boot-cljs "0.0-2371-27"] [adzerk/boot-cljs-repl "0.1.6"] [adzerk/boot-reload "0.1.6"] [deraen/boot-cljx "0.1.0-SNAPSHOT"] … project deps … ]) (task-options! cljs [:output-to "public/main.js" :source-map true :unified true]) (deftask dev "Start the dev env..." [] (comp Global options ● Watch: all following tasks run whenever there is file change. ● cljs-repl, start-app are implemented so that they only run once. ● (start-app is specific to the project) ● cljs, cljx no-op if no file changes for them ● Reload: Like figwheel. Sends websocket (watch) (cljs-repl) (cljx) (start-app) (cljs :optimizations :none) (reload :on-jsload 'saapas.core/main))) notifications to browser. (deftask dev-repl "Connect to the repl started by the dev task." [] (repl :client true))
  15. 15. Challenges with Boot • IDE Support • Editors using nrepl work (fireplace, cider) • Keep project.clj around for Cursive (and maybe others) • Missing tasks (less, unit testing…) • boot-cljx was easy to create, so should be the others
  16. 16. Summary Lein Boot Task envs Forks new JVMs Multiple classloaders in one JVM Configuration Configuration over code Composable functions Files Static classpath (target, resources) Tasks create temp dirs Equivalent JS tool Grunt Gulp, Broccoli
  17. 17. Questions?
  18. 18. Links • http://boot-clj.com/ • https://github.com/Deraen/saapas • #hoplon @ Freenode

×