ClojuTRE - Build tooling with Boot
-
Upload
metosin -
Category
Technology
-
view
939 -
download
2
description
Transcript of ClojuTRE - Build tooling with Boot
![Page 1: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/1.jpg)
Build tooling with Boot
Juho Teperi / Metosin
ClojuTRE
25.11.2014
![Page 2: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/2.jpg)
Contents
• Example project• Challenges with Leiningen• Solutions using Boot• Summary
![Page 3: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/3.jpg)
Example project
• “(Typical) full-stack Clojure project”• src/clj, backend code• src/cljs• src/cljx, shared code• src/less (or sccs, garden etc.)
![Page 4: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/4.jpg)
Leiningen
• Configuration over code• Great with pure Clojure
projects• Plugins provide additional
tasks
![Page 5: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/5.jpg)
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
![Page 6: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/6.jpg)
Lein, problem #1
• Each lein command starts a JVM• Most commands fork another for the task
• 7 JVMs• much GB• Slow start up
![Page 7: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/7.jpg)
Lein, problem #2
• Plugins are not composable• Descriptive configuration doesn’t help• Each lein plugin implements the file watching
themselves• Each implementation works differently…
![Page 8: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/8.jpg)
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
![Page 9: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/9.jpg)
: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
![Page 10: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/10.jpg)
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
![Page 11: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/11.jpg)
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.
![Page 12: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/12.jpg)
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
![Page 13: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/13.jpg)
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
![Page 14: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/14.jpg)
(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 (watch) (cljs-repl) (cljx) (start-app) (cljs :optimizations :none) (reload :on-jsload 'saapas.core/main)))
(deftask dev-repl "Connect to the repl started by the dev task." [] (repl :client true))
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
notifications to browser.
![Page 15: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/15.jpg)
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
![Page 16: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/16.jpg)
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
![Page 17: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/17.jpg)
Questions?
![Page 18: ClojuTRE - Build tooling with Boot](https://reader030.fdocuments.us/reader030/viewer/2022020218/559b33ad1a28ab3e638b4646/html5/thumbnails/18.jpg)
Links
• http://boot-clj.com/ • https://github.com/Deraen/saapas• #hoplon @ Freenode