Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use "foreign" JavaScript dependencies in Clojurescript?

I'm trying to wrap my head around using "foreign" JavaScript dependencies in Clojurescript. I've read most everything Google has to offer on this topic but I still fail to understand this process. In particular, I'm interested how to depend on the jsonld.js library from Clojurescript.

Some points I don't get:

  1. Do you put :foreign-libs into deps.cljs or compiler options (e.g., :compiler map in project.clj)?

  2. Is the value of :file in :foreign-libs interpreted as a Java resource? Where do you put the JavaScript files you use as foreign libraries? I tried putting them into resources and elsewhere, but all my attempts resulted in java.lang.NullPointerException.

Steps to reproduce:

# Create an empty Clojurescript project
lein new figwheel jsonld

# Download jsonld.js library
cd jsonld/resources
curl -O http://cdnjs.cloudflare.com/ajax/libs/jsonld/0.3.15/jsonld.js

# Configure foreign libs in project.clj.
# Add the following into `:compiler` in the dev build:
# :foreign-libs {:file "resources/jsonld.js"
#                :provides ["jsonld"]}

lein figwheel # => java.lang.NullPointerException

Alternatively, if I provide deps.cljs with the following content:

{:foreign-libs {:file "jsonld.js"
                :provides ["jsonld"]}}

Then Figwheel starts, but when I call (require '[jsonld]), I get this error:

WARNING: JavaScript file found on classpath for library `jsonld`, but does not contain a corresponding `goog.provide` declaration
clojure.lang.ExceptionInfo: No such namespace: jsonld, could not locate jsonld.cljs, jsonld.cljc, or Closure namespace "jsonld" {:tag :cljs/analysis-error}
like image 857
Jindřich Mynarz Avatar asked Apr 26 '26 15:04

Jindřich Mynarz


1 Answers

Update: The :foreign-libs option takes a vector of foreign libs and not a single map.

The :foreign-libs option can either be supplied to the compiler directly or via a deps.cljs file within jars. deps.cljs is mostly useful when you want to package a Javascript library within a jar that other people may use — maybe useful later but not what you need right now.

You can find more information about the compiler option in the wiki. There also is a page specifically about using/packaging foreign dependencies in ClojureScript.

I think in your particular example the problem is the path you're supplying as :file. The path is classpath-relative and the contents of the resources/ directory are added to the classpath, meaning if you want to point to resources/jsonld.js in a classpath-relative way it's just jsonld.js.

PS: You can also supply URLs as :file and the compiler will download them for you.

like image 121
Martin Klepsch Avatar answered Apr 28 '26 04:04

Martin Klepsch