Code Monkey home page Code Monkey logo

lein-cljsbuild's Introduction

lein-cljsbuild

Latest version:

Clojars Project

This is a Leiningen plugin that makes it quick and easy to automatically compile your ClojureScript code into Javascript whenever you modify it. It's simple to install and allows you to configure the ClojureScript compiler from within your project.clj file.

Beyond basic compiler support, lein-cljsbuild can optionally help with a few other things:

The latest version of lein-cljsbuild is 1.1.8. See the release notes here.

Note that cljsbuild crossovers are deprecated, and will be removed eventually. You should never use them. Please use either reader conditionals (available in Clojure >= 1.7.0-beta2 and ClojureScript >= 0.0-3255), or cljx to target both Clojure and ClojureScript from the same codebase.

If you are using ClojureScript >= 1.7.170 you need to use a lein-cljsbuild version >= 1.1.1.

Requirements

The lein-cljsbuild plugin works with Leiningen version 2.1.2 or higher.

Installation

You can install the plugin by adding lein-cljsbuild to your project.clj file in the :plugins section:

(defproject lein-cljsbuild-example "1.2.3"
  :plugins [[lein-cljsbuild "1.1.8"]])

In addition, you should add an explicit ClojureScript dependency to your project using the ClojureScript version you want to use:

:dependencies [[org.clojure/clojurescript "1.9.521"]]

lein-cljsbuild will add a dependency to your project if it doesn't already contain one, but that functionality will not remain for long. The latest version of lein-cljsbuild currently requires a minimum of ClojureScript 0.0-3211.

Just Give Me a Damned Example Already!

See the example-projects directory for a couple of simple examples of how to use lein-cljsbuild. The simple project shows a dead-simple "compile only" configuration, which is a good place to start. The advanced project contains examples of how to use the extended features of the plugin.

For an exhaustive list of all options supported by lein-cljsbuild, see the sample.project.clj file. For a list of options that can be passed to the ClojureScript compiler have a look at the ClojureScript Compiler Options site.

Basic Configuration

The lein-cljsbuild configuration is specified under the :cljsbuild section of your project.clj file. A simple project might look like this:

(defproject lein-cljsbuild-example "1.2.3"
  :plugins [[lein-cljsbuild "1.1.8"]]
  :cljsbuild {
    :builds [{
        ; The path to the top-level ClojureScript source directory:
        :source-paths ["src-cljs"]
        ; The standard ClojureScript compiler options:
        ; (See the ClojureScript compiler documentation for details.)
        :compiler {
          :output-to "war/javascripts/main.js"  ; default: target/cljsbuild-main.js
          :optimizations :whitespace
          :pretty-print true}}]})

Basic Usage

Once the plugin is installed, you can build the ClojureScript once:

$ lein cljsbuild once

Or you can have lein-cljsbuild watch your source files for changes and automatically rebuild them. This is recommended for development, as it avoids the time-consuming JVM startup for each build:

$ lein cljsbuild auto

Assuming you have configured cljsbuild to emit compiler output to one of Leiningen's :clean-targets (which includes ./target by default), running lein clean will delete all of the JavaScript and ClojureScript files that lein-cljsbuild generates during compilation.

Color-coded output on Windows

Colors are a big deal when reading ClojureScript compiler output, but Windows consoles don't support ANSI color codes. This limitation is commonly corrected by installing ANSICON:

  1. Download and unzip ANSICON anywhere.
  2. Open a command prompt (Run as administrator).
  3. Navigate to the unzipped folder.
  4. cd x86 or x64 (depending on whether you have 32-bit or 64-bit machine, respectively)
  5. Run ansicon -i to install.

Afterwards, you should get colored output from all future console sessions that use ANSI color codes.

Hooks

Some common lein-cljsbuild tasks can hook into the main Leiningen tasks to enable ClojureScript support in each of them. The following tasks are supported:

$ lein compile
$ lein test
$ lein jar

To enable ClojureScript support for these tasks, add the following entry to your project configuration:

:hooks [leiningen.cljsbuild]

Note that by default the lein jar task does not package your ClojureScript code in the JAR file. This feature needs to be explicitly enabled by adding the following entry to each of the :builds that you want included in the JAR file. lein uberjar derives its behavior from lein jar and will include the ClojureScript as well if enabled.

:jar true

Debug Note: There is a known issue (#366) where the lein uberjar task fails to build when using hooks and a cljsbuild configuration within an :uberjar profile. Instead of hooks, you can use :prep-tasks as an alternative:

:prep-tasks ["compile" ["cljsbuild" "once"]]

Multiple Build Configurations

If the :builds sequence contains more than one map lein-cljsbuild will treat each map as a separate ClojureScript compiler configuration, and will build all of them in parallel:

(defproject lein-cljsbuild-example "1.2.3"
  :plugins [[lein-cljsbuild "1.1.8"]]
  :cljsbuild {
    :builds [
      {:source-paths ["src-cljs-main"]
       :compiler {:output-to "main.js"}}
      {:source-paths ["src-cljs-other"]
       :compiler {:output-to "other.js"}}]})

This is extremely convenient for doing library development in ClojureScript. This allows cljsbuild to compile in all four optimization levels at once, for easier testing, or to compile a test suite alongside the library code.

You can optionally assign an ID to a build configuration and build only that one:

(defproject lein-cljsbuild-example "1.2.3"
  :plugins [[lein-cljsbuild "1.1.8"]]
  :cljsbuild {
    :builds [
      {:source-paths ["src-cljs-main"]
       :compiler {:output-to "main.js"}}
      {:id "other"
       :source-paths ["src-cljs-other"]
       :compiler {:output-to "other.js"}}]})
$ lein cljsbuild auto other

If you want IDs for all of your build configurations, you can specify them as a map instead of a vector:

(defproject lein-cljsbuild-example "1.2.3"
  :plugins [[lein-cljsbuild "1.1.8"]]
  :cljsbuild {
    :builds {
      :main
      {:source-paths ["src-cljs-main"]
       :compiler {:output-to "main.js"}}
      :other
      {:source-paths ["src-cljs-other"]
       :compiler {:output-to "other.js"}}}})

You can also build multiple configurations at once:

$ lein cljsbuild auto main other

See the example-projects/advanced directory for a working example of a project that uses this feature.

REPL Support

Lein-cljsbuild has built-in support for launching ClojureScript REPLs in a variety of ways. See the REPL documentation for more details.

Testing Support

Lein-cljsbuild has built-in support for running external ClojureScript test processes. See the testing documentation for more details.

Extended Configuration

Custom warning handlers

You can place custom warning handlers for the ClojureScript compiler under the :warning-handlers key. The value should be a vector of either 1.) fully-qualified symbols that resolve to your custom handler, or 2.) anonymous functions that will get eval'd at project build-time.

