├── .gitignore ├── .travis.yml ├── README.md ├── build.sh ├── example ├── .gitignore ├── README.md ├── project.clj ├── resources │ └── public │ │ └── index-dev.html └── src │ ├── clj │ └── hello │ │ └── core.clj │ └── cljs │ └── hello │ └── core.cljs ├── project.clj └── src └── lively └── core.cljs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | /.idea 11 | *.iml 12 | cljsbuild.out 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: clojure 2 | script: ./build.sh 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lively [](https://travis-ci.org/immoh/lively) 2 | 3 | ClojureScript live coding with ease 4 | 5 | Lively monitors compiled JavaScript files for changes and reloads them when they 6 | change, so that you don't have to. This creates a development environment where you can edit ClojureScript code and see the changes 7 | immediately in your browser without needing to refresh the page. 8 | 9 | Lively does not compile ClojureScript. (I recommend using [lein-cljsbuild](https://github.com/emezeske/lein-cljsbuild) for that.) 10 | 11 | Lively does not provide web server for serving JavaScript files. 12 | 13 | 14 | ## Installation 15 | 16 | Add the following Leiningen dependency: 17 | 18 | ```clojure 19 | [lively "0.2.1"] 20 | ``` 21 | 22 | ## Usage 23 | 24 | Prerequisites: 25 | 26 | * ClojureScript version 0.0-2202 or newer 27 | * ClojureScript is compiled with `:optimizations` set to `:none` 28 | * JavaScript files are loaded over HTTP 29 | 30 | Simply include call to `lively/start` somewhere in your ClojureScript codebase, passing the location of the main JavaScript file 31 | (this is the value of `src` attribute of the `script` tag loading the file in your HTML markup): 32 | 33 | ```clojure 34 | (ns your.app 35 | (:require [lively.core :as lively])) 36 | 37 | (lively/start "/js/hello.js") 38 | ``` 39 | 40 | Call to `start` is idempotent, it is safe to call it multiple times. 41 | 42 | The followig options can be passed as an optional options map: 43 | 44 | * `:polling-rate`: Milliseconds to sleep between polls. Defaults to 1000. 45 | * `:on-reload`: Callback function to call after files have been reloaded. 46 | 47 | For example: 48 | 49 | ```clojure 50 | (lively/start "/js/hello.js" {:polling-rate 500 51 | :on-reload (fn [] (.log js/console "Reloaded!"))}) 52 | ``` 53 | 54 | ## Examples 55 | 56 | * Minimalistic example project can be found in [example](https://github.com/immoh/lively/tree/master/example) directory. 57 | * [Lively Snake Demo](https://github.com/immoh/lively-snake-demo) showcases implementing a snake game using Lively 58 | 59 | 60 | ## How does it work? 61 | 62 | Lively monitors changes in JavaScript files by making consecutive HEAD requests to the server. 63 | When ClojureScript files are compiled, the main JavaScript file is always is generated again and this change is 64 | noticed by Lively. Lively finds out which namespaces have changed by making HEAD requests for each namespace-specific 65 | JavaScript file and reloads ones that have changed. 66 | 67 | 68 | ## License 69 | 70 | Copyright © 2014-2015 Immo Heikkinen 71 | 72 | Distributed under the Eclipse Public License, the same as Clojure. 73 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o pipefail 4 | set -e 5 | 6 | OUTPUT_FILE="cljsbuild.out" 7 | 8 | if lein do clean, cljsbuild once 2>&1 | tee $OUTPUT_FILE 9 | then 10 | ! grep WARNING $OUTPUT_FILE 11 | else 12 | exit $? 13 | fi 14 | 15 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | /.idea 11 | *.iml 12 | /resources/public/js 13 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Lively example project 2 | 3 | This is a minimal example project showing [lively](http://github.com/immoh/lively) in action. 4 | 5 | 6 | ## Instructions 7 | 8 | 9 | 1. **Start ClojureScript compiler** 10 | 11 | In terminal: 12 | 13 | ``` 14 | lein cljsbuild auto 15 | ``` 16 | 17 | 2. **Start the server** 18 | 19 | In another terminal: 20 | 21 | ``` 22 | lein ring server 23 | ``` 24 | 25 | This should automatically open a web browser, if not, navigate to 26 | [http://localhost:3000/index-dev.html](http://localhost:3000/index-dev.html). 27 | 28 | 29 | 3. **Start hacking** 30 | 31 | Open your favorite editor and start editing ClojureScript files in [src/cljs](http://github.com/immoh/lively/blob/0.1.0/example/src/cljs). Your changes 32 | are automatically reflected in the browser with no need to reload the page! 33 | 34 | For example, try editing the greeting text in [greet](http://github.com/immoh/lively/blob/0.1.0/example/src/cljs/hello/core.cljs#L5) function. 35 | After saving the file, click on the greet button. 36 | 37 | 38 | Copyright © 2014 Immo Heikkinen 39 | -------------------------------------------------------------------------------- /example/project.clj: -------------------------------------------------------------------------------- 1 | (defproject hello "0.1.0-SNAPSHOT" 2 | :min-lein-version "2.0.0" 3 | :source-paths ["src/clj"] 4 | :dependencies [[org.clojure/clojure "1.6.0"] 5 | [org.clojure/clojurescript "0.0-2850"] 6 | [compojure "1.2.0"] 7 | [lively "0.2.0"]] 8 | :plugins [[lein-ring "0.8.12"] 9 | [lein-cljsbuild "1.0.3"]] 10 | :ring {:handler hello.core/app 11 | :browser-uri "/index-dev.html"} 12 | :cljsbuild {:builds {:main {:source-paths ["src/cljs"] 13 | :compiler {:output-to "resources/public/js/hello.js" 14 | :output-dir "resources/public/js/out" 15 | :optimizations :none}}}}) 16 | -------------------------------------------------------------------------------- /example/resources/public/index-dev.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |