How do I use cljsjs packages in a deps.edn project - clojure

I've tried adding a dependency to my deps.edn:
{:deps {cljsjs/js-yaml {:mvn/version "3.3.1-0"}
...}
But I'm not able to call functions from that library.
In the REPL:
cljs.user=> (require '[cljsjs.js-yaml])
cljs.user=> js/safeLoad
Execution error (ReferenceError) at (<cljs repl>:1).
safeLoad is not defined
The instructions I found are for leinigen (project.clj). Do I need to do something special to get it working in deps.edn?

You need to do js/jsyaml.safeLoad and at the repl you need to use the function require rather than the symbol used in a ns declaration.
bfabry#18723-bfabry /t/foo> plk
ClojureScript 1.10.520
cljs.user=> (require '[cljsjs.js-yaml])
nil
cljs.user=> (js/jsyaml.safeLoad "app:\n bar: baz\n")
#js {:app #js {:bar "baz"}}
cljs.user=>
the packages are namespaced using js objects of their own name.

Related

Clojure: Cannot launch cider repl with boot

I have the following build.boot file,
(set-env!
:resource-paths #{"src"}
:dependencies '[[me.raynes/conch "0.8.0"]
[boot.core :as boot]])
(task-options!
pom {:project 'myapp
:version "0.1.0"}
jar {:manifest {"Foo" "bar"}})
(boot/deftask cider "CIDER profile"
[]
(require 'boot.repl)
(swap! #(resolve 'boot.repl/default-dependencies)
concat '[[org.clojure/tools.nrepl "0.2.12"]
[cider/cider-nrepl "0.15.0"]
[refactor-nrepl "2.3.1"]])
(swap! #(resolve 'boot.repl/default-middleware)
concat '[cider.nrepl/cider-middleware
refactor-nrepl.middleware/wrap-refactor])
identity)
following this documentation: https://github.com/boot-clj/boot/wiki/Cider-REPL
However, upon doing cider-jack-in I get the error "refusing to run as root. set BOOT_AS_ROOT=yes to force.", and yet after doing export BOOT_AS_ROOT=yes, I get the same error. What's wrong?
This wiki page is super outdated, so I don't recommend following it. I'd be best to read CIDER's documentation instead.
Just make sure you're using Boot 2.8.3. You don't really need any special CIDER profile. Just create a Boot project, open a file from it in CIDER and do M-x cider-jack-in-clj.

Can not require third-party library in lein repl

clojure version: 1.8.0
leiningen version: 2.7.1
jdk version: 1.8.0_101
When I require a library, say reagent(has added in the project dependencies), in the lein repl:
user=> (require '[reagent.core :as r])
nil
The output is nil, which I think it means success. But when I use the r,say (r/atom 3), the repl throw an error says:
CompilerException java.lang.RuntimeException: Unable to resolve symbol: r in
this context, compiling: (/private/var/folders/_y/n3ym4ftj2ld9tl471g_kcv_00000gn/T
/form-init1002540725014588615.clj:1:4923)
That seems strange.
Anyone has some idea?
By the way, I can require java and clojure library.
Probably you are trying to use ClojureScript library: reagent within the Clojure REPL. Finding the cause to error is not that useful since Clojure and ClojureScript are suppose to run in very different environments, JVM and JavaScript respectively. But same attempt will succeed in ClojureScript context.
As a test, create a ClojureScript project based on figwheel template.
lein new figwheel rtest
cd rtest
Add the regent dependency in project.clj
:dependencies [[org.clojure/clojure "1.8.0"]
[reagent "0.6.0"] ; only add this line
Run the project
rlwrap lein figwheel
You will be connected to the browser repl automatically. Otherwise browse to http://localhost:3449/index.html to get connected.
Now you can retry what you did.
cljs.user=> (require '[reagent.core :as r])
nil
cljs.user=> (type r/render-component)
#object[Function "function Function() { [native code] }"]

Can't get browser repl to work from chestnut template (figwheel, weasel)

I try to get started with ClojureScript using the chestnut leiningen template which combines piggyback, figwheel and weasel. After upgrading my leiningen installation to 2.5.0, I can start the clojure repl, but after issuing the recommended run and browser-repl commands, I run into a cryptic error. There seems to be a core.async issue as well, which I don't know whether it's related.
chestnut-borked.server=> (run)
2014-10-07 12:38:06.506:INFO:oejs.Server:jetty-7.6.13.v20130916
2014-10-07 12:38:06.545:INFO:oejs.AbstractConnector:Started SelectChannelConnector#0.0.0.0:10555
Starting figwheel.
Starting web server on port 10555 .
#<Server org.eclipse.jetty.server.Server#6cdd377c>
Compiling ClojureScript.
Figwheel: Starting server at http://localhost:3449
Figwheel: Serving files from '(dev-resources|resources)/public'
Compiling "resources/public/js/app.js" from ["src/cljs"]...
WARNING: Use of undeclared Var cljs.core.async/do-alts at line 62 file:/home/schauer /.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async/impl/ioc_helpers.cljs
WARNING: Bad method signature in protocol implementation impl/Handler lock-id at line 214 file:/home/schauer/.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async.cljs
WARNING: Use of undeclared Var cljs.core.async.impl.protocols/lock-id at line 217 file:/home/schauer/.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async.cljs
WARNING: Use of undeclared Var chestnut-borked.dev/put! at line 14 src/cljs/chestnut_borked/dev.cljs
[... some warnings removed after first answer ...]
WARNING: Bad method signature in protocol implementation impl/Handler lock-id at line 214 resources/public/js/out/cljs/core/async.cljs
WARNING: Use of undeclared Var cljs.core.async.impl.protocols/lock-id at line 217 resources/public/js/out/cljs/core/async.cljs
Successfully compiled "resources/public/js/app.js" in 21.377 seconds.
notifying browser that file changed: /js/app.js
notifying browser that file changed: /js/out/goog/deps.js
notifying browser that file changed: /js/out/chestnut_borked/core.js
notifying browser that file changed: /js/out/chestnut_borked/dev.js
Besides from the warnings, so far, so good -- Jetty seems to have started successfully. However, when I try to start the browser-repl, I run into an error and the connection seems to be broken:
chestnut-borked.server=> (browser-repl)
WARNING: Bad method signature in protocol implementation impl/Handler lock-id at line 214 file:/home/schauer/.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async.cljs
ArityException Wrong number of args (0) passed to: compiler/with-core-cljs clojure.lang.AFn.throwArity (AFn.java:429)
chestnut-borked.server=> (browser-repl)
java.io.IOException: No client connected to Websocket
at weasel.repl.server$send_BANG_.invoke(server.clj:25)
at weasel.repl.websocket$send_for_eval_BANG_.invoke(websocket.clj:130)
at weasel.repl.websocket$websocket_eval.invoke(websocket.clj:109)
at weasel.repl.websocket.WebsocketEnv._evaluate(websocket.clj:34)
at cljs.repl$evaluate_form.invoke(repl.clj:113)
at cemerick.piggieback$cljs_eval$fn__5152.invoke(piggieback.clj:115)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
[...]
UPDATE: After the input from lnmx, it's becoming clear that weasel isn't functioning properly. If I take a look at the JS elements that the browser sees, the dev script apparently doesn't get loaded and neither is the repl.js from weasel, although there are goog.addDependency calls for them in app.js.
Chestnut 0.5.0 has been released now. It contains an updated ClojureScript which should fix the issue with Weasel (the browser-connected REPL), as well as several other improvements.
I had some success with chestnut 0.5.0, but some changes were needed. I am new to Clojure so I may be missing something -- anyway, here's what I found:
It looks like the README file for chestnut describes the usage of version 0.5.0, but that version is not available on clojars as of today.
So, per the README, I installed from a local copy:
git clone https://github.com/plexus/chestnut.git
cd chestnut
lein install
...and created a new project:
lein new chestnut tree
Attempting to compile the cljs with lein cljsbuild once produced the Bad method signature warning related to lock-id. So, I started by adding the latest core.async to project.clj under :dependencies
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
Then there were some errors related to undefined core.async functions, so I fixed the requires in src/cljs/tree/core.cljs:
(ns tree.core
(:require [tree.dev :refer [is-dev?]]
[cljs.core.async :refer [chan <!]]
[om.core :as om :include-macros true]
[om.dom :as dom :include-macros true])
(:require-macros [cljs.core.async.macros :refer [go alt!]]))
and src/cljs/tree/dev.cljs:
(ns tree.dev
(:require [figwheel.client :as figwheel :include-macros true]
[cljs.core.async :refer [put!]]
[weasel.repl :as weasel]))
The next issue is that tree.dev needs a reference to the re-render-ch owned by tree.core. So I wrapped the "dev mode" setup into a function called from tree.core (src/cljs/tree/core.cljs):
(defonce re-render-ch (chan))
(when is-dev?
(tree.dev/setup re-render-ch))
...and implemented in tree.dev (src/cljs/tree/dev.cljs):
(def is-dev? (.contains (.. js/document -body -classList) "is-dev"))
(defn setup [re-render-ch]
(when is-dev?
(enable-console-print!)
(figwheel/watch-and-reload
:websocket-url "ws://localhost:3449/figwheel-ws"
:jsload-callback (fn []
(println "reloaded")
(put! re-render-ch true)))
(weasel/connect "ws://localhost:9001" :verbose true)))
With those changes, I can start lein repl, (run) and (browser-repl) OK.
During (run) I get this error:
ArityException Wrong number of args (0) passed to: compiler/with-core-cljs
(not sure where this is coming from). However, if I edit tree/src/cljs/tree/core.cljs and add
(reset! app-state {:text "Hello There?"})
the change is compiled automatically and shows up in the browser shortly after I save the file.
Per the comment, this still doesn't fix the browser-repl. For that I had to get a local copy of weasel, and hack src/clj/weasel/repl/websocket.clj ~line 88:
- (cmp/with-core-cljs)
+ (cmp/with-core-cljs {} (fn [] (println "foo")))
It seems to be related to an API change in the cljs compiler. With that, I can (browser-repl) without any warnings, and (do (js/alert "Hello world!") 42) produces an alert in the browser.

Importing clojure.contrib.generic.math-functions

I download the clojure 1.2 and clojure-contrib-1.2.0.jar from the download site.
And I found the info about the math functions.
As is shown in the example, I tried to run the code.
(ns your-namespace
(:require clojure.contrib.generic.math-functions))
(println (abs 10))
But, I got the following error, when I run as follows.
CLOJURE_JAR=/Users/smcho/bin/jar/clojure.jar:/Users/smcho/bin/jar/clojure-contrib-1.2.0.jar
java -cp $CLOJURE_JAR:$CLASSPATH clojure.main SOURCE.CLJ
Exception in thread "main" java.lang.Exception: Unable to resolve symbol: abs in this context (hello.clj:4)
at clojure.lang.Compiler.analyze(Compiler.java:5205)
...
at clojure.main.main(main.java:37)
Caused by: java.lang.Exception: Unable to resolve symbol: abs in this context
at clojure.lang.Compiler.resolveIn(Compiler.java:5677)
at clojure.lang.Compiler.resolve(Compiler.java:5621)
at clojure.lang.Compiler.analyzeSymbol(Compiler.java:5584)
at clojure.lang.Compiler.analyze(Compiler.java:5172)
... 25 more
What might be wrong?
Try :use instead of :require
(ns your-namespace
(:use clojure.contrib.generic.math-functions))
(println (abs 10))
10
nil
Require makes the symbol (abs in this case) available, but you'd have to fully qualify it. Use imports the symbol into "your-namespace":
(ns your-namespace2
(:require clojure.contrib.generic.math-functions))
(println (clojure.contrib.generic.math-functions/abs 10))
10
nil

Compiling Clojure?

I'm feeling slightly silly here, but I can't get Clojure Hello World to compile.
Directory structure:
hello-world/
clojure-1.1.0.jar
build/
classes/
src/
test/
hello.clj
hello.clj:
(ns test.hello
(:gen-class))
(defn -main [& args]
(println "Hello" (nth args 0)))
Interaction:
$ cd hello-world
[hello-world]$ java -cp ./clojure-1.1.0.jar:./build/classes:./src clojure.main
Clojure 1.1.0
user=> (require 'test.hello)
nil
user=> (test.hello/-main "there")
Hello there
nil
user=> (compile 'test.hello)
java.io.IOException: No such file or directory (hello.clj:2)
user=> *compile-path*
"classes"
user=> (doseq [p (.split (System/getProperty "java.class.path") ":")] (println p))
./clojure-1.1.0.jar
./build/classes
./src
nil
So I can load and call the file from the REPL, but it doesn't compile.
According to clojure.org, compilation needs
namespace must match classpath-relative file path - check
*compile-path* must be on the classpath - check
:gen-class argument to the ns form - check
I found this post from a year back, as far as I can tell I'm doing exactly the same, but it doesn't work.
What am I missing?
System: OS X 10.6, Java 1.6.0, Clojure 1.1
Got it, there's a fourth requirement:
*compile-path* is resolved relative to the JVMs working directory, normally the directory where java is started. Or by REPL: (System/getProperty "user.dir"),
So this works:
user=> (set! *compile-path* "build/classes")
"build/classes"
user=> (compile 'test.hello)
test.hello
Why you don't use Leiningen? It's much easier to use it, than compile code manually. You can use my article about it as introduction...
To run clojure file
clojure filename.clj