(defproject lein-cljsbuild-example "1.2.3"
  :plugins [[lein-cljsbuild "1.0.4"]]
  :cljsbuild {
    :builds {:id           "example"
             :compiler     {}
             :warning-handlers [my.ns/custom-warning-handler ;; Fully-qualified symbol
                                ;; Custom function (to be evaluated at project build-time)
                                (fn [warning-type env extra]
                                  (when-let [s (cljs.analyzer/error-message warning-type extra)]
                                    (binding [*out* *err*]
                                      (cljs.analyzer/message env s))))]}})

ClojureScript Version

After configuring lein-cljsbuild, lein deps will fetch a known-good version of the ClojureScript compiler. You can use a different version of the compiler via a local clone of the ClojureScript git repository. See the wiki for details.

License

Source Copyright © Evan Mezeske, 2011-2013. Released under the Eclipse Public License - v 1.0. See the file COPYING.

Contributors

A big thank you to all contributors who help to make this project better.

lein-cljsbuild's People

Contributors

avasenin avatar bitemyapp avatar bostonaholic avatar cemerick avatar cprice404 avatar deraen avatar emezeske avatar ericnormand avatar fhd avatar gaverhae avatar hsalokor avatar hura avatar jeluard avatar jenanwise avatar krisajenkins avatar kumarshantanu avatar levand avatar magomimmo avatar matthiasn avatar mfikes avatar mneise avatar noprompt avatar paulbutcher avatar psalaberria002 avatar puredanger avatar sgrove avatar skuro avatar slagyr avatar tonsky avatar trieloff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lein-cljsbuild's Issues

Exception with cljsbuild once in windows

Hi..I'm trying use clojurescript in win...actually I'm follow the tutorial from
http://djhworld.github.com/2012/02/12/getting-started-with-clojurescript-and-noir.html

this work in linux but not when I use windows....
I get this exception:

