ANN: ClojureScript 0.0-2719, JavaScript Dependencies (original) (raw)

David Nolen

unread,

Jan 24, 2015, 10:10:12 AM1/24/15

to clojure, clojur...@googlegroups.com

ClojureScript, the Clojure compiler that emits JavaScript source code.

New release version: 0.0-2719

Leiningen dependency information:

[org.clojure/clojurescript "0.0-2719"]

ClojureScript is not an island, like Clojure on the JVM, ClojureScript

embraces the many benefits provided by the host. However this goal

has been hampered by another goal - the compilation stragey. Google

Closure Compiler offers superior optimization and minification for

ClojureScript while simultaneously making it considerably more

difficult to integrate non-Closure compatible libraries. Using popular

libraries like jQuery, React or D3 is an error prone process: "which

extern did I forget?", "which script tag did I miss for development?",

"are these script tags in dependency order?".

No more. 0.0-2719 delivers full support for non-Closure compatible

libraries through some less known features that have been lurking

around for almost three years - `deps.cljs` and the :foreign-libs

compiler option.

`deps.cljs` is a simple EDN file provided at the root of a JAR that

describes additional build information for the ClojureScript

compiler. For example here is the `deps.cljs` for the React JAR I

maintain:

{

:foreign-libs [{:file "react/react.js"

:file-min "react/react.min.js"

:provides ["com.facebook.React"]}

{:file "react/react_with_addons.js"

:file-min "react/react_with_addons.min.js"

:provides ["com.facebook.ReactWithAddons"]}]

:externs ["react/externs/react.js"]

}

This file provides all the information ClojureScript needs to

correctly manage the foreign dependency for you under all compilation

modes and REPLs.

In a REPL:

