lein-dalap is a source code transformation tool that facilitates the creation and maintenance of libraries that work in Clojure and Clojurescript.
lein-dalap allows you to maintain code that works in both the JVM and in the browser, without forking your code and without relying on cljsbuild crossovers.
lein-dalap is inspired by cljx, a
leiningen plugin that transforms input source files with a .cljx
extension and special meta-data markup into .clj
and .cljs
output. In
contrast with cljx, lein-dalap's input files are plain .clj
files and
only the .cljs
files are auto-generated. It is also simpler to specify
custom transformation rules at the project level.
This guide covers lein-dalap version 0.1.0
Currently this tool has only been tested with Clojure 1.4 and leiningen 2
You will require leiningen in order to use this plugin, you'll need to add it to the plugin list of your project
(defproject some-project
;; ...
:plugins [[com.birdseye-sw/lein-dalap "0.1.0"]]
;;...
)
lein-dalap offers a similar interface to lein-cljsbuild. There are three main sub-tasks:
lein dalap auto
transforms your clj files to cljs files as
soon as it detects a change in one of themlein dalap once
transforms your clj files to cljs only oncelein dalap clean
removes all files generated by lein-dalaplein-dalap expects you to specify every Clojure source file that you
would like to transform to Clojurescript in a top-level file named
dalap_rules.clj
.
This file needs to be in the root of your project (where your
project.clj is). Specify a map of file specs (the keys) and the
transformation rules to use (the values of the map). A file spec is a
2 element vector of [input-path output-path]
. Transformation rules
are css-like selector+transformer pairs and are interpreted using
dalap. Specify them in a
vector of pairs. Leave the vector empty if you only need the default
lein-dalap rules.
{
["src/clj/util.clj" "src/cljs/util.clj"]
;; ^ the file-spec [source-clj-file target-cljs-file]
;; followed by the transformation rules for util.clj:
[
;; Rule 1
JavaClass
js_class ;; replace all the JavaClass symbols with js_class on cljs
;; Rule 2
;; You may also use functions as selectors and transformers.
;; Wrap selector functions in `dalap/when' and transformer
;; functions in `dalap/transform'. The following is a default rule:
(dalap/when (has-meta? :cljs))
(dalap/transform (replace-with-meta :cljs))
;;
;; from clojure:
;; (^{:cljs '-invoke} invoke [args] ...)
;; To clojurescript:
;; (-invoke [args] ...)
]
}
Add a file-spec for each of the files you want to transform to cljs.
By default, lein-dalap transforms some core Clojure/Java type symbols to their JS equivalents. For example
(extend-protocol IMyProtocol
java.lang.String
(my-fn [s] ...)
java.lang.Object
(my-fn [s] ...)
becomes the following Clojurescript
(extend-protocol IMyProtocol
string
(my-fn [s] ...)
default
(my-fn [s] ...))
See rules.clj in the source for all the defaults. Please note, the default JVM types specified in rules.clj
will only be transformed if they are fully qualified symbols: java.lang.Object
not Object
.
If you want to replace any form in your Clojure source with an
alternate Clojurescript form, mark the form with :cljs
meta tag
containing the quoted replacement form. For example
^{:cljs
'(ns project.test.util-tests
(:require [project.util :as utils])
(:require-macros [buster-cljs.macros :refer [deftest describe it is]]))
(ns project.test.util-tests
(:require [buster-cljs.clojure :refer [deftest describe it is]
[project.util :as utils])
To completely remove a form in the Clojurescript output, mark it with
the ^:clj
meta tag.
(defn my-fn []
^:clj
(println "hello world")
...)
The (println "hello world")
will be dropped in the Clojurescript output.
You may specify a form that will only be available in Clojurescript while
keeping it a valid Clojure form by using the #_(:cljs form)
syntax
#_(:cljs (initialize-buster))
The Clojure reader will drop it and it will translated into the following Clojurescript
(do
(initialize-buster))
Given that you will most likely be running cljsbuild alongside this plugin
you can automatically run lein-dalap when you are running cljsbuild auto or
once command, just by adding a :hooks
to your project.clj
file
(defproject my-project
;; ...
:hooks [leiningen.dalap]
;; ...
)
Congratulations, you now know how to do the most common operations with lein-dalap, let's review what we just learned:
lein dalap auto|once|clean
commands.dalap_rules.clj
specifying the files you want to transform.You may want to check out the dalap project. It is also being used to generate HTML from Clojure forms with the same css-like rule transformation system in lein-dalap.