[ANN] CLJSJS

577 views
Skip to first unread message

Martin Klepsch

unread,
Jan 5, 2015, 12:19:56 PM1/5/15
to clojur...@googlegroups.com
CLJSJS [1] is an effort to package Javascript libraries + their respective
extern files and provide tooling to integrate them into your project.

Traditionally interoperability features are a big deal for Clojure.
In Clojurescript however things are not as straightforward. There are
no mechanisms to depend on Javascript libraries that work smooth
accross all optimization modes. CLJSJS aims to change that.

Popular libraries like React, Hammer.js, jQuery and more have already
been packaged for you and can be depended on via Clojars:

[cljsjs/react "0.12.2-2"] etc.

If you're using the Boot build tool relying on one of those libraries
is straightforward[2] and even transitive CLJSJS dependencies will "just work".
With Leiningen things are more manual, contributions to make
this easier are very welcome.

You can read more about CLJSJS on the project homepage.

I'm very excited to hear what you think!

[1] http://cljsjs.github.io
[2] https://github.com/cljsjs/packages#using-a-package

gvim

unread,
Jan 5, 2015, 2:25:09 PM1/5/15
to clojur...@googlegroups.com
Fantastic! Just what I was looking for.

gvim
Message has been deleted

Dave Dixon

unread,
Jan 5, 2015, 9:05:31 PM1/5/15
to clojur...@googlegroups.com
I'll second the "fantastic". Solved a couple of major headaches we had packaging internal JS libs with ClojureScript.

Thomas Heller

unread,
Jan 6, 2015, 5:49:11 AM1/6/15
to clojur...@googlegroups.com
FWIW there is absolutely no need to ship a production/development version of the code. The Closure Compiler is perfectly capable of minifying any JS source (NOT advanced optimize, just minify).

Therefore the full JS + externs would be enough.

As a build tool author I don't quite agree with using a naming convention to detect the files (eg. *.inc.js, ...). You could never package more than one file this way since there would be no way to tell the compiler: file Y needs to be added before file B.

There are some efforts in the Closure Compiler to support AMD, CommonJS, ES6 modules. I haven't looked closely but we might even be able to :advanced compile any JS code in the future. Don't know if that works yet though (or if that even is the goal).

Regards,
/thomas

PS: we also need to rethink some of this stuff for HTTP/2 ... but thats a topic for another day. I believe the goog.module efforts are motivated by that.

Martin Klepsch

unread,
Jan 6, 2015, 6:01:27 AM1/6/15
to clojur...@googlegroups.com
> FWIW there is absolutely no need to ship a production/development version of the code. The Closure Compiler is perfectly capable of minifying any JS source (NOT advanced optimize, just minify). 

That's right but for some projects the assumption that .min.js means "minified" is just not true. E.g. React ships with different logging levels enabled based on wether you're including the development or production build. I'm sure there are more projects that include extra debugging stuff that's stripped while packaging.

> As a build tool author I don't quite agree with using a naming convention to detect the files (eg. *.inc.js, ...). You could never package more than one file this way since there would be no way to tell the compiler: file Y needs to be added before file B.


Very fair point. We haven't actually come across that situation as most libs are distributed as single files but I agree that this might cause 
problems with libraries that are distributed with multiple files (Thinking of Bootstrap - although that's a whole other beast).
 
--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/qhFNVEeNCbc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Thomas Heller

unread,
Jan 6, 2015, 6:20:04 AM1/6/15
to clojur...@googlegroups.com

>
> That's right but for some projects the assumption that .min.js means "minified" is just not true. E.g. React ships with different logging levels enabled based on wether you're including the development or production build. I'm sure there are more projects that include extra debugging stuff that's stripped while packaging.
>

You are right, I guess I'm too spoiled by CLJS/Closure that I don't have to worry about things like that. ;)


> > As a build tool author I don't quite agree with using a naming convention to detect the files (eg. *.inc.js, ...). You could never package more than one file this way since there would be no way to tell the compiler: file Y needs to be added before file B.
>
>
> Very fair point. We haven't actually come across that situation as most libs are distributed as single files but I agree that this might cause 
> problems with libraries that are distributed with multiple files (Thinking of Bootstrap - although that's a whole other beast).
>  

I was thinking in terms of my project. The only external (non-closure) JS I use is CodeMirror. I have several different builds, most of them do not need CodeMirror. Yet CLJSJS (boot) would prepend it to everything. Also in my case not all builds use the same amount of CodeMirror (eg. one gets clojure-mode vs the other does not).

This stuff is pretty complex, I don't think we can solve it by just creating a few jar files. We MUST address the fact that the produced JS files are shipped to clients (ie. browsers) a lot, therefore we must take great care that they don't contain unnecessary stuff. Shipping CodeMirror to everyone of our users would be a disaster since it is only used for backend/admin stuff.


/thomas

Juho Teperi

unread,
Jan 6, 2015, 8:38:51 AM1/6/15
to clojur...@googlegroups.com
On Tuesday, January 6, 2015 1:20:04 PM UTC+2, Thomas Heller wrote:
> >
> > That's right but for some projects the assumption that .min.js means "minified" is just not true. E.g. React ships with different logging levels enabled based on wether you're including the development or production build. I'm sure there are more projects that include extra debugging stuff that's stripped while packaging.
> >
>
> You are right, I guess I'm too spoiled by CLJS/Closure that I don't have to worry about things like that. ;)
>
>
> > > As a build tool author I don't quite agree with using a naming convention to detect the files (eg. *.inc.js, ...). You could never package more than one file this way since there would be no way to tell the compiler: file Y needs to be added before file B.
> >
> >
> > Very fair point. We haven't actually come across that situation as most libs are distributed as single files but I agree that this might cause 
> > problems with libraries that are distributed with multiple files (Thinking of Bootstrap - although that's a whole other beast).
> >  
>
> I was thinking in terms of my project. The only external (non-closure) JS I use is CodeMirror. I have several different builds, most of them do not need CodeMirror. Yet CLJSJS (boot) would prepend it to everything. Also in my case not all builds use the same amount of CodeMirror (eg. one gets clojure-mode vs the other does not).

Using boot it's easy to filter fileset so that some of files are removed before cljs task picks up the .inc.js files:
(sift :exclude #{#"^cljsjs/.*codemirror.*"})

But several different builds (different apps or modules) is indeed still an area where boot will need some work. It should be possible to build several apps from same sources etc. but all resulting js would contain all the same shared code.

>
> This stuff is pretty complex, I don't think we can solve it by just creating a few jar files. We MUST address the fact that the produced JS files are shipped to clients (ie. browsers) a lot, therefore we must take great care that they don't contain unnecessary stuff. Shipping CodeMirror to everyone of our users would be a disaster since it is only used for backend/admin stuff.

One way would be to build your admin/backend application as a separate app which would have it's own maven dependencies. Or, using boot, it's possible to remove and add maven dependencies as build steps.
So there are ways to control what gets included to build but it's manual work as there is no way to know what external code is actually used by the built js.

I think the greatest problem is that there exists libraries which are pretty useless without custom built step (e.g. Highlight.js is one I encountered). CodeMirror modes and add-ons is also such one. I'm not sure how it should or could be packaged.

>
>
> /thomas

pand...@gmail.com

unread,
Jan 6, 2015, 5:14:52 PM1/6/15
to clojur...@googlegroups.com
I'm pretty sure codemirror's addons (eg clojure mode) can just be included as script tags; so therefore they could be packaged as cljsjs, with a dependency on codemirror itself, no?
Reply all
Reply to author
Forward
0 new messages