12

I've just written some ClojureScript code, only to find out that I couldn't access one of the libraries listed in my project.clj's dependencies. Is this correct, i.e. that you can't use Clojure libraries from CLJS unless they're specifically designed to allow it?

If so, how much extra work is required to take a Clojure library that doesn't use any Java interop, and would itself be valid ClojureScript code, and make it useable from ClojureScript? From looking around GitHub, many libs appear to have separate source directories for clj and cljs code. Can such a library be added to my project.clj and be used immediately from either platform?

2 Answers 2

6

There are some ClojureScript differences from Clojure.

Dependecies from "project.clj" can be applicable / visible / usable by ClojureScript, for example, take a look at "jayq". You would include it in "project.clj":

(defproject xyz/xyz "0.1.0-SNAPSHOT"
  :dependencies [[clj-time "0.4.3"]
                 [jayq "2.2.0"]
                  ....

And then use it in the ClojureScript file:

(ns xyz.some.cljs
  (:require ...
            ...
            [clojure.browser.repl :as repl]
            [jayq.core :as jq])

While "jayq" is not a "Clojure" library in the "backend" sense since it just wraps JavaScript, it is an example of using a "project.clj" dependency on the ClojureScript side.

In addition most of the core and several non core libraries are already ported to the ClojureScript side:

  • clojure.set
  • clojure.string
  • clojure.walk
  • clojure.zip
  • clojure.core.reducers
  • fold is currently an alias for reduce
  • core.match
  • core.logic (in works)

Other Clojure libraries will have to conform to the ClojureScript subset in order to work in ClojureScript.

It is worthwhile to clone ClojureScript repo and get a sense of what it supported (plus add your own features if you feel adventurous :)

ClojureScript dependencies are usually "front end" based (included the ones ported from backend). In other words, the end goal is to be compiled by V8 and run as JavaScript, hence anything that can be compiled by the ClojureScript compiler (repo above) can be used.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks. So when I add jayq to my project.clj file, how does the compiler know that it's ClojureScript? I see that jayq's own project file is almost empty: github.com/ibdknox/jayq/blob/master/project.clj So how does it tell?
Also, as an extension to the above, if I wanted to write a library that worked from both "ends," how would I go about it?
usually when developing in Clojure/ClojureScript, you would use a lein-cljsbuild plugin that allows to configure CLJS compiler via "project.clj", as well as share code where you can reuse namespaces between Clojure and ClojureScript. Of course: "remember that since the namespace will be used by both Clojure and ClojureScript, it will need to only use the subset of features provided by both languages"
OK. So if I wrote a library with a project.clj that pointed to a crossover namespace with all my code in it, that library would work from both Clojure and ClojureScript? If so, how come jayq doesn't have anything in its project.clj?
correct. given that a new library files are in :source-dir/:extra-classpath-dirs + they are in "ClojureScript" supported feature subset. Also try it first without building a new library "jar", but using the library ".clj" files directly (e.g. easier for lein-cljsbuild to manage the classpath and monitor changes)
|
0

I see that the answers were given in 2013, but as of 2020, this is still the case with CLJS version 1.10. Its still not possible to use just any Clojure library, unless the library has been made CLJS compatible.Building with shadow-cljs will give build error like:

The required namespace "clojure.data.json" is not available, it was required by "bharati/binita/frontend/demo3/main.cljs".
"clojure/data/json.clj" was found on the classpath. Should this be a .cljs file?

I could not see any solution to that,other than using any other alternative library that is CLJS compatible.

2 Comments

Since Clojure 1.8 (2016), if library writers name their source files ".cljc" instead of ".clj", the library is usable in all variants of Clojure. See release notes github.com/clojure/clojure/blob/clojure-1.8.0/changes.md. A cljc file should mainly stick to portable language features, but may provide JVM/JS/CLR variants where it needs to.
Anyway, clojure.data.json is a salve for JVM programs that must jump through hoops to read JSON. Browsers read JSON natively; no need for such a library. You may read and write JSON using ClojureScript's JS interop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.