This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-07
Channels
- # announcements (1)
- # babashka (77)
- # beginners (219)
- # chlorine-clover (6)
- # cider (52)
- # clj-kondo (14)
- # cljdoc (5)
- # clojure (173)
- # clojure-europe (49)
- # clojure-finland (1)
- # clojure-germany (2)
- # clojure-italy (1)
- # clojure-nl (39)
- # clojure-sweden (4)
- # clojure-uk (51)
- # clojurescript (25)
- # code-reviews (9)
- # conjure (25)
- # data-science (2)
- # figwheel-main (6)
- # fulcro (74)
- # graalvm (1)
- # graphql (11)
- # jobs-discuss (17)
- # keechma (4)
- # lein-figwheel (4)
- # leiningen (1)
- # luminus (10)
- # malli (14)
- # mid-cities-meetup (2)
- # off-topic (28)
- # re-frame (5)
- # reagent (76)
- # reitit (30)
- # ring (7)
- # ring-swagger (1)
- # shadow-cljs (163)
- # spacemacs (11)
- # specter (2)
- # sql (43)
- # tools-deps (13)
- # vim (6)
- # yada (1)
Clojurists Together is coming up and I'm thinking about applying for shadow-cljs. I just don't have anything in particular I want to work on. Do any of you have any suggestions about stuff I should be working on?
yeah that is kinda what I want to work on but its too speculative and really not shadow-cljs specific
maybe I'll make an update for the Inspect stuff I already built and apply with that separately
ah, so is the non-speculativeness an important criteria for the application? i thought the results here: https://www.clojuriststogether.org/news/q2-2020-survey-results/ sort of suggested that may be speculative things might be appreciated too?
yes, but I'm asking specifically if there is something in shadow-cljs itself people would like to see
I know what extra-mains does in figwheel but I don't see why I would use it over separate builds?
I'd also love to see more work on Shadow-CLJS Inspect. I'm aware that you intend for Inspect to be usable from outside of Shadow-CLJS, but that doesn't make it a "too risky" project, in my opinion. The fact that it can be decoupled from Shadow seems like a pure advantage to me. Sorry for adding a second reply that avoids your constraints, but Inspect is something I think could become fantastic. It might make sense to identify some Shadow-CLJS maintainance tasks to go along. I don't have any good recommendations there. Note that whereas one of the points of Clojurists Together is to fund the "boring work", there's plenty of interest in doing speculative work. Image source: https://www.clojuriststogether.org/news/q2-2020-survey-results/
I also view Shadow as quite stable in its current state, with great docs. Maintainance work and documentation might be more of a critical task in other projects.
well that depends I'd say. for my 6core/12thread CPU running two builds in parallel that may use the same namespace usually end up completing at the same time?
and extra-mains produces overhead for the "main" build making that always slower and recompiling when it might not need to
I'm not against adding it since it is fairly trivial to do so. I just don't have use for it myself so I need a proper use-case setup I can use for testing
are they all rolled into one with extra-mains during development and then just split out for release builds?
can you clarify what target means for you? :target
in shadow-cljs is likely not what you mean?
I guess we should start by trying to switch to shadow an measuring the performance impact, this has been on our list for a while
and your main concern about using separate builds is that namespaces will be compiled once for each build?
yes, our setup also is such that we compile the same main namespace for different targets, e.g. browser, web-worker and graaljs
that way the worker and main can share code and the user only downloads cljs.core etc once
oh, I missed that and didnβt know about that. That should cut things down quite a bit for us, thank you!
{:init-fn foo.bar/init}
is basically sugar for {:entries [foo.bar] :append-js "foo.bar.init();"}
but :append-js
per module is also shadow-cljs specific
but the entire :modules
integration in shadow-cljs is so completely different that it will be non-trivial to adopt this for core
I wondered why you are using :simple
compiled CLJS for the "normal" pages that aren't even using CLJS?
wouldn't it be better for your users to have one :advanced
build for regular page stuff
would it be possible to have an advanced build and load self-hosted into the same target?
as long as the advanced and self-hosted builds only interact via "remote" RPC basically. so each serializes to EDN or whatever and the other loads it
easy if you load the self-hosted env in a worker or so since that has to talk that way anyways
well each will have its own base yes but the :advanced
one will be much much smaller
and the self-hosted load on demand so no impact on overall page performance that might not use it
also multiple builds in shadow-cljs works a bit differently than elsewhere due do the caching
how come the link you gave me about the graal stuff loads the :simple
compiled version of cljs?
doesn't seem to need any self-hosted things? seems like a large chunk of JS for a page that doesn't use much?
but your entire setup seems rather "custom" and the defaults in shadow-cljs might not be a good fit for a setup like that
> graaljs support has some up in the past and that would be interesting @thheller i am very curious about what this would mean in the context of shadow-cljs
this stuff https://nextjournal.com/kommen/clojure-berlin-prosemirror-transforms-with-graalvm-and-clojure
graalvm native-image cannot be supported since the CLJS compiler needs to be able to load code dynamically for macros and stuff. native-image cannot do that.
very interesting
and since nashorn is going away I need to find a replacement for shadow-cljs anyways (since that uses nashorn)
i'm quite ignorant about the graalvm space so forgive me if this is a stupid question, but is it conceptually possible to build a Clojure based graalvm native image which embeds the graaljs execution environment inside it as they have done in the example you linked, so you would end up with a native binary which runs cljs?
a friend of mine @retrogradeorbit is shipping really neat stuff with Clojure + GraalVM and I'm in awe of it (bootleg, spire)
but that comes at the code of not being dynamic anymore and clojure is cool because it is dynamic
yes tradeoffs
i guess there are situations where shipping a single binary to the end user is advantageous
if the end user doesn't know or care about nodejs
i know there is nexe too
I still see graalvm native-image in the same way as an :advanced
compiled CLJS build. highly optimized for one particular thing and not extensible at all π
@thheller How would you do you cli βconfig-merge
with a edn files? (Having a $(cat config.edn)
I guess?)
I recommend using the CLJ api whenever things go past a simple command line. https://shadow-cljs.github.io/docs/UsersGuide.html#clj-run
Hmmm... how do you modify the argument of your build then?
ad Clojurist Together, I would cast a selfish vote for Dirac support: https://github.com/thheller/shadow-cljs/issues/636
@darwin you can likely already do all of that. assuming that you are able to use websockets, no tcp or other remote method available yet
I'm getting this error when loading the page (latest version):
Exception in thread "async-dispatch-17" java.lang.IllegalArgumentException: No implementation of method: :close! of protocol: #'clojure.core.async.impl.protocols/Channel found for class: clojure.
lang.PersistentVector
at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:583)
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:575)
at clojure.core.async.impl.protocols$eval246$fn__247$G__235__252.invoke(protocols.clj:21)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:979)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:975)
at clojure.core.async$ioc_alts_BANG_$fn__3086.invoke(async.clj:385)
at clojure.core.async$do_alts$fn__3018$fn__3021.invoke(async.clj:254)
at clojure.core.async.impl.channels.ManyToManyChannel$fn__670.invoke(channels.clj:265)
at clojure.lang.AFn.run(AFn.java:22)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
I have a shadow-cljs question - I am using shadow-cljs with the self-hosted cljs repl, and I notice that because the CLOSURE_BASE_PATH is defined as a relative path, I get loading errors for source maps and things, depending on what URL I happen to be accessing via the embedded dev http server. Does this sound like a crazy configuration error on my part?
@thheller Yes ... I think I have it all fixed, using the :asset-path
as you suggested.
having an issue with a new project. Build keeps on failing.
Davids-MBP:~ Dave$ cd projects
Davids-MBP:projects Dave$ cd hone-master/
Davids-MBP:hone-master Dave$ shadow-cljs watch app
shadow-cljs - config: /Users/Dave/Projects/hone-master/shadow-cljs.edn cli version: 2.8.83 node: v13.12.0
shadow-cljs - starting via "clojure"
running: npm install --save [email protected] [email protected]
npm WARN saveError ENOENT: no such file or directory, open '/Users/Dave/package.json'
npm WARN enoent ENOENT: no such file or directory, open '/Users/Dave/package.json'
npm WARN Dave No description
npm WARN Dave No repository field.
npm WARN Dave No README data
npm WARN Dave No license field.
+ [email protected]
+ [email protected]
updated 2 packages and audited 2750 packages in 0.871s
found 3 low severity vulnerabilities
run `npm audit fix` to fix them, or `npm audit` for details
[2020-04-07 12:02:51.476 - WARNING] :shadow.cljs.devtools.server.nrepl04/middleware-fail - {:sym refactor-nrepl.middleware/wrap-refactor}
FileNotFoundException Could not locate refactor_nrepl/middleware__init.class, refactor_nrepl/middleware.clj or refactor_nrepl/middleware.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
clojure.lang.RT.load (RT.java:462)
clojure.lang.RT.load (RT.java:424)
clojure.core/load/fn--6839 (core.clj:6126)
clojure.core/load (core.clj:6125)
clojure.core/load (core.clj:6109)
clojure.core/load-one (core.clj:5908)
clojure.core/load-one (core.clj:5903)
clojure.core/load-lib/fn--6780 (core.clj:5948)
clojure.core/load-lib (core.clj:5947)
clojure.core/load-lib (core.clj:5928)
clojure.core/apply (core.clj:667)
clojure.core/load-libs (core.clj:5985)
shadow-cljs - HTTP server available at
shadow-cljs - server version: 2.8.40 running at
shadow-cljs - nREPL server started on port 49842
shadow-cljs - watching build :app
[:app] Configuring build.
[:app] Compiling ...
[:app] Build failure:
The required namespace "react" is not available, it was required by "reagent/core.cljs".
The namespace was provided via :foreign-libs which is not supported.
Please refer to for more information.
You may just need to run:
npm install react
ok i tried that and then ran shadow-cljs watch app
again and got a different error
NPM dependency "react" has installed version "^16.13.1"
"16.9.0" was required by jar:file:/Users/Dave/.m2/repository/reagent/reagent/0.9.1/reagent-0.9.1.jar!/deps.cljs
NPM dependency "react-dom" has installed version "^16.13.1"
"16.9.0" was required by jar:file:/Users/Dave/.m2/repository/reagent/reagent/0.9.1/reagent-0.9.1.jar!/deps.cljs
[2020-04-07 12:51:04.188 - WARNING] :shadow.cljs.devtools.server.nrepl04/middleware-fail - {:sym refactor-nrepl.middleware/wrap-refactor}
FileNotFoundException Could not locate refactor_nrepl/middleware__init.class, refactor_nrepl/middleware.clj or refactor_nrepl/middleware.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
the print out was very long but that seems to be the meat and potatoes@dgonsalves22 looks like you have configured to use the refactor-nrepl middleware but did not add it do the classpath
Is it possible to disable :`browser-inject` for a build? I have a web-worker module in a seperate build, and this worked until I upgraded today. Now it chokes because the generated script references window:
(js/window.addEventListener "beforeunload"
(fn []
(when-let [s @socket-ref]
(.close s))))
the recommended setup is using :modules
. see https://shadow-cljs.github.io/docs/UsersGuide.html#_web_workers
Is inspect intended to be used with a value that can change over time? Does this require tapping it continuously, or should once be enough?
I'm trying this:
(tap> #'re-frame.db/app-db)
with this Datafiable
protocol extension:
(ns foo.utilities.debug
(:require [clojure.core.protocols :as p]
[reagent.ratom]
[shadow.remote.runtime.cljs.browser]))
(extend-type reagent.ratom/RAtom
p/Datafiable
(datafy [x]
@x))
Hmm I think I'm mistaken, looks like the deref is happening more than once (I added a print)
but the point of datafy is to get data, so not something that changes over time π
i removed the middleware and now I get
{:type java.lang.IllegalArgumentException
:message "Cannot open <nil> as a Reader."
:at [$fn__11520 invokeStatic "io.clj" 288]}
when I run shadow-cljs watch app
i mean there is a lot more I just wanted to avoid putting the whole thing in here because it would be very long
Also, thanks for the help @thheller and @lilactown