This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-21
Channels
- # beginners (65)
- # boot (24)
- # cider (2)
- # clara (13)
- # cljs-dev (45)
- # clojure (48)
- # clojure-dusseldorf (2)
- # clojure-italy (69)
- # clojure-norway (1)
- # clojure-russia (5)
- # clojure-sanfrancisco (1)
- # clojure-spec (51)
- # clojure-uk (34)
- # clojurescript (312)
- # cursive (5)
- # datavis (1)
- # datomic (9)
- # duct (13)
- # editors (3)
- # emacs (2)
- # fulcro (11)
- # graphql (19)
- # hoplon (1)
- # immutant (2)
- # jobs (7)
- # jobs-discuss (38)
- # lein-figwheel (1)
- # luminus (6)
- # off-topic (2)
- # parinfer (10)
- # pedestal (1)
- # re-frame (9)
- # reagent (28)
- # reitit (1)
- # remote-jobs (12)
- # ring-swagger (26)
- # shadow-cljs (232)
- # slack-help (8)
- # tools-deps (29)
- # unrepl (29)
- # vim (10)
- # yada (31)
Anyone else runnig into with shadow-cljs 2.2.16:
Exception in thread "async-thread-macro-12" java.lang.NoClassDefFoundError: Could not initialize class shadow.cljs.devtools.server.reload_classpath$process_update$fn__59202
at shadow.cljs.devtools.server.reload_classpath$process_update.invokeStatic(reload_classpath.clj:21)
at shadow.cljs.devtools.server.reload_classpath$process_update.invoke(reload_classpath.clj:21)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:341)
at clojure.core$reduce.invokeStatic(core.clj:6747)
at clojure.core$reduce.invoke(core.clj:6730)
at shadow.cljs.devtools.server.reload_classpath$process_updates.invokeStatic(reload_classpath.clj:45)
at shadow.cljs.devtools.server.reload_classpath$process_updates.invoke(reload_classpath.clj:38)
at shadow.cljs.devtools.server.reload_classpath$watch_loop.invokeStatic(reload_classpath.clj:75)
at shadow.cljs.devtools.server.reload_classpath$watch_loop.invoke(reload_classpath.clj:63)
at shadow.cljs.devtools.server.reload_classpath$start$fn__59234.invoke(reload_classpath.clj:92)
at clojure.core.async$thread_call$fn__8239.invoke(async.clj:442)
at clojure.lang.AFn.run(AFn.java:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I think it's my fault
a wrong tools.reader version
No I a old tools.reader in my project.clj
Well now it works after removing tools.reader 1.1.2
I see cider support as been improved:
Very cool
Only thing that is not working anymore is file watching for some reason..
yeah, fixed some piggieback things reported here https://github.com/clojure-emacs/cider/issues/2239
Oh sorry, I didn't dare you were so angry the last time you started cider 😛
11:38:40.868 [nREPL-worker-0] WARN shadow.build.classpath - failed to parse javascript file: jar:file:/home/mitchel/.m2/repository/cljs-hash/cljs-hash/0.0.2/cljs-hash-0.0.2.jar!/js/sha256.js
[{:line 11, :column 9, :message "'identifier' expected"}] { }
11:38:40.875 [nREPL-worker-0] WARN shadow.build.classpath - failed to parse javascript file: jar:file:/home/mitchel/.m2/repository/cljs-hash/cljs-hash/0.0.2/cljs-hash-0.0.2.jar!/js/md5.js
[{:line 9, :column 9, :message "'identifier' expected"}] { }
11:38:40.877 [nREPL-worker-0] WARN shadow.build.classpath - failed to parse javascript file: jar:file:/home/mitchel/.m2/repository/cljs-hash/cljs-hash/0.0.2/cljs-hash-0.0.2.jar!/js/sha1.js
[{:line 9, :column 9, :message "'identifier' expected"}] { }
11:38:41.633 [nREPL-worker-0] WARN shadow.build.classpath - failed to parse javascript file: jar:file:/home/mitchel/.m2/repository/doo/doo/0.1.8/doo-0.1.8.jar!/runners/nashorn.js
[{:line 21, :column 39, :message "Semi-colon expected"}] { }
11:38:42.192 [nREPL-worker-0] WARN shadow.build.classpath - failed to parse javascript file: jar:file:/usr/lib/jvm/java-8-openjdk/lib/tools.jar!/com/sun/tools/hat/resources/hat.js
Hmm I know why watching is not working:
(shadow-server/stop!)
shutting down ...
JS runtime disconnected.
Worker shutdown.
11:45:10.423 [nREPL-worker-2] WARN shadow.cljs.devtools.server - shutdown failed ((rt/stop-all app)) { }
java.lang.ThreadDeath: null
at java.lang.Thread.stop(Thread.java:853)
at clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__62024.invoke(interruptible_eval.clj:243)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at user$eval74385$fn__74386$fn__74388.invoke(form-init5239952018706589785.clj:1)
at shadow.cljs.devtools.server.nrepl$cljs_eval$fn__62323.invoke(nrepl.clj:171)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.load_file$wrap_load_file$fn__62170.invoke(load_file.clj:79)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at shadow.cljs.devtools.server.nrepl$cljs_load_file$fn__62334.invoke(nrepl.clj:192)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.session$add_stdin$fn__62099.invoke(session.clj:238)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_debug$fn__70069.invoke(nrepl.clj:161)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_enlighten$fn__70077.invoke(nrepl.clj:187)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_macroexpand$fn__70111.invoke(nrepl.clj:264)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cemerick.piggieback$wrap_cljs_repl$fn__62286.invoke(fake_piggieback.clj:31)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_inspect$fn__70103.invoke(nrepl.clj:224)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_out$fn__70127.invoke(nrepl.clj:305)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_pprint$fn__70035.invoke(nrepl.clj:107)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_tracker$fn__70191.invoke(nrepl.clj:450)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at shadow.cljs.devtools.server.nrepl$cljs_select$fn__62315.invoke(nrepl.clj:153)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.pr_values$pr_values$fn__61940.invoke(pr_values.clj:22)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl$wrap_test$fn__70175.invoke(nrepl.clj:415)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at cider.nrepl.middleware.pprint$handle_pprint_fn.invokeStatic(pprint.clj:49)
at cider.nrepl.middleware.pprint$handle_pprint_fn.invoke(pprint.clj:44)
at clojure.lang.Var.invoke(Var.java:385)
at cider.nrepl$wrap_pprint_fn$fn__70025.invoke(nrepl.clj:88)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.session$session$fn__62084.invoke(session.clj:192)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__61733.invoke(middleware.clj:22)
at clojure.tools.nrepl.server$handle_STAR_.invokeStatic(server.clj:19)
at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:16)
at clojure.tools.nrepl.server$handle$fn__62185.invoke(server.clj:28)
at clojure.core$binding_conveyor_fn$fn__5476.invoke(core.clj:2022)
at clojure.lang.AFn.call(AFn.java:18)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
Still via lein
Because I did (shadow/watch :app)
but it wasn't recompiling
I will try hold on
Now i have this again:
Exception in thread "async-thread-macro-15" java.lang.NoClassDefFoundError: Could not initialize class shadow.cljs.devtools.server.reload_classpath$process_update$fn__59438
at shadow.cljs.devtools.server.reload_classpath$process_update.invokeStatic(reload_classpath.clj:21)
at shadow.cljs.devtools.server.reload_classpath$process_update.invoke(reload_classpath.clj:21)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:341)
at clojure.core$reduce.invokeStatic(core.clj:6747)
at clojure.core$reduce.invoke(core.clj:6730)
at shadow.cljs.devtools.server.reload_classpath$process_updates.invokeStatic(reload_classpath.clj:45)
at shadow.cljs.devtools.server.reload_classpath$process_updates.invoke(reload_classpath.clj:38)
at shadow.cljs.devtools.server.reload_classpath$watch_loop.invokeStatic(reload_classpath.clj:75)
at shadow.cljs.devtools.server.reload_classpath$watch_loop.invoke(reload_classpath.clj:63)
at shadow.cljs.devtools.server.reload_classpath$start$fn__59470.invoke(reload_classpath.clj:92)
at clojure.core.async$thread_call$fn__8239.invoke(async.clj:442)
at clojure.lang.AFn.run(AFn.java:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
which is probably the error that causes this
when doing (shadow/watch :app)
restarting
don't forget lein clean
as usual. doesn't affect shadow-cljs but I don't know what lein
may have done
I get it after stopping and starting the server again and then running (shadow/watch :app)
I am running this to start it btw:
(do (shadow.cljs.devtools.server/start!) (shadow.cljs.devtools.api/watch :app) (shadow.cljs.devtools.api/nrepl-select :app))
Could a circular dependency break shadow-cljs? Just thinking out loud here
so to break it you call (shadow.cljs.devtools.server/stop!)
and then the start above again?
cljs.user> :cljs/quit
:cljs/quit
user> (shadow-server/reload!)
Worker shutdown.
shadow-cljs - HTTP server for :devcards available at
:shadow.cljs.devtools.server/restarted
user> Exception in thread "async-thread-macro-4" java.lang.NoClassDefFoundError: Could not initialize class shadow.cljs.devtools.server.reload_classpath$process_update$fn__65735
at shadow.cljs.devtools.server.reload_classpath$process_update.invokeStatic(reload_classpath.clj:21)
at shadow.cljs.devtools.server.reload_classpath$process_update.invoke(reload_classpath.clj:21)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:341)
at clojure.core$reduce.invokeStatic(core.clj:6747)
at clojure.core$reduce.invoke(core.clj:6730)
at shadow.cljs.devtools.server.reload_classpath$process_updates.invokeStatic(reload_classpath.clj:45)
at shadow.cljs.devtools.server.reload_classpath$process_updates.invoke(reload_classpath.clj:38)
at shadow.cljs.devtools.server.reload_classpath$watch_loop.invokeStatic(reload_classpath.clj:75)
at shadow.cljs.devtools.server.reload_classpath$watch_loop.invoke(reload_classpath.clj:63)
at shadow.cljs.devtools.server.reload_classpath$start$fn__65767.invoke(reload_classpath.clj:92)
at clojure.core.async$thread_call$fn__9069.invoke(async.clj:442)
at clojure.lang.AFn.run(AFn.java:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I do that several hundred times when working on shadow-cljs itself yet I have never seen that error
the error happens on the file change after reload!
Hmm yes I have run go
That would make sense that it breaks it
I don't know why it would though. maybe its something related to the nrepl change I did
Maybe i should start running it externally
Let me try that out to see if that breaks
can you try just restarting it directly from the REPL without calling the tools.namespace stuff?
Hold on wil restart it first
I'll also run a lein deps tree
hmm core async conflict might be related?
I just restarted
en changed a file
and nothing happens
it does not reload
I have no clue. it might be the piggieback change I did because that messes with the *ns*
binding which is a bit scary
Very weird the only thing is broken is the watching and recompiling
the repl works like a charm
wait does the reloading also not work if you just started it clean without stop!
or reload!
first?
2.1.21
Only other conflicts with jars that I find is jackson-core but I cannot imagine that breaking anything
Would it help if I put shadow-cljs in verbose mode somehow?
I have never seen this error in several years of clojure. I don't understand why you'd get NoClassDefFoundError
. clojure is supposed to create the class before loading it.
Hmm I do a set-refesh-dirs
And now it works
When I removed that call
I had this:
(set-refresh-dirs "dev/server" "src/main" "test" "src/cards")
from
[clojure.tools.namespace.repl :as tools-ns :refer [set-refresh-dirs]]
removal works.. I still had this from the fulcro template
The set-refresh-dirs
was there because figwheel would copy cljc files into resources, and then server refresh will accidentally find them and cause problems. Shadow doesn’t do that, so it probably isn’t helping anything.
I'll see if it stays fixed
Thank you for listening @thheller
It also keeps working after resets
@thheller Now I am running into: java.lang.NoClassDefFoundError: Could not initialize class shadow.build.warnings$get_source_excerpts$iter__60601__60605$fn__60606$fn__60607$fn__60609
Really weird that I am getting NoClassDefFoundError
@mitchelkuijpers so weird indeed
> val_waeselynck [17:28] @thheller I tend to have this sort of error after I uberjar my project while my code is running. I think this changes the class files in some way to messes up the REPL.
I am now running it separately with the shadow-cljs command
No nothing like that
Here I am @hlolli
cool, Im guessing you didn't set :devtools ?
:devtools {:http-root "public"
:http-port 8088
;; :http-handler dev.server/handler
:after-load visitor.main/init}
this is my current project, the after load would be my react init function.I just cloned and ran this: https://github.com/lauritzsh/reagent-shadow-cljs-starter
Maybe it’s too old.. I’ll update it
I see that now lol
There it is!
Ohh, nice spinner
Wow, I might switch from lein/cljsbuild to boot/shadow in the same week, lol.
yup, I'm like a broken record repeating this tip, but you can basically start shadow-cljs watch and then start the backend to serve the output directory, you'll get the hot reload weather or not you're conencted to the localhost port given in the :devtools.
I assume it plays nicely with boot as well?
yes, if you keep the clojure seperated from the clojurescript, then it would also work well with python, node or any backend.
some folks are mixing lein and shadow in some fancy way, have no idea if that works with boot, and what the gain is from doing that.
@jmckitrick I know very little about boot and haven't done many tests. I know that it interferes a little with shadow-cljs related to caching and things. everything should work in theory but I really don't know.
I greatly appreciate the offer! We’re doing the first official clojure products at work, and I’ll be on the hot seat for any issues we run into along the way 😧
the smoothest option is to just keep the CLJ and CLJS worlds separate. they don't benefit at all when you combine them and just cause headaches if your CLJS deps interfere with CLJ deps
Interesting. ok, duly noted.
Should I be surprised if the binary is much smaller than that produced by cljs-build?
the config sets a couple of optmizations that you maybe didn't set when using cljsbuild
I might be sold, then. I’m going to spend the day tomorrow digging in deeper. So much for generative testing day, lol.
I’ve updated my guide on how to use javascript in cljs. My goal here is to have something to point people to when they ask about this on slack. I’d appreciate a read before I start sending it to folks just to make sure I’m not mischaracterizing something. https://gist.github.com/jmlsf/f41b46c43a31224f46a41b361356f04d
@thheller doesnt it incur extra overhead to separate front and back ends? In other words how do I serve up the front end page and assets separately from the backend? I assume I need to run Express?
@lee.justin.m you probably know the answer as well
during development you just serve the front end from the shadow-cljs development server
during production, you’ll compile the front end to a javascript bundle and then serve it as if it were a static resource from the backend
So I can’t really keep the code entirely separate, then, right? The payload still needs to end up in the js directory of the server project
I was assuming you’ve got a SPA front end that connects via some kind of API that is running on clojure.
I wouldn't separate the code because you might want to share some code from the client and server
If you are running a templated backend then the “keep it separate” advice might be more complicated.
if you compile your code to say public/js
and configure your server to serve static files from public
you are all set
Or if you’re doing something like server side rendering, that might call for something different.
@lee.justin.m reading over your gist
shouldn't that be like (1)? you don't need to tell the compiler about the double bundle at all in theory
I think it should say like (1) or (3) because you can do it either way (the two blog posts I link to do either either way)
one extra thing that shadow-cljs does that the default cljs externs inference doesn't do
since shadow-cljs fully processes all .js files it extracts some extra externs infos from them
that makes it sound like string requires are shadow-cljs only. they are not. if :npm-deps ever works out it should work identically in CLJS
Accurate?
> Use shadow-cljs
automated externs inference. Shadow-cljs will give you warnings when it can’t figure things out and you can just provide a type hint. Because shadow processes all of your JavaScript libraries, Shadow can infer externs from them, which is a real advantage over some other approaches relying on the built-in compiler’s extern inference.
in theory if externs inference for CLJS was perfect that would be enough. the extra JS processing just makes it a bit more reliable for now
in your example config. remove clojure/clojurescript deps, they are provided. :http-handler
push-state is the default now so you can remove that as well
>Note the :after-load entry point: this is what shadow-cljs will call when it hot reloads new code.
Note the :after-load
symbol, this is what shadow-cljs will call after hot reloading code finishes.
I wouldn't bash cljsjs so heavily. It works pretty darn well IFF you are only using a very small amount of it. say if you are only using React it is pretty darn good for that.
It’s so complicated! Here, learn this barely documented externs syntax! Here, learn boot!
but I used it for a very long time when I just wanted react is it worked well for that
I’ll look for places to tone it down. I don’t want to be mean to people who spent their free time on something.
you could also mention that shadow-cljs actually allows full 100% interop (ns demo.bar (:require ["./foo" :as foo]))
would load demo/foo.js
from the classpath
and that JS can actually require CLJS via import cljs from "goog:cljs.core"; cljs.assoc(nil, "foo", 1)
this is not 100% perfect yet but it is a goal of mine to support compilation of JS projects that just want to start using CLJS without having to rewrite everything
in theory I could add support for https://www.webjars.org/ which also mirrors npm
Okay I added these two points. It’s a little OT but I agree it’s worth mentioning. * Shadow-cljs actually lets you load any JavaScript file on the classpath. So, (ns demo.bar (:require ["./foo" :as foo]))
would load demo/foo.js
from the classpath. [This is experimental.](https://shadow-cljs.github.io/docs/UsersGuide.html#_requiring_js)
* It also allows interop in the other direction, [by embedding cljs in an existing JavaScript app](https://shadow-cljs.github.io/docs/UsersGuide.html#target-npm-module).