Fork me on GitHub
Darin Douglass16:12:16

what’s best-practice on clojure(script) as :deps in libraries? we’ve run into a case where, because clojurescript is packaged in the library’s pom, data.json breaks when serializing instants:

❯ clj -Sdeps '{:deps {org.clojure/data.json {:mvn/version "2.4.0"} com.yetanalytics/colossal-squuid {:mvn/version "0.1.3"}}}' ;; this includes both `clojure` and `clojurescript` (with the latter being the problem) in its `:deps`
Clojure 1.10.3
user=> (require '[ :as json])
user=> (json/write-str (java.time.Instant/now))
Execution error at (json.clj:385).
Don't know how to write JSON of class java.time.Instant
i started looking around at clojure/script libraries a bit and didn’t see anything super conclusive, though of the cljc libraries i looked through, colossal-squuid is the only one with a hard dep on clojurescript. should clojure(script) be treated as “provided” deps in libraries and just assumed to provided by the app? should apps (per colossal-squiid’s recommendation) just :exclusion what it doesn’t need?


Back when I was maintaining cljc libs, I would build different artifacts (maybe using classifiers? don’t remember) for each. This was definitely not a mainstream approach though, so for other people’s libs I just checked the transitive dependencies carefully and used exclusions.


I think the fundamental lesson I took away from that experience was that even though you share a src folder doesn’t mean you share a deps.edn/project.clj/pom.xml


the same code has different sets of dependencies. Since dependency declaration in the maven system is tied to artifacts, that means different artifacts is the least-friction approach

Darin Douglass17:12:03

ya, when the different flavors of the library have completely different dependency sets it makes sense to have different artifacts

Alex Miller (Clojure team)16:12:59

I assume this is because of the bundled older data.json in Clojurescript? I'd say that's really the core problem and both those suggestions are valid workarounds. Really cljs should probably be shading that dep to avoid this issue.

Darin Douglass16:12:36

that’s kinda what i thought as well, though -Stree shows that old version being dropped

❯ clj -Sdeps '{:deps {org.clojure/data.json {:mvn/version "2.4.0"} org.clojure/clojurescript {:mvn/version "1.10.879"}}}' -Stree
org.clojure/clojure 1.10.3
  . org.clojure/spec.alpha 0.2.194
  . org.clojure/core.specs.alpha 0.2.56
org.clojure/data.json 2.4.0
org.clojure/clojurescript 1.10.879
  . v20210505
  . org.clojure/google-closure-library 0.0-20201211-3e6c510d
    . org.clojure/google-closure-library-third-party 0.0-20201211-3e6c510d
  X org.clojure/data.json 0.2.6 :use-top
  . org.clojure/tools.reader 1.3.3
  . com.cognitect/transit-clj 0.8.309
    . com.cognitect/transit-java 0.8.332
      . com.fasterxml.jackson.core/jackson-core 2.8.7
      . org.msgpack/msgpack 0.6.12
        . com.googlecode.json-simple/json-simple 1.1.1
        . org.javassist/javassist 3.18.1-GA
      . commons-codec/commons-codec 1.10

Darin Douglass16:12:25

also in the repl, the clojure/data/json.clj resource apparently points at the right 2.4.0 jar ¯\(ツ)

Alex Miller (Clojure team)16:12:29

Clojurescript bundles it in its jar so tools.deps can't know about it or make decisions about it

Alex Miller (Clojure team)16:12:56

Depending how the classpath sorts, you can see either