Skip to content
Newer
Older
100644 243 lines (181 sloc) 7.74 KB
e0219ff @emezeske Initial commit of lein-cljsbuild.
emezeske authored Dec 28, 2011
1 # lein-cljsbuild
2
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
3 This is a leiningen plugin that makes it easy (and quick) to compile
4 ClojureScript source into JavaScript. It's similar to [cljs-watch] [1],
4e13bbd @emezeske Proselytism improvements.
emezeske authored Dec 30, 2011
5 but is driven via lein instead of via a standalone executable. This means
6 that your project can depend on a specific version of lein-cljsbuild, fetch
7 it via `lein deps`, and you don't have to install any special executables into
8 your `PATH`.
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
9
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 30, 2011
10 Also, this plugin has built-in support for seamlessly sharing code between
11 your Clojure server-side project and your ClojureScript client-side project.
12
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
13 [1]: https://github.com/ibdknox/cljs-watch
e0219ff @emezeske Initial commit of lein-cljsbuild.
emezeske authored Dec 29, 2011
14
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
15 ## Installation
e0219ff @emezeske Initial commit of lein-cljsbuild.
emezeske authored Dec 29, 2011
16
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
17 You can install the plugin via lein:
18
4b6032c @emezeske Notch the version number.
emezeske authored Jan 18, 2012
19 $ lein plugin install lein-cljsbuild 0.0.7
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
20
21 Or by adding lein-cljs to your `project.clj` file in the `:dev-dependencies`
22 section:
23
593631b @emezeske Try to appease github's markdown flavor.
emezeske authored Dec 30, 2011
24 ```clojure
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
25 (defproject lein-cljsbuild-example "1.2.3"
4b6032c @emezeske Notch the version number.
emezeske authored Jan 19, 2012
26 :dev-dependencies [[lein-cljsbuild "0.0.7"]])
593631b @emezeske Try to appease github's markdown flavor.
emezeske authored Dec 30, 2011
27 ```
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
28
29 Make sure you pull down the jar file:
30
31 $ lein deps
32
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
33 ## Just Give Me a Damned Example Already!
34
35 See the `example-projects` directory for a couple of simple examples
36 of how to use lein-cljsbuild.
37
0113e9f @emezeske s/example/sample.
emezeske authored Jan 15, 2012
38 Also, see the `sample.project.clj` file in this directory for an
31039ba @emezeske Add a note about example.project.js.
emezeske authored Jan 15, 2012
39 exhaustive list of all options supported by lein-cljsbuild.
40
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
41 ## Configuration
42
43 The lein-cljsbuild configuration is specified under the `:cljsbuild` section
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
44 of your `project.clj` file. A simple project might look like this:
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
45
593631b @emezeske Try to appease github's markdown flavor.
emezeske authored Dec 30, 2011
46 ```clojure
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
47 (defproject lein-cljsbuild-example "1.2.3"
4b6032c @emezeske Notch the version number.
emezeske authored Jan 19, 2012
48 :dev-dependencies [[lein-cljsbuild "0.0.7"]]
593631b @emezeske Try to appease github's markdown flavor.
emezeske authored Dec 30, 2011
49 :cljsbuild {
50 ; The path to the top-level ClojureScript source directory:
41bcef7 @emezeske Use namespaces for crossovers instead of dirs.
emezeske authored Dec 31, 2011
51 :source-path "src-cljs"
58b4f4f @emezeske Allow all compiler options to be passed on though.
emezeske authored Dec 31, 2011
52 ; The standard ClojureScript compiler options:
53 ; (See the ClojureScript compiler documentation for details.)
54 :compiler {
460cada @kumarshantanu fix typo in documentation
kumarshantanu authored Jan 13, 2012
55 :output-to "war/javascripts/main.js" ; default: main.js in current directory
58b4f4f @emezeske Allow all compiler options to be passed on though.
emezeske authored Jan 1, 2012
56 :optimizations :whitespace
57 :pretty-print true}})
593631b @emezeske Try to appease github's markdown flavor.
emezeske authored Dec 30, 2011
58 ```
e0219ff @emezeske Initial commit of lein-cljsbuild.
emezeske authored Dec 29, 2011
59
d40c3a9 @emezeske Add a "cljsbuild clean" task, and hook into "clean".
emezeske authored Jan 19, 2012
60 If you'd like your ClojureScript to be compiled when you run `lein compile`, and
61 deleted when you run `lein clean`, you can also add the following entry to your
62 defproject config:
d82ea57 @emezeske Add a hook for 'lein compile'.
emezeske authored Dec 30, 2011
63
4e1cf60 @emezeske Add highlighting for a block I missed.
emezeske authored Dec 31, 2011
64 ```clojure
65 :hooks [leiningen.cljsbuild]
66 ```
d82ea57 @emezeske Add a hook for 'lein compile'.
emezeske authored Dec 31, 2011
67
e0219ff @emezeske Initial commit of lein-cljsbuild.
emezeske authored Dec 29, 2011
68 ## Usage
69
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
70 Once the plugin is installed, you can build the ClojureScript once:
71
72 $ lein cljsbuild once
73
74 Or you can have lein-cljsbuild watch your source files for changes and
75 automatically rebuild them. This is recommended for development, as it
76 avoids the time-consuming JVM startup for each build:
77
78 $ lein cljsbuild auto
e0219ff @emezeske Initial commit of lein-cljsbuild.
emezeske authored Dec 29, 2011
79
d40c3a9 @emezeske Add a "cljsbuild clean" task, and hook into "clean".
emezeske authored Jan 19, 2012
80 To delete all of the JavaScript and ClojureScript files that lein-cljsbuild
81 automatically generated during compilation, run:
82
83 $ lein cljsbuild clean
84
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
85 ## Sharing Code Between Clojure and ClojureScript
86
87 Sharing code with lein-cljsbuild is accomplished via the configuration
c5b2f41 @emezeske Document the use of CLASSPATH for crossovers.
emezeske authored Jan 19, 2012
88 of "crossovers". A crossover specifies a Clojure namespace, the content
89 of which should be copied into your ClojureScript project. This can be any
90 namespace that is available via the Java CLASSPATH, which includes your
91 project's main :source-path by default.
92
93 When a crossover namespace is provided by your current project (either via the
94 main :source-dir or one of the :extra-classpath-dirs in your project.clj file),
95 the files that make up that namespace (recursively) will be monitored for changes,
96 and will be copied to the ClojureScript project whenever modified.
97
98 Crossover namespaces provided by jar files cannot be searched recursively, and
99 thus must be specified on a per-file basis. They are copied over once, when
100 lein-cljsbuild begins compilation, and are not monitored for changes.
101
102 Of course, remember that since the namespace will be used by both Clojure
41bcef7 @emezeske Use namespaces for crossovers instead of dirs.
emezeske authored Jan 1, 2012
103 and ClojureScript, it will need to only use the subset of features provided by
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
104 both languages.
105
41bcef7 @emezeske Use namespaces for crossovers instead of dirs.
emezeske authored Jan 1, 2012
106 Assuming that your top-level directory structure looks something like this:
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
107
108 <pre>
109 ├── src-clj
110 │   └── example
111 │   ├── core.clj
112 │   ├── something.clj
113 │   └── crossover
114 │      ├── some_stuff.clj
115 │      └── some_other_stuff.clj
116 └── src-cljs
117    └── example
118    ├── core.cljs
119    ├── whatever.cljs
120    └── util.cljs
121 </pre>
122
41bcef7 @emezeske Use namespaces for crossovers instead of dirs.
emezeske authored Jan 1, 2012
123 And your `project.clj` file looks like this:
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
124
125 ```clojure
126 (defproject lein-cljsbuild-example "1.2.3"
4b6032c @emezeske Notch the version number.
emezeske authored Jan 19, 2012
127 :dev-dependencies [[lein-cljsbuild "0.0.7"]]
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
128 :source-path "src-clj"
129 :cljsbuild {
41bcef7 @emezeske Use namespaces for crossovers instead of dirs.
emezeske authored Jan 1, 2012
130 :source-path "src-cljs"
131 ; Each entry in the :crossovers vector describes a Clojure namespace
132 ; that is meant to be used with the ClojureScript code as well.
133 ; The files that make up this namespace will be automatically copied
134 ; into the ClojureScript source path whenever they are modified.
135 :crossovers [example.crossover]
58b4f4f @emezeske Allow all compiler options to be passed on though.
emezeske authored Jan 1, 2012
136 :compiler {
460cada @kumarshantanu fix typo in documentation
kumarshantanu authored Jan 12, 2012
137 :output-to "war/javascripts/main.js" ; default: main.js in current directory
58b4f4f @emezeske Allow all compiler options to be passed on though.
emezeske authored Jan 1, 2012
138 :optimizations :whitespace
139 :pretty-print true}})
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
140 ```
141
142 Then lein-cljsbuild would copy files from `src-clj/example/crossover`
143 to `src-cljs/example/crossover`, and you'd end up with this:
144
145 <pre>
146 ├── src-clj
147 │   └── example
148 │   ├── a_file.clj
149 │   ├── core.clj
150 │   └── crossover
151 │      ├── some_stuff.clj
152 │      └── some_other_stuff.clj
153 └── src-cljs
154    └── example
155    ├── a_different_file.cljs
156    ├── crossover
157    │   ├── some_stuff.cljs
158    │   └── some_other_stuff.cljs
159    ├── whatever.cljs
160    └── util.cljs
161 </pre>
162
163 With this setup, you would probably want to add `src-cljs/example/crossover`
164 to your `.gitignore` file (or equivalent), as its contents are updated automatically
165 by lein-cljsbuild.
166
167 ## Sharing Macros Between Clojure and ClojureScript
168
169 In ClojureScript, macros are still written in Clojure, and can not be written
170 in the same file as actual ClojureScript code. Also, to use them in a ClojureScript
171 namespace, they must be required via `:require-macros` rather than the usual `:require`.
172
173 This makes using the crossover feature to share macros between Clojure and ClojureScript
174 a bit difficult, but lein-cljsbuild has some special constructs to make it possible.
175
176 Three things need to be done to use lein-cljsbuild to share macros.
177
178 ### 1. Keep Macros in Separate Files
179
180 These examples assume that your project uses the `src-clj/example/crossover`
181 directory, and that all of the macros are in a file called
182 `src-clj/example/crossover/macros.clj`.
183
184 ### 2. Tell lein-cljsbuild Which Files Contain Macros
185
186 Add this magical comment to any crossover files that contain macros:
187
188 ```clojure
189 ;*CLJSBUILD-MACRO-FILE*;
190 ```
191
c5b2f41 @emezeske Document the use of CLASSPATH for crossovers.
emezeske authored Jan 20, 2012
192 This tells lein-cljsbuild to refrain from copying the `.clj` files
193 into the ClojureScript directory. This step can be skipped if the
194 macro file is not included in any of the crossover namespaces.
91e8506 @emezeske Adding crossover support and examples.
emezeske authored Dec 31, 2011
195
196 ### 3. Use Black Magic to Require Macros Specially
197
198 In any crossover Clojure file, lein-cljsbuild will automatically erase the
199 following string (if it appears):
200
201 ```clojure
202 ;*CLJSBUILD-REMOVE*;
203 ```
204
205 This magic can be used to generate a `ns` statement that will work in both
206 Clojure and ClojureScript:
207
208 ```clojure
209 (ns example.crossover.some_stuff
210 (:require;*CLJSBUILD-REMOVE*;-macros
211 [example.crossover.macros :as macros]))
212 ```
213
214 Thus, after removing comments, Clojure will see:
215
216 ```clojure
217 (ns example.crossover.some_stuff
218 (:require
219 [example.crossover.macros :as macros]))
220 ```
221
222 However, lein-cljsbuild will remove the `;*CLJSBUILD-REMOVE*;` string entirely,
223 before copying the file. Thus, ClojureScript will see:
224
225 ```clojure
226 (ns example.crossover.some_stuff
227 (:require-macros
228 [example.crossover.macros :as macros]))
229 ```
230
231 And thus the macros can be shared.
232
e0219ff @emezeske Initial commit of lein-cljsbuild.
emezeske authored Dec 29, 2011
233 ## License
234
460cada @kumarshantanu fix typo in documentation
kumarshantanu authored Jan 12, 2012
235 Source Copyright © Evan Mezeske, 2011-2012.
cb80cbc @emezeske Preparing for release.
emezeske authored Dec 30, 2011
236 Released under the Eclipse Public License - v 1.0.
237 See the file COPYING.
27ded34 @emezeske Add a contributors section.
emezeske authored Jan 12, 2012
238
239 ## Contributors
240
241 * Evan Mezeske **(Author)** (evan@mezeske.com)
242 * Shantanu Kumar (kumar.shantanu@gmail.com)
Something went wrong with that request. Please try again.