cljs.user> (require 'com.facebook.React)

cljs.user> (. js/React

(renderToString

(. js/React (DOM.div nil "Hello!"))))

In your project:

(ns foo.bar

(:require com.facebook.React))

(enable-console-print!)

(println

(. js/React

(renderToString

(. js/React (DOM.div nil "Hello!")))))

The above works under all compilation modes. There is no need to

include React as a script tag under development, there is no need to put

script tags in dependency order, there is no need to add React to

:preamble under :advanced, and there is no need to explicitly provide

:externs.

All that is required is that JavaScript libraries be packaged in JARs

with a `deps.cljs`.

Some of you might reasonably ask why not a tool like Bower for this

instead? Bower requires an additional dependency on Node.js. While

ClojureScript embraces Node.js as a useful target it is not a

requirement to be productive. Bower manages dependencies, but in the

Clojure world we have already embraced Maven for this task and have

done the same for ClojureScript. Finally Bower does not address the

problem of loading libraries at runtime. This is challenging to do -

some JavaScript libraries adopt CommonJS, some AMD, and the most

popular ones make no assumptions at all allowing users to simply use

script tags as they have done for nearly two decades. The above

solution addresses the issue for all ClojureScript users by

eliminating paralysis of choice. Finally none of the above

precludes Bower usage in any way whatsoever.

This new feature addresses a long outstanding pain point with

ClojureScript development. All that is required is that we take the

time to properly package up the most popular JavaScript libraries that

fill gaps not currently served by exising ClojureScript and Google

Closure Library functionality.

Please kick the tires and feedback is most welcome. This feature

touched many bits of code so there are likely to be wrinkles and we want

to get these ironed out as quickly as possible.

## 0.0-2719

### Changes

* Full support for foreign dependencies

* CLJS-985: make ex-info not lose stack information

* CLJS-984: Update Node.js REPL support to use public API

* CLJS-963: do not bother computing goog/dep.js under :none

### Fixes

* CLJS-982: Var derefing should respect Clojure semantics

* CLJS-980: ClojureScript REPL stacktraces overrun prompt in many cases

* CLJS-979: ClojureScript REPL needs error handling for the special functions

* CLJS-971: :reload should work for require-macros special fn

* CLJS-980: ClojureScript REPL stacktraces overrun prompt in many cases

* CLJS-979: ClojureScript REPL needs error handling for the special functions

* CLJS-971: :reload should work for require-macros special fn

* CLJS-936: Multi arity bitwise operators

* CLJS-962: fix inconsistent hashing of empty collections

Bruce Hauman

unread,

Jan 24, 2015, 10:38:43 AM1/24/15

to clo...@googlegroups.com, clojur...@googlegroups.com

Great stuff! This will smooth things out quite a bit.

I spent far too much time just yesterday trying to get an advanced build working right.

Thanks!

Martin Klepsch

unread,

Jan 24, 2015, 10:43:35 AM1/24/15

to clo...@googlegroups.com, clojur...@googlegroups.com

David, thanks for making those improvements to Clojurescript, they'll

make things a lot easier in the future.

In the realm of Boot we started working on CLJSJS as an effort to

package up and ship popular Javascript libraries for use in Clojurescript [1].

While these packages have only been compatible with a Boot-based

Clojurescript build chain we fully intend to make them work with this

new approach to handle external Javascript libraries.

That said a bunch of libraries are already in place, we tracked down

extern files etc, so the changes to make them compatible should be

rather small. Contributions are very welcome. I hope to get one of the

libs compatible tomorrow so the migration path for the others is

clear.

A general question/concern I'd like to voice in that context is that

this change makes it hard to split JS preamble from our compiled

Clojurescript. Given that the Clojurescript code might change on a

daily basis and the preamble mostly stays the same this forces users

to re-download our (unchanged) JS dependencies over and over again,

while caching them would have provided us with much better performance.

David Nolen

unread,

Jan 24, 2015, 10:54:03 AM1/24/15

to clojur...@googlegroups.com, clojure

David Nolen

unread,

Jan 24, 2015, 11:09:08 AM1/24/15

to clojure, clojur...@googlegroups.com

Daniel Kersten

unread,

Jan 24, 2015, 11:31:47 AM1/24/15

to clojur...@googlegroups.com, clojure

Thanks David for your continued hard work - another fantastic release. This looks really good and solves real problems.

Moritz Ulrich

unread,

Jan 24, 2015, 11:43:17 AM1/24/15

to David Nolen, clojure, clojur...@googlegroups.com

As I already said on IRC: This is just *great*. I tried it in both
applications I'm working on right now and both saw a (meaningful)
reduction in size.

Thanks again for this great release!

David Nolen

unread,

Jan 24, 2015, 12:04:32 PM1/24/15

to clojure, clojur...@googlegroups.com

David Nolen

unread,

Jan 24, 2015, 3:58:02 PM1/24/15

to clojure, clojur...@googlegroups.com

I just cut 0.0-2723. The significant change is an often requested feature - that script inclusion for :none be the same as other build settings. This is finally supported if you provide a :main entry specifying a namespace.

{:main hello-world.core

:output-to "hello_world.js"

:output-dir "out"

:optimizations :none

:source-map true}

Then your markup just needs:

Same as :advanced.

David

David Nolen

unread,

Jan 24, 2015, 4:22:16 PM1/24/15

to clojure, clojur...@googlegroups.com

And just cut 0.0-2725 to address a Node.js target support regression.

David

David Nolen

unread,

Jan 24, 2015, 8:42:46 PM1/24/15

to clojure, clojur...@googlegroups.com

Just cut 0.0-2727 to fix an issue around the new :main support. ClojureScript now supports an :asset-path option to control how the :main script imports other scripts in order to respect whatever asset configuration you may have set up for your web server.

David

David Nolen

unread,

Jan 25, 2015, 2:42:43 PM1/25/15

to clojure, clojur...@googlegroups.com

I strongly recommend the Clojure(Script) community join forces when packaging libraries to avoid duplicated effort and dependency conflicts.

David

David Nolen

unread,

Jan 25, 2015, 5:49:00 PM1/25/15

to clojure, clojur...@googlegroups.com

Ivan L

unread,

Jan 25, 2015, 7:28:01 PM1/25/15

to clo...@googlegroups.com, clojur...@googlegroups.com

To this end I would hope everyone takes a look at using webjars.org as their source for frontend libraries. imo, it's a way forward to dep mgmt outside of bower/npm/node etc.

David Nolen

unread,

Jan 25, 2015, 8:11:22 PM1/25/15

to clojur...@googlegroups.com, clojure

Webjars doesn't package JS libs in a useful way for ClojureScript.

--

Note that posts from new members are moderated - please be patient with your first post.

---
You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.

Laurent PETIT

unread,

Jan 26, 2015, 3:08:43 AM1/26/15

to clojur...@googlegroups.com, clojure

David Nolen

unread,

Jan 26, 2015, 8:15:01 AM1/26/15

to clojur...@googlegroups.com, clojure