Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusable ClojureScript Libraries

So, I took my large Clojure project and split it into two.

I compiled the core part and made an Uberjar.

Then typed :

lein deploy clojars

to make that jar public, and then added it as a dependency in the project.clj file for my application.

This code is written in cljx so it can compile to javascript.

What are the equivalent steps I need to make my two cljx codebases into two separate javascript libraries, without having the whole ClojureScript virtual machine repeated twice?

Update : Just to clarify a couple of things.

1) I know I can move to .cljc rather than .cljx. My only concern is that this seems pretty new and I don't know if existing users of my code are likely to have it. But I probably will make this move shortly. Answers in terms of cljc are also welcome.

2) I am already successfully compiling my code to a single monolithic main.js file. What I'm looking for is how to compile separate libraries of cljs that can be included in other cljs projects. As every time I currently compile something in cljs I get a main.js file with the entire clojurescript VM.

3) One of my motivations for coming back to this question is that I want to start using Figwheel. So I want to be able to make libraries in clojurescript that I can drop into a new clojurescript project I'm developing through Figwheel. So I imagine I'd be referencing them in this new project's project.clj file, and including them within the web-page as already compiled .js files. Am I wrong about this?

like image 402
interstar Avatar asked Dec 03 '14 14:12

interstar


2 Answers

Have you tried Leiningen's checkout dependencies feature?

https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md#checkout-dependencies

like image 84
myguidingstar Avatar answered Oct 11 '22 21:10

myguidingstar


It's difficult to say what's wrong or missing from your configuration without having more details about your project.clj, but I'll try to cover the most important parts where you should take a look at.

Do not use cljx. Use Reader Conditionals!

Nowadays, cljx is deprecated in favor of Reader Conditionals (cljc). If you have the chance to upgrade to clojure 1.7.0 then my suggestion is to do that and leave cljx behind: You'll avoid much of the issues from cljx because instead of using a build tool (that needs to be in sync with the rest of the build pipeline) cljc is something that the clojure compiler is aware of.

If you are still going to use cljx...

I won't repeat all the stuff covered in the excellent README from cljx but just pinpoint some relevant parts:

  1. You have to be sure cljx once is called before other tasks down in the pipeline (javac, compile, uberjar and even test or cljsbuild test). So you might want to create aliases or modify the default :prep-tasks in your project.clj. More info: see the Installation section

  2. Your cljx :output-path should be added to your cljsbuild :source-paths. See the Usage section

Last but not least:

  1. Do not declare your dependency as :classifier "aot" in your dependencies vector when using cljsbuild. Use it only if you know what you are doing. Remove it during development if you have dependency issues. This applies whether you are using cljx, cljc or just plain cljs.

  2. Take a look to other projects cljx configurations. For example: Prismatic/schema and the "Switch to reader conditionals" commit in Sablono

like image 31
nberger Avatar answered Oct 11 '22 22:10

nberger