lein cljsbuild once
Downloading: cljsbuild/cljsbuild/0.0.13/cljsbuild-0.0.13.pom from repository central at http://repo1.maven.org/maven2
Unable to locate resource in repository
[INFO] Unable to find resource 'cljsbuild:cljsbuild:pom:0.0.13' in repository central (http://repo1.maven.org/maven2)
Downloading: cljsbuild/cljsbuild/0.0.13/cljsbuild-0.0.13.pom from repository clojars at http://clojars.org/repo/
Transferring 2K from clojars
Downloading: cljsbuild/cljsbuild/0.0.13/cljsbuild-0.0.13.jar from repository central at http://repo1.maven.org/maven2
Unable to locate resource in repository
[INFO] Unable to find resource 'cljsbuild:cljsbuild:jar:0.0.13' in repository central (http://repo1.maven.org/maven2)
Downloading: cljsbuild/cljsbuild/0.0.13/cljsbuild-0.0.13.jar from repository clojars at http://clojars.org/repo/
Transferring 4K from clojars
Compiling ClojureScript
Compiling resources/public/js/cljs.js from src-cljs...
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. (js-keys hashobj) sort) is no longer a property access. Maybe you meant (. (js-keys hashobj) -sort) instead?
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. (js-keys hashobj) sort) is no longer a property access. Maybe you meant (. (js-keys hashobj) -sort) instead?
Failed!
←[31mjava.lang.NullPointerException: ←[39m←[31m←[39m
←[34m Compiler.java:869 com.google.javascript.jscomp.Compiler.newTracer←[39m
←[34m Compiler.java:516 com.google.javascript.jscomp.Compiler.compile←[39m
←[34m (Unknown Source) sun.reflect.NativeMethodAccessorImpl.invoke0←[39m
←[34m (Unknown Source) sun.reflect.NativeMethodAccessorImpl.invoke←[39m
←[34m (Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke←[39m
←[34m (Unknown Source) java.lang.reflect.Method.invoke←[39m
←[36m Reflector.java:92 clojure.lang.Reflector.invokeMatchingMethod←[39m
←[36m Reflector.java:30 clojure.lang.Reflector.invokeInstanceMethod←[39m
←[32m closure.clj:649 cljs.closure/optimize←[39m
←[36m RestFn.java:139 clojure.lang.RestFn.applyTo←[39m
←[35m core.clj:602 clojure.core/apply←[39m
←[32m closure.clj:840 cljs.closure/build←[39m
←[32m core.clj:71 cljsbuild.core/compile-cljs←[39m
←[32m core.clj:179 cljsbuild.core/run-compiler←[39m
←[33m NO_SOURCE_FILE:1 user/eval2057[fn]←[39m
←[32m core.clj:154 cljsbuild.core/in-threads[fn]←[39m
←[35m core.clj:1817 clojure.core/binding-conveyor-fn[fn]←[39m
←[36m AFn.java:18 clojure.lang.AFn.call←[39m
←[34m (Unknown Source) java.util.concurrent.FutureTask$Sync.innerRun←[39m
←[34m (Unknown Source) java.util.concurrent.FutureTask.run←[39m
←[34m (Unknown Source) java.util.concurrent.ThreadPoolExecutor.runWorker←[39m
←[34m (Unknown Source) java.util.concurrent.ThreadPoolExecutor$Worker.run←[39m
←[34m (Unknown Source) java.lang.Thread.run←[39m

hope you can understand what this mean...thanks man...

Missing crossover namespaces are silently ignored

When I specify a crossover namespace for inclusion, it should either get copied or an error message should be displayed citing the reason. Currently a missing crossover is silently ignored. (In my case the missing crossover namespace actually resides in the test directory along with other unit test files but for some reason it does not get copied.)

lein cljsbuild auto fails with 0.0.10

I just upgraded to 0.0.10 and suddenly lein cljsbuild auto fails with the following exception:

lein cljsbuild auto
Exception in thread "main" java.lang.IllegalArgumentException: Vector arg to map conj must be a pair (NO_SOURCE_FILE:0)
    at clojure.lang.Compiler.eval(Compiler.java:5440)
    at clojure.lang.Compiler.eval(Compiler.java:5391)
    at clojure.core$eval.invoke(core.clj:2382)
    at clojure.main$eval_opt.invoke(main.clj:235)
    at clojure.main$initialize.invoke(main.clj:254)
    at clojure.main$script_opt.invoke(main.clj:270)
    at clojure.main$main.doInvoke(main.clj:354)
    at clojure.lang.RestFn.invoke(RestFn.java:482)
    at clojure.lang.Var.invoke(Var.java:381)
    at clojure.lang.AFn.applyToHelper(AFn.java:178)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: Vector arg to map conj must be a pair
    at clojure.lang.ATransientMap.conj(ATransientMap.java:37)
    at clojure.lang.ATransientMap.conj(ATransientMap.java:17)
    at clojure.core$conj_BANG_.invoke(core.clj:2559)
    at clojure.lang.ArrayChunk.reduce(ArrayChunk.java:60)
    at clojure.core$r.invoke(core.clj:797)
    at clojure.core$into.invoke(core.clj:2614)
    at leiningen.cljsbuild$merge_dependencies.invoke(cljsbuild.clj:72)
    at leiningen.cljsbuild$run_local_project.invoke(cljsbuild.clj:84)
    at leiningen.cljsbuild$run_compiler.invoke(cljsbuild.clj:93)
    at leiningen.cljsbuild$cljsbuild.invoke(cljsbuild.clj:152)
    at clojure.lang.Var.invoke(Var.java:369)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.core$apply.invoke(core.clj:542)
    at leiningen.core$apply_task.invoke(core.clj:259)
    at leiningen.core$_main.doInvoke(core.clj:325)
    at clojure.lang.RestFn.applyTo(RestFn.java:139)
    at clojure.core$apply.invoke(core.clj:542)
    at leiningen.core$_main.invoke(core.clj:328)
    at user$eval42.invoke(NO_SOURCE_FILE:1)
    at clojure.lang.Compiler.eval(Compiler.java:5424)
    ... 11 more

Make the clojurescript JAR version configurable

This way a user of lein-cljsbuild can specify an explicit clojurescript version. This will not always work, e.g. if the compiler API changes, lein-cljsbuild will obviously have to be updated. However, in simple cases it could be a useful thing to do.

Bizarre jscomp compiler error with a seemingly simple config

Getting the error below when building with lein-cljsbuild, though cljs-watch builds it without problems. I'm too tired to debug further right now, but hopefully you have some thoughts on it.

java.lang.NoSuchMethodError: com.google.common.collect.ImmutableSet.copyOf(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableSet;
DiagnosticGroup.java:48 com.google.javascript.jscomp.DiagnosticGroup.
DiagnosticGroups.java:44 com.google.javascript.jscomp.DiagnosticGroups.registerGroup
DiagnosticGroups.java:81 com.google.javascript.jscomp.DiagnosticGroups.
CompilationLevel.java:121 com.google.javascript.jscomp.CompilationLevel.applySafeCompilationOptions
CompilationLevel.java:59 com.google.javascript.jscomp.CompilationLevel.setOptionsForCompilationLevel
closure.clj:93 cljs.closure/make-options
closure.clj:647 cljs.closure/optimize
RestFn.java:139 clojure.lang.RestFn.applyTo
core.clj:602 clojure.core/apply
closure.clj:840 cljs.closure/build
core.clj:71 cljsbuild.core/compile-cljs
core.clj:179 cljsbuild.core/run-compiler
NO_SOURCE_FILE:1 user/eval2057[fn]
core.clj:154 cljsbuild.core/in-threads[fn]
core.clj:1817 clojure.core/binding-conveyor-fn[fn]
AFn.java:18 clojure.lang.AFn.call
FutureTask.java:303 java.util.concurrent.FutureTask$Sync.innerRun
FutureTask.java:138 java.util.concurrent.FutureTask.run
ThreadPoolExecutor.java:886 java.util.concurrent.ThreadPoolExecutor$Worker.runTask
ThreadPoolExecutor.java:908 java.util.concurrent.ThreadPoolExecutor$Worker.run
Thread.java:680 java.lang.Thread.run

Trying to migrate from 0.0.13 to 0.1.2 - lein failed

I'm probably doing something really studied here, but I get:
"Exception in thread "main" java.lang.IllegalArgumentException: No matching field found: getDirectoryScanner for class org.apache.tools.ant.types.FileSet (NO_SOURCE_FILE:0)"

when running lein clean

project file as follow:
(defproject cljs_first "1.0.0-SNAPSHOT"
:description "ClojureScript first"
:dependencies [[org.clojure/clojure "1.3.0"]
[jayq "0.1.0-SNAPSHOT"]
[crate "0.1.0-SNAPSHOT"]
[compojure "1.0.1"]
[hiccup "0.3.8"]]
:dev-dependencies [[appengine-magic "0.4.7"]]
:plugins [[lein-cljsbuild "0.1.2"]]
:cljsbuild {
:builds [{
; The path to the top-level ClojureScript source directory:
:source-path "src-cljs"
; The standard ClojureScript compiler options:
; (See the ClojureScript compiler documentation for details.)
:compiler {
:output-to "war/js/" ; default: main.js in current directory
:optimizations :whitespace
:pretty-print true}}
]})

Advice will be appreciated
Tzach

NullPointerException running lein cljsbuild once

I receive the following exception when running 'lein cljsbuild once' against lein-cljsbuild 0.0.8. I get this exception when running against my own project, but also when running against the example-projects/simple project.

Exception in thread "main" java.lang.NullPointerException (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:5440)
at clojure.lang.Compiler.eval(Compiler.java:5391)
at clojure.core$eval.invoke(core.clj:2382)
at clojure.main$eval_opt.invoke(main.clj:235)
at clojure.main$initialize.invoke(main.clj:254)
at clojure.main$script_opt.invoke(main.clj:270)
at clojure.main$main.doInvoke(main.clj:354)
at clojure.lang.RestFn.invoke(RestFn.java:482)
at clojure.lang.Var.invoke(Var.java:381)
at clojure.lang.AFn.applyToHelper(AFn.java:178)
at clojure.lang.Var.applyTo(Var.java:482)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at leiningen.compile$prep.invoke(compile.clj:139)
at leiningen.compile$eval_in_project.doInvoke(compile.clj:159)
at clojure.lang.RestFn.invoke(RestFn.java:490)
at leiningen.cljsbuild$run_local_project.invoke(cljsbuild.clj:74)
at leiningen.cljsbuild$run_compiler.invoke(cljsbuild.clj:83)
at leiningen.cljsbuild$cljsbuild.invoke(cljsbuild.clj:136)
at clojure.lang.Var.invoke(Var.java:369)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:482)
at clojure.core$apply.invoke(core.clj:542)
at leiningen.core$apply_task.invoke(core.clj:228)
at leiningen.core$_main.doInvoke(core.clj:294)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:542)
at leiningen.core$_main.invoke(core.clj:297)
at user$eval42.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:5424)
... 11 more

Figure out the best way to add rlwrap/jline support for REPLs

In Leiningen 1.x, the "lein" shell script detects whether rlwrap or jline is available, and uses it if possible. However, it appears that in trampoline commands, the second (trampolined) process does not run with the advantage of rlwrap/jline. This makes the lein-cljsbuild REPL not so fun.

This page offers a good resource on how rlwrap/jline are used for a regular Clojure REPL:

http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Enhancing_Clojure_REPL_with_rlwrap

CLJS Sources should be looked up in CLASSPATH and :source-path

In Maven (therefore in Leiningen too) both JAR and ZIP are valid artifact types. A JAR file can contain .class files, .clj files or other resource files. A ZIP file can contain resource files. Resources may also include .cljs files among other things. CLJS files can be distributed in source form via JAR and ZIP files uploaded to Maven repos.

Hence, it makes sense to pick up CLJS source files from CLASSPATH as well as from the source directory specified by :cljsbuild ==> :builds ==> :source-path. While looking up, the actual name of the file e.g. foo/bar.cljs should be used.

Cannot compile try-catch code blocks

ClojureScript's try-catch is different from Clojure's:
https://github.com/clojure/clojurescript/wiki/Exception-Handling

lein-cljsbuild seems to be using the Clojure compiler to compile CLJS sources and as a consequence it throws exception when compiling .cljs files with valid CLJS try-catch blocks complaining about "Unsupported binding form..". When compiling with a placeholder (shown below) or Exception e instead of e _, it produces JavaScript that throws exception about the runtime (missing variable) in the browser.

(ns foo
  (:require [cljs.reader :as reader]))

(defn bar []
  (try
    (reader/read-string "(+ 78 #\\.// 45)")
    (catch e _
      "Some error occured")))

It is entirely possible that I do not know well about this topic; so please conduct your own experiments to assert the situation.

Compilation fails abruptly

While lein-cljsbuild worked for me earlier, now in a different repository I get the following error for the project.clj snippet below:

:dependencies [[org.clojure/clojure "1.3.0"]]                        
:dev-dependencies [;[org.clojure/clojure "1.3.0"]                             
                   [emezeske/lein-cljsbuild "0.0.2"]]
:cljsbuild {                                                                  
    :source-path "src-cljs"                                                     
    ; Each entry in the :crossovers vector describes a Clojure namespace        
    ; that is meant to be used with the ClojureScript code as well.             
    ; The files that make up this namespace will be automatically copied        
    ; into the ClojureScript source path whenever they are modified.            
    :compiler {                                                                 
      :output-file "war/javascripts/main.js"                                    
      :optimizations :whitespace                                                
      :pretty-print true}}
Compiler started.
Exception in thread "main" java.lang.NullPointerException
Compiling main.js from src-cljs...  at java.io.File.<init>(File.java:360)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at clojure.lang.Reflector.invokeConstructor(Reflector.java:183)
    at fs$as_file.invoke(fs.clj:19)
    at fs$mkdirs.invoke(fs.clj:121)
    at cljsbuild.core$compile_cljs.invoke(core.clj:32)
    at cljsbuild.core$run_compiler.invoke(core.clj:121)
    at user$eval1925.invoke(NO_SOURCE_FILE:1)
    at clojure.lang.Compiler.eval(Compiler.java:6465)
    at clojure.lang.Compiler.eval(Compiler.java:6455)
    at clojure.lang.Compiler.eval(Compiler.java:6431)
    at clojure.core$eval.invoke(core.clj:2795)
    at clojure.main$eval_opt.invoke(main.clj:296)
    at clojure.main$initialize.invoke(main.clj:315)
    at clojure.main$null_opt.invoke(main.clj:348)
    at clojure.main$main.doInvoke(main.clj:426)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:405)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.main.main(main.java:37)

Some ClojureScript compile errors drop auto mode

When running lein cljsbuild auto, if your ClojureScript code has syntax errors, the compiler throws an exception and the auto build exits so you have to restart it.

The exception could be caught here:

at cljsbuild.core$compile_cljs.invoke(core.clj:37)

An example error that causes this:

Exception in thread "main" java.lang.RuntimeException: java.lang.AssertionError: Assert failed: set! target must be a field or a symbol naming a var

No :dependencies in project.clj causes NullPointerException

It should be perfectly OK for a "library" project to include the Clojure JAR in :dev-dependencies instead of :dependencies – however, lein-cljsbuild causes NullPointerException when the :dependencies is not specified even though :dev-dependencies contains the Clojure JAR.

Macro file crossovers from jars probably are broken

The code that checks for file updates attempts to determine the mtime for the macro files without checkout to see if their URL protocol is "file". It should not try to check mtimes for URLs with protocol "jar".

hook for "run" task?

Kudos on this plugin. It's has made my struggles with ClojureScript much easier.

Is it possible to add a hook to the "run" task? I often do the following:

lein trampoline run :main

or

lein run :main

These don't necessarily compile the app, so cljsbuild isn't invoked. Yes, I use emacs/swank, or use the auto feature of cljsbuild, and even build uberjars, but I also do the above when I just want to start up an app, then work on something else. Doing one of the above commands even calls "deps" behind the scenes, which is so nice.

Anyway, hope this seems a reasonable (and super simple) addition.

Regards,
Keith

NullPointerException when detecting leiningen.core.eval/*prepping?* in Lein2

It works fine for Lein 1.7, but when I run lein2 clean with :hooks [leiningen.cljsbuild] in project.clj, I get the following NullPointerException:

Exception in thread "main" java.lang.NullPointerException
    at clojure.core$deref.invoke(core.clj:2078)
    at leiningen.cljsbuild.subproject$prepping_QMARK_.invoke(subproject.clj:59)
    at leiningen.cljsbuild$clean_hook.doInvoke(cljsbuild.clj:204)
    at clojure.lang.RestFn.invoke(RestFn.java:423)
    at clojure.lang.Var.invoke(Var.java:405)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.core$apply.invoke(core.clj:602)
    at robert.hooke$compose_hooks$fn__613.doInvoke(hooke.clj:33)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:600)
    at robert.hooke$run_hooks.invoke(hooke.clj:39)
    at robert.hooke$prepare_for_hooks$fn__618$fn__619.doInvoke(hooke.clj:47)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:401)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.core$apply.invoke(core.clj:602)
    at leiningen.core.main$resolve_task$fn__648.doInvoke(main.clj:54)
    at clojure.lang.RestFn.invoke(RestFn.java:410)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:602)
    at leiningen.core.main$apply_task.invoke(main.clj:75)
    at leiningen.core.main$_main.doInvoke(main.clj:124)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:401)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.core$apply.invoke(core.clj:600)
    at clojure.main$main_opt.invoke(main.clj:323)
    at clojure.main$main.doInvoke(main.clj:426)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at clojure.lang.Var.invoke(Var.java:409)
    at clojure.lang.AFn.applyToHelper(AFn.java:167)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.main.main(main.java:37)

cljs -> crossover -> cljs dependency issue

Here's a small project exemplifying the issue.

lein cljsbuild once leads to:

ERROR: JSC_LATE_PROVIDE_ERROR. required "lateprovide.a.file3" namespace not provided yet at .../.lein-cljsbuild-compiler-0/lateprovide/b/file2.js line 3 : 12

But here's something strange, compiling again fixes the error! This is reproducible every time. I'm not sure what this could be, maybe some late classpath problem...

As a quick fix, would it be possible to additionally copy the cljs source-path into the crossovers directory, so that the cljs compiler would just have to compile a single directory (i.e. not depend on multiple classpath entries)?

Edit: I spoke too soon, "fixes the error" was exaggerated - the produced js file is empty.

Use checksums to notice modifications in files in JARs

One problem that I have personally experienced, and have heard others complaining about, is the project not being rebuilt when an upstream JAR that contains CLJS code is updated. This is due to timestamps being used for noticing modifications, but JAR-ed files don't contain timestamps. So, lein-cljsbuild should keep track of checksums for those files, and use that to notice modifications.

Support for passing "--define" option to compiler.jar

for example by specifying in project.clj
:compiler {
:define "goog.userAgent.ASSUME_MOBILE_WEBKIT"
:define "goog.userAgent.product.ASSUME_ANDROID"
}

Resources:
goog.userAgent global props: http://closure-library.googlecode.com/svn/docs/closure_goog_useragent_useragent.js.html
goog.userAgent.product global props: http://closure-library.googlecode.com/svn/docs/closure_goog_useragent_product.js.html
"java -jar compiler.jar --help" for all available options
Google Closure Definitive Guide at Google Books: http://books.google.pl/books?id=p7uyWPcVGZsC

clojurescript/src/clj/cljs/closure.clj: functions "make-options" and "set-options"

(defn set-options
"TODO: Add any other options that we would like to support."
[opts ^CompilerOptions compiler-options](when %28contains? opts :pretty-print%29
%28set! %28.prettyPrint compiler-options%29 %28:pretty-print opts%29%29)
(when (contains? opts :print-input-delimiter)
(set! (.printInputDelimiter compiler-options)
(:print-input-delimiter opts))))

(defn make-options
"Create a CompilerOptions object and set options from opts map."
[opts](let [level %28case %28:optimizations opts%29
:advanced CompilationLevel/ADVANCED_OPTIMIZATIONS
:whitespace CompilationLevel/WHITESPACE_ONLY
:simple CompilationLevel/SIMPLE_OPTIMIZATIONS%29
compiler-options %28doto %28CompilerOptions.%29
%28.setCodingConvention %28ClosureCodingConvention.%29%29%29]
%28do %28.setOptionsForCompilationLevel level compiler-options%29
%28set-options opts compiler-options%29
compiler-options%29))

Handling Clojure/ClojureScript protocol differences and other platform discrepencies

How should we handle language runtime and platform between Clojure and ClojureScript?

One option for handling platform differences is to duplicate namespaces across clj and cljs.
In maths.cljs:

(ns maths) 
(def sqrt (.-sqrt js/Math))

and in maths.clj

(ns maths) ;;maths.clj
(defn sqrt [x] (Math/sqrt x))

Then use Clojure as usual and in ClojureScript just let the cljs version of the namespace get picked up (don't list maths in the crossovers).

That feels like a lot of unnecessary juggling for a LISP though; perhaps we should take advantage of metadata to mark platform-specific functions and provide alternatives all in the same file?

I've also run into problems with differences in the language runtimes.
For instance, in Clojure:

(reify
  clojure.lang.ILookup (valAt [k v] ...))

but in ClojureScript:

(reify
  ILookup (-lookup [k v] ...))

Is there anything we can do to crossover Clojure code like this automatically within lein-cljsbuild?
It's probably easier to make the changes in ClojureScript itself, but maybe there is a reason ClojureScript's protocols have slightly different names than Clojure's (pinging @how should we handle language runtime and platform between Clojure and ClojureScript?

One option for handling platform differences is to duplicate namespaces across clj and cljs.
In maths.cljs:

(ns maths) 
(def sqrt (.-sqrt js/Math))

and in maths.clj

(ns maths) ;;maths.clj
(defn sqrt [x] (Math/sqrt x))

Then use Clojure as usual and in ClojureScript just let the cljs version of the namespace get picked up (don't list maths in the crossovers).

That feels like a lot of unnecessary juggling for a LISP though; perhaps we should take advantage of metadata to mark platform-specific functions and provide alternatives all in the same file?

I've also run into problems with differences in the language runtimes.
For instance, in Clojure:

(reify
  clojure.lang.ILookup (valAt [k v] ...))

but in ClojureScript:

(reify
  ILookup (-lookup [k v] ...))

Is there anything we can do to crossover Clojure code like this automatically within lein-cljsbuild?
It's probably easier to make the changes in ClojureScript itself, but maybe there is a reason ClojureScript's protocols have slightly different names than Clojure's (pinging @swannodette).

NullPointerException !

Hmm, I wonder how come?

(defproject test "0.1.1"
:resources-path "war"
:dependencies [[org.clojure/clojure "1.3.0"]
[org.clojure/clojurescript "0.0-993"]]
:plugins [[lein-cljsbuild "0.1.2"]]
:hooks [leiningen.cljsbuild]
:cljsbuild {:builds [{:source-path "src/novapilot"
;; The standard ClojureScript compiler options:
;; (See the ClojureScript compiler documentation for details.)
:compiler {:output-to "war/novapilot/main.js" ; default: main.js in current directory
:optimizations :whitespace
:foreign-libs [{:file "war/js/cocos.js"
:provides ["cocos"]}
{:file "war/js/jah.js"
:provides "jah"}]
:pretty-print true}
:jar true} ... etc ...

Then, "leon cljsbuild once" (or auto)

Compiling war/test/main.js from src/test...
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. (js-keys hashobj) sort) is no longer a property access. Maybe you meant (. (js-keys hashobj) -sort) instead?
Failed!
java.lang.NullPointerException:
Compiler.java:869 com.google.javascript.jscomp.Compiler.newTracer
Compiler.java:516 com.google.javascript.jscomp.Compiler.compile
(Unknown Source) sun.reflect.NativeMethodAccessorImpl.invoke0
NativeMethodAccessorImpl.java:39 sun.reflect.NativeMethodAccessorImpl.invoke
DelegatingMethodAccessorImpl.java:25 sun.reflect.DelegatingMethodAccessorImpl.invoke
Method.java:597 java.lang.reflect.Method.invoke
Reflector.java:92 clojure.lang.Reflector.invokeMatchingMethod
Reflector.java:30 clojure.lang.Reflector.invokeInstanceMethod
closure.clj:661 cljs.closure/optimize
RestFn.java:139 clojure.lang.RestFn.applyTo
core.clj:602 clojure.core/apply
closure.clj:869 cljs.closure/build
compiler.clj:36 cljsbuild.compiler/compile-cljs
compiler.clj:53 cljsbuild.compiler/run-compiler
NO_SOURCE_FILE:1 user/eval2122[fn]
util.clj:31 cljsbuild.util/in-threads[fn]
core.clj:1817 clojure.core/binding-conveyor-fn[fn]
AFn.java:18 clojure.lang.AFn.call
FutureTask.java:303 java.util.concurrent.FutureTask$Sync.innerRun
FutureTask.java:138 java.util.concurrent.FutureTask.run
ThreadPoolExecutor.java:886 java.util.concurrent.ThreadPoolExecutor$Worker.runTask
ThreadPoolExecutor.java:908 java.util.concurrent.ThreadPoolExecutor$Worker.run
Thread.java:680 java.lang.Thread.run

AOT errors when using as a global plugin?

seancornfield in IRC reported problems with this when using lein-cljsbuild as a global plugin, rather than as a :dev-dependencies entry. I should spend some time experimenting with this -- I probably haven't tested things enough as a global plugin.

My guess is that it's related to the fact that emezeske/clojurescript doesn't work properly when AOT compiled, due to a bug in the Clojure compiler that loses :macro metadata when compiling to Java class files. I'll have to experiment with this to be sure.

Wrong number of args exception

whenever I run any cljsbuild task I get an error like this

Compiling ClojureScript.
Exception in thread "main" java.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$assert (core.clj:213)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5376)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyze(Compiler.java:5151)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:4670)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:4941)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5369)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5357)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyze(Compiler.java:5151)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:4670)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:4328)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3173)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5367)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.access$100(Compiler.java:35)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:4921)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5369)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5357)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyze(Compiler.java:5151)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:4670)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:4328)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3173)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5367)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5357)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyze(Compiler.java:5151)
    at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:798)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5369)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5357)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.access$100(Compiler.java:35)
    at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:438)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5369)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyze(Compiler.java:5151)
    at clojure.lang.Compiler.eval(Compiler.java:5428)
    at clojure.lang.Compiler.eval(Compiler.java:5414)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.RT.loadResourceScript(RT.java:340)
    at clojure.lang.RT.loadResourceScript(RT.java:331)
    at clojure.lang.RT.load(RT.java:409)
    at clojure.lang.RT.load(RT.java:381)
    at clojure.core$load$fn__4519.invoke(core.clj:4915)
    at clojure.core$load.doInvoke(core.clj:4914)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:4729)
    at clojure.core$load_lib.doInvoke(core.clj:4766)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:542)
    at clojure.core$load_libs.doInvoke(core.clj:4800)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:542)
    at clojure.core$require.doInvoke(core.clj:4881)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at cljs.compiler$eval115.invoke(compiler.clj:18)
    at clojure.lang.Compiler.eval(Compiler.java:5424)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.RT.loadResourceScript(RT.java:340)
    at clojure.lang.RT.loadResourceScript(RT.java:331)
    at clojure.lang.RT.load(RT.java:409)
    at clojure.lang.RT.load(RT.java:381)
    at clojure.core$load$fn__4519.invoke(core.clj:4915)
    at clojure.core$load.doInvoke(core.clj:4914)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:4729)
    at clojure.core$load_lib.doInvoke(core.clj:4766)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:542)
    at clojure.core$load_libs.doInvoke(core.clj:4800)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:542)
    at clojure.core$require.doInvoke(core.clj:4881)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at cljs.closure$eval103$loading__4414__auto____104.invoke(closure.clj:9)
    at cljs.closure$eval103.invoke(closure.clj:9)
    at clojure.lang.Compiler.eval(Compiler.java:5424)
    at clojure.lang.Compiler.eval(Compiler.java:5415)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.RT.loadResourceScript(RT.java:340)
    at clojure.lang.RT.loadResourceScript(RT.java:331)
    at clojure.lang.RT.load(RT.java:409)
    at clojure.lang.RT.load(RT.java:381)
    at clojure.core$load$fn__4519.invoke(core.clj:4915)
    at clojure.core$load.doInvoke(core.clj:4914)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:4729)
    at clojure.core$load_lib.doInvoke(core.clj:4766)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:542)
    at clojure.core$load_libs.doInvoke(core.clj:4800)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:544)
    at clojure.core$use.doInvoke(core.clj:4892)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at cljsbuild.compiler$eval5$loading__4414__auto____6.invoke(compiler.clj:1)
    at cljsbuild.compiler$eval5.invoke(compiler.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:5424)
    at clojure.lang.Compiler.eval(Compiler.java:5415)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.RT.loadResourceScript(RT.java:340)
    at clojure.lang.RT.loadResourceScript(RT.java:331)
    at clojure.lang.RT.load(RT.java:409)
    at clojure.lang.RT.load(RT.java:381)
    at clojure.core$load$fn__4519.invoke(core.clj:4915)
    at clojure.core$load.doInvoke(core.clj:4914)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:4729)
    at clojure.core$load_lib.doInvoke(core.clj:4766)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:542)
    at clojure.core$load_libs.doInvoke(core.clj:4800)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:542)
    at clojure.core$require.doInvoke(core.clj:4881)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at user$eval1.invoke(NO_SOURCE_FILE:1)
    at clojure.lang.Compiler.eval(Compiler.java:5424)
    at clojure.lang.Compiler.eval(Compiler.java:5414)
    at clojure.lang.Compiler.eval(Compiler.java:5391)
    at clojure.core$eval.invoke(core.clj:2382)
    at clojure.main$eval_opt.invoke(main.clj:235)
    at clojure.main$initialize.invoke(main.clj:254)
    at clojure.main$null_opt.invoke(main.clj:279)
    at clojure.main$main.doInvoke(main.clj:354)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:369)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$assert
    at clojure.lang.AFn.throwArity(AFn.java:437)
    at clojure.lang.AFn.invoke(AFn.java:51)
    at clojure.lang.Var.invoke(Var.java:377)
    at clojure.lang.AFn.applyToHelper(AFn.java:172)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.lang.Compiler.macroexpand1(Compiler.java:5286)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5355)
    ... 133 more

REPL fails to start

Running the advanced example:

lein trampoline cljsbuild repl-launch firefox http://localhost:3000/repl-demo

results in this:

Running ClojureScript REPL and launching command: (firefox :stdout .repl-firefox-out :stderr .repl-firefox-err http://localhost:3000/repl-demo)
Background command output will be shown after the REPL is exited via :cljs/quit .
"Type: " :cljs/quit " to quit"
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. this toString) is no longer a property access. Maybe you meant (. this -toString) instead?
WARNING: The form (. (js-keys hashobj) sort) is no longer a property access. Maybe you meant (. (js-keys hashobj) -sort) instead?
Error in background process: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: http://localhost:3000/repl-demo>

I am running:

Leiningen 1.7.0 on Java 1.6.0_26 Java HotSpot(TM) 64-Bit Server VM on Ubuntu 11.10.

Let :crossover accept namespaces too

I don't like the idea of putting all my crossover-files into separate directories. A nicer solution would let me specify namespaces like the following:

:crossovers [my.namespace.foo my.namespace.bar]

Error while building multiple configurations in parallel

I have two build configurations in a project, with some overlapping CLJS and crossover files. Leiningen hook is defined as :hooks [leiningen.cljsbuild]. When running lein clean && lein cljsbuild once on different occasions I noticed following kinds of errors.

_Case 1_

Sometimes I get this exception trace:

Exception in thread "main" java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at clojure.lang.Util.runtimeException(Util.java:165)
    at clojure.lang.LazySeq.sval(LazySeq.java:51)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:466)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core$dorun.invoke(core.clj:2723)
    at clojure.core$doall.invoke(core.clj:2739)
    at cljsbuild.core$in_threads.invoke(core.clj:154)
    at user$eval2057.invoke(NO_SOURCE_FILE:1)
    at clojure.lang.Compiler.eval(Compiler.java:6465)
    at clojure.lang.Compiler.eval(Compiler.java:6455)
    at clojure.lang.Compiler.eval(Compiler.java:6431)
    at clojure.core$eval.invoke(core.clj:2795)
    at clojure.main$eval_opt.invoke(main.clj:296)
    at clojure.main$initialize.invoke(main.clj:315)
    at clojure.main$null_opt.invoke(main.clj:348)
    at clojure.main$main.doInvoke(main.clj:426)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:405)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.main.main(main.java:37)
Caused by: java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
    at java.util.concurrent.FutureTask.get(FutureTask.java:83)
    at clojure.core$future_call$reify__5684.deref(core.clj:6054)
    at clojure.core$deref.invoke(core.clj:2078)
    at clojure.core$map$fn__3811.invoke(core.clj:2432)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    ... 20 more
Caused by: java.lang.NullPointerException
    at java.util.regex.Matcher.getTextLength(Matcher.java:1140)
    at java.util.regex.Matcher.reset(Matcher.java:291)
    at java.util.regex.Matcher.<init>(Matcher.java:211)
    at java.util.regex.Pattern.matcher(Pattern.java:888)
    at clj_stacktrace.utils$re_gsub.invoke(utils.clj:6)
    at clj_stacktrace.core$clojure_ns.invoke(core.clj:14)
    at clj_stacktrace.core$parse_trace_elem.invoke(core.clj:68)
    at clojure.core$map$fn__3811.invoke(core.clj:2432)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:466)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core$map$fn__3811.invoke(core.clj:2424)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:466)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core$map$fn__3811.invoke(core.clj:2424)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.Cons.next(Cons.java:39)
    at clojure.lang.RT.length(RT.java:1599)
    at clojure.lang.RT.seqToArray(RT.java:1555)
    at clojure.lang.LazySeq.toArray(LazySeq.java:133)
    at clojure.lang.RT.toArray(RT.java:1533)
    at clojure.core$to_array.invoke(core.clj:325)
    at clojure.core$sort.invoke(core.clj:2697)
    at clojure.core$sort.invoke(core.clj:2694)
    at clj_stacktrace.repl$find_source_width.invoke(repl.clj:98)
    at clj_stacktrace.repl$pst_on.invoke(repl.clj:107)
    at clj_stacktrace.repl$pst_PLUS_.doInvoke(repl.clj:129)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at cljsbuild.core$compile_cljs.invoke(core.clj:75)
    at cljsbuild.core$run_compiler.invoke(core.clj:179)
    at user$eval2057$fn__2058.invoke(NO_SOURCE_FILE:1)
    at cljsbuild.core$in_threads$fn__2003$fn__2004.invoke(core.clj:154)
    at clojure.core$binding_conveyor_fn$fn__3713.invoke(core.clj:1817)
    at clojure.lang.AFn.call(AFn.java:18)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)

_Case 2_

Some other times only the first file is generated and I notice the following error message:

Feb 19, 2012 7:07:30 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/error.js

ERROR: JSC_DUPLICATE_INPUT. Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/error.js at (unknown source) line (unknown line) : (unknown column)
Feb 19, 2012 7:07:30 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 1 error(s), 0 warning(s)
target/test.js compiled in 1.900348 seconds.
target/basil.js compiled in 3.588077 seconds.

_Case 3_

At other times only the first file is generated and I notice the following error message:

Feb 19, 2012 7:09:08 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/error.js

ERROR: JSC_DUPLICATE_INPUT. Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/error.js at (unknown source) line (unknown line) : (unknown column)
Feb 19, 2012 7:09:08 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/group.js

Feb 19, 2012 7:09:08 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/render.js

Feb 19, 2012 7:09:08 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/slot.js

Feb 19, 2012 7:09:08 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 4 error(s), 0 warning(s)
ERROR: JSC_DUPLICATE_INPUT. Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/group.js at (unknown source) line (unknown line) : (unknown column)
ERROR: JSC_DUPLICATE_INPUT. Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/render.js at (unknown source) line (unknown line) : (unknown column)
ERROR: JSC_DUPLICATE_INPUT. Duplicate input: /Users/shantanu/projects/workspace/basil/.clojurescript-output/basil/slot.js at (unknown source) line (unknown line) : (unknown column)
target/test.js compiled in 1.721299 seconds.
target/basil.js compiled in 2.680332 seconds.

Macros do not appear to work when crossover namespace is granular

Disclaimer: This may or may not be an error at all; perhaps just lack of understanding on my part.

In a project I have just a single level namespace, such as basil.core, basil.group, basil.render etc. This is a library and I do not have the liberty to introduce namespaces such as basil.crossover.foobar etc. The existing 'advanced' example in lein-cljsbuild shows the usage of macros with an umbrella namespace example.crossover; when I use macros similarly in my project they do not seem to work.

The error message I get (in PhantomJS and Firebug) is:
goog.require could not find: basil.test.test_macros

basil.test.test-macros is a namespace containing CLJS unit-test related macros in a file called test-cljs/basil/test/test_macros.clj. This file on its first line has ;*CLJSBUILD-MACRO-FILE*; to demarcate it as a file containing macros. To have this file picked up as a regular Clojure file I have specified :extra-classpath-dirs ["test-cljs"] in project.clj file.

goog-jar version?

I'm having trouble requiring goog.dom.query within a project using cljsbuild.
My understanding is that this is caused from a broken goog-jar:

https://groups.google.com/forum/#!topic/clj-noir/x5x9vcI-T4E

something which @ibdknox resolved by cutting his own goog-jar.
Is there any way to use that?

cygwin home location errors

This could be in dependencies, but like several other things, like Leiningen itself, Cygwin seems to have some special considerations. I already use a dummy project and its project.clj to list a plugin as a dependency so that the JAR files are downloaded correctly through maven and a proxy, and then run the typical plugin install commands which then place everything correctly for lein.

However on top of that, some aspects of installing cljsbuild meant that I had to set my $HOME to the DOS equivalent:

export HOME="c:\cygwin\home\USERNAME"

and then plugin installation completed successfully. What happens, the home is normally just "/home/USERNAME" but something detects itself as being on windows (maybe some aspect of the JVM?) and then it can't resolve c:/home/USERNAME and gives up.

Thank you so so much for writing this great build tool, and please know your efforts are appreciated!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.