Fork me on GitHub
Braden Shepherdson00:02:06

I'm wrestling with how to handle cross-platform macros with dependencies. in particular I want to write log, warn, fatal etc. from in a CLJS-friendly way. on JVM, using itself, and on CLJS using glogi. • I tried just using a CLJC namespace first, but that doesn't work because when the CLJS compiler loads the Clojure side to get the macros, it tries to require, which isn't in the CLJS deps. • I tried splitting the namespace into CLJS and CLJ flavours with the same name; same problem. • I tried putting actual functions, no macros, into an impl.cljc, and depending on it from a log.clj with the macros + log.cljs with :refer-macros. that still breaks, it's the same problem but transitive. • I tried using macrovich's case to hide a real-`:clj`-context-only (require ', but that doesn't work either, not sure why. it really feels like there's a correct way to do this out there, but I'm pretty stuck. any pointers?

Braden Shepherdson00:02:02

Yes, in a few permutations.

Braden Shepherdson00:02:41

It seems like that's arguing for just requiring c.t.l in both settings. It doesn't reach the compiled JS in any case.

Braden Shepherdson00:02:09

What I really want is more options in the reader conditional. :clj/macro vs. :clj/native


I think there's a way to tell if a clj macro is expanding cljs code, but I forget the magical incantation.

Braden Shepherdson00:02:59

The :ns &env hack, yeah. Macrovich/case uses that


I don't think it's possible to know at readtime, so I think it would require a macro


you would then have to wrap calls to functions to the c.t.l namespace with something like requiring-resolve or a delay

Braden Shepherdson00:02:10

Ooh, a delay might cut it. I'm away from my laptop right now, but that feels like it's worth trying.


ok, figured I'd ask in here since the slack looks a lot more active than the discord... I'm using cljs-http as seen in the attached images, but getting the following error at build time:

[:app] Configuring build.
[:app] Compiling ...
[:app] Build failure:
The required namespace "cljs-http.client" is not available, it was required by "reagent_test/ncbi.cljs".

Sam Ritchie23:02:38

I think the keyword in deps.edn should be :deps

Sam Ritchie23:02:59

(Or are they both allowed?)

Sam Ritchie23:02:34

I’ve always used :paths and :deps


That looks like a part of a profile in project.clj and not deps.edn. @U04MNATSXJN Are you sure that profile is active at build time?


it's in shadow-cljs.edn


Ah, then you probably have a shadow-cljs server running somewhere in that project's directory that had been started before you've added the cljs-http dependency. I think that even if you manage your dependencies with shadow-cljs.edn, you still have to restart the server to take their changes into account.


I have

{:dependencies [[cljs-http "0.1.46"]]}
in shadow-cljs.edn and then i'm running
❯ npx shadow-cljs browser-repl
shadow-cljs - config: /private/tmp/shadow/shadow-cljs.edn
[2023-02-04 17:34:15.767 - WARNING] TCP Port 9630 in use.
shadow-cljs - server version: 2.20.20 running at 
shadow-cljs - nREPL server started on port 57508
[:browser-repl] Configuring build.
[:browser-repl] Compiling ...
[:browser-repl] Build completed. (121 files, 0 compiled, 0 warnings, 2.16s)
cljs.user=> (require '[cljs-http.client :as http])

cljs.user=> (dir http)


i think the shadow-cljs server still running and not restarted is a great hypothesis


I found a java process containing cljs with htop, killed that


I also ended up having to nuke .shadow-cljs


works now, thanks for the help guys 👍


that second part is surprising.


yeah it was giving me a socket connection error:

shadow-cljs - socket connect failed, server process dead?


looked it up and the top stackoverflow post said to just clear whatever's cached in .shadow-cljs


welp that took an embarrassingly long time 🤡

Sam Ritchie23:02:36

Join the club ;) we’ve all been there

❤️ 2

how are you starting shadow?


i have yarn dev bound to shadow-cljs watch app


ah. that may make it hard to actually kill the shadow server depending on how yarn dev spawns its other process. might be worth having npx shadow-cljs server in a dedicated terminal. Then you can be sure you've killed the server and not have to find the process like this again


shadow will start up a server from the first process that needs it and then others will reuse that server. so if you start one in a dedicated terminal, the watch command from yarn dev will use that server and it will be faster each time it doesn't have to restart a server


I see, that's good advice


wonder if there's a way to keep the binding without spawning the server in the background deep_thinking


bc I usually prefer to use yarn scripts and not have to think about how the sausage is made (vite, rollup, tsc, etc)


With CIDER you can M-x cider-jack-in-cljs and automagically start and stop shadow-cljs server. This is what I typically do. I only have NPM scripts set up for compiling release builds of the app


> wonder if there's a way to keep the binding without spawning the server in the background Not sure what "binding" here means, but you can make every command start its own JVM (and, correspondingly, a shadow-cljs server process) by adding the --force-spawn flag. Pretty much all of these things are documented.