This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-12-15
Channels
- # adventofcode (80)
- # beginners (94)
- # biff (19)
- # cider (74)
- # clj-kondo (11)
- # cljs-dev (7)
- # clojure (110)
- # clojure-austin (3)
- # clojure-australia (1)
- # clojure-belgium (1)
- # clojure-china (1)
- # clojure-europe (83)
- # clojure-filipino (1)
- # clojure-hk (1)
- # clojure-indonesia (1)
- # clojure-japan (1)
- # clojure-korea (1)
- # clojure-my (1)
- # clojure-nl (1)
- # clojure-norway (4)
- # clojure-sg (1)
- # clojure-taiwan (1)
- # clojure-uk (2)
- # cursive (3)
- # data-science (8)
- # datalevin (8)
- # emacs (18)
- # etaoin (5)
- # graalvm (1)
- # holy-lambda (3)
- # honeysql (1)
- # jackdaw (10)
- # java (10)
- # jobs (3)
- # luminus (9)
- # malli (106)
- # off-topic (88)
- # polylith (8)
- # portal (2)
- # re-frame (50)
- # reagent (11)
- # reitit (74)
- # remote-jobs (1)
- # shadow-cljs (46)
- # tools-deps (26)
- # xtdb (49)
Hello 🙂
Initially, I had three different «subprojects» frontend
, backend
, domain
, each with their own deps.edn
. I just refactored everything into one project and it works fine if I spawn a REPL for the frontend (shadow) and a REPL for the backend.
However, as far as I understand, I should be able to spawn a single REPL for both now, with cider-jack-in-clj&cljs
.
This opens two windows that both seam to run shadow
:
1:
;; ClojureScript REPL type: shadow
;; ClojureScript REPL init form: (do (require '[shadow.cljs.devtools.api :as shadow]) (shadow/watch :app) (shadow/nrepl-select :app))
;;
2:
;;
;; ClojureScript REPL type: shadow
;;
I will put the Emacs messages in the thread.
Can someone help me understanding what I did wrong and how to fix it?This is the Emacs message I get:
[nREPL] Starting server via /opt/homebrew/bin/clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version "1.0.0"} cider/cider-nrepl {:mvn/version "0.28.7"} refactor-nrepl/refactor-nrepl {:mvn/version "3.6.0"} cider/piggieback {:mvn/version "0.5.2"}} :aliases {:cider/nrepl {:main-opts ["-m" "nrepl.cmdline" "--middleware" "[refactor-nrepl.middleware/wrap-refactor,cider.nrepl/cider-middleware,cider.piggieback/wrap-cljs-repl]"]}}}' -M:cider/nrepl
[nREPL] server started on 49951
[nREPL] Establishing direct connection to localhost:49951 ...
[nREPL] Direct connection to localhost:49951 established
[nREPL] Establishing direct connection to localhost:49951 ...
[nREPL] Direct connection to localhost:49951 established
Connected! Clojure isn't a language, it's a building material.
error in process filter: user-error: The shadow-cljs ClojureScript REPL is not available. Please check for details
error in process filter: The shadow-cljs ClojureScript REPL is not available. Please check for details
your understanding is half right and half wrong. cider-jack-in-clj&cljs
will attempt to use the same process to run two different repls.
Since you are using shadow you are using npx shadow-cljs …
for one process and presumably clj -A:…
for the backend process. You will need to continue to start both processes separately
That makes sense! Thanks.
What is the purpose of cider-jack-in-clj&cljs
then?
figwheel and figwheel main can be run from a regular clj
repl. shadow technically can as well but you have to do a bit more work. But the idea is that if a clj repl can become a cljs repl by just running something like (figwheel/run! <build>)
then you can just make two repls into the same process
shadow does it’s own startup from its own process. this brings many nice things to the table and thomas has made incredible software. But because it is a separate process, your cljs repl is in one process and the clojure repl in another. So the “trick” of clj&cljs
doesn’t work there
honestly, cider-jack-in-clj&cljs
usually brings more questions and headaches than the purported benefit. I’d be in favor of removing it
Thanks so much for the details. :man-bowing: The tooling around Clojure is a bit hard to navigate at times. But when it works it’s great. 🙂
https://clojurians.slack.com/archives/C099W16KZ/p1668002441531949?thread_ts=1667924045.274949&cid=C099W16KZ check this out.
Haha, that was already me asking the question back then. 😄
I am coming from non-lispy languages, so managing a REPL is new world. Writing code to handle «REPL specific» things is not intuitive to me yet. + Clojure + ClojureScript + Emacs + Shadow + … 🤯 So, when I read your suggestion, it’s not evident where/how this should be written or launched.
What I understand is that: I would need a file somewhere (cljs?), where I describe the shadow REPL to be created. Then, this would be the target of my shadow «entrypoint»?
Yeah. That’s why i’m not a fan of the clj&cljs
style. You don’t know where to go and what documentation to read to fix your issues. I added the startup command:
info at the top of repls to hopefully demystify how CIDER works
It’s not a hard requirement on my side at all. When I discover something new, I don’t want to reinvent the wheel. Conformism isn’t always bad. 🙂
because CIDER is just starting your repls the same way you would ever start a repl:
clojure -Sdeps '{cider/nrepl <cider-nrepl-dep>}' -M:your:aliases:cider/nrepl
. And it is just calling nrepl.cmdline
as the main and puts some middleware as an arg to nrepl.cmdline
Not sure I get everything you said, but thank you for taking the time. I don’t have a reason to spawn only one REPL besides potential environment simplicity, but to be honest the overhead makes the tradeoff not worth in my opinion. Two REPLs is perfectly fine. 🙂
Not a good writer myself.... Whenever you are ready to revisit this, just put the cider dependency in your dev
related lein profile/deps alias, and the clj code in your dev
startup code.
Now, I am having a funky problem. I run cider-jack-in-clj
, and I get a working REPL for my backend. Then, cider-jack-in-cljs
, and I get a working REPL for my frontend.
Everything looks right. But, when I navigate to a backend file (`.clj`), the buffer is not connected to the Clojure REPL anymore.
I navigate to the CLJ REPL buffer, it’s there. I navigate back to the .clj
file and it’s connected, but .cljs
files are not connected anymore. 🤯
CIDER has a bug that it considers itself connected to the last repl you had your point in. So visit the cljs buffer and then cljs files will see it is connected. for clj files, visit the clj repl and it will behave as you like
Ok! So, what do people do to work with projects that have Clojure and ClojureScript?
exactly what i just said. just have the clojure repl visible and the last repl you touched when doing backend, and similar when working in the frontend
If you use the infamous cider-jack-in-clj&cljs
then it works as expected and you don't have to select the clj or cljs repl first.
I think there are multiple issues for this already. I commented in one how I solved it with shadow: https://github.com/clojure-emacs/cider/issues/2946#issuecomment-768140666
So, if I constantly navigate between cljs and clj, I need to navigate to their respective REPLs in between?
I had the exact problem and asked the question. The solution was to use one shadow repl to support both clj and cljs repl, and use cider-connect-sibling-cljs
https://clojurians.slack.com/archives/C099W16KZ/p1667924263389159?thread_ts=1667924045.274949&cid=C099W16KZ
I am not using jack-in-clj&cljs
, I use jack-in-clj
and jack-in-cljs
.
> la boucle est bouclée
I meant if you use jack-in-clj
and separately jack-in-cljs
you hit that bug that cider gets confused about where to eval. So the solution is to use jack-in-clj&cljs
or connect-sibling..
Ok! So, I will experiment with your solutions to make shadow play nice with Cider.
Thank you all for your time and answers. 🙂
I will probably be back at some point with annoying questions. 🙂
I agree that it's definitely confusing working with shadow and tools.deps in the same session. This area could need a bit more love and documentation 😄
@UFAP0C8KU how to setup to use jack-in-clj&cljs
?
As I wrote in that github issue.
E.g. my current .dir-locals.el
for one of my projects contains this currently:
((clojure-mode . ((cider-clojure-cli-global-options . "-A:dev:cljs")
(cider-preferred-build-tool . clojure-cli)
(cider-custom-cljs-repl-init-form . "(do (require '[shadow.cljs.devtools.api :as shadow]) (require '[shadow.cljs.devtools.server :as server]) (server/start!) (shadow/watch :app) (shadow/nrepl-select :app))")
(cider-default-cljs-repl . custom))))
but then you also need to add shadow.cljs.devtools.server.nrepl/middleware
to your nrepl-middlewares
My Emacs config for this is here: https://github.com/dakra/dmacs/blob/ca8f80f411cb15d3ec9cfed445d5fde164be50b7/init.org?plain=1#L5718-L5723
I am not 100% clear on what the purpose of the :cljs
alias is.
Nothing. That's just an arbitrary deps.edn alias where I specify additional deps etc.
But as I always use :cljs alias for my cljs projects I use this to decide if I add the shadow nrepl middleware or not.
Yeah, that’s the other part that’s not 100% clear… 😄
cider-jack-in-nrepl-middlewares
is a variable that specifies what nrepl middlewares to inject in your session. And for shadow cljs to work it needs "shadow.cljs.devtools.server.nrepl/middleware" added
Ok, I am starting to piece things together now.
As far as I understand, this middleware will also be in your clj REPL. So, most likely it’s not breaking stuff.
(for this clj REPL)
yes, shadow itself runs also on the jvm. (afaik the npx shadowcljs command is just a wrapper around the java stuff)
I feel we are doing essentially the same thing. Difference is that your code goes to .emacs and mine goes to dev startup code.
Probably. I think jack-in-clj&cljs is just a shortcut for jack-in and connect-sibling?!
I am getting:
error in process sentinel: nrepl-server-sentinel: Could not start nREPL server: Execution error (FileNotFoundException) at nrepl.cmdline/require-and-resolve (cmdline.clj:220).
Could not locate shadow/cljs/devtools/server/nrepl__init.class, shadow/cljs/devtools/server/nrepl.clj or shadow/cljs/devtools/server/nrepl.cljc on classpath.
I am missing some dependency, but it’s not clear which.I added nrepl/nrepl
to both deps.edn
and shadow-cljs.edn
, but it does not change things.
you need the shadow-cljs dep as well. e.g. thheller/shadow-cljs {:mvn/version "2.20.14"}
Thanks! That was not very obvious. But now it looks like it’s working!
It’s alive! 👻
I am using re-frame’s 10x with preloads inside shadow-cljs.edn.
It’s used in my code, so the build actually fails.
Is it something I should add to the (do (require '[shadow.cljs.devtools.api :as shadow]) (shadow/watch :app) (shadow/nrepl-select :app))
?
I think you have to set more.. see my dir-locals from above. e.g. (cider-custom-cljs-repl-init-form . "(do (require '[shadow.cljs.devtools.api :as shadow]) (require '[shadow.cljs.devtools.server :as server]) (server/start!) (shadow/watch :app) (shadow/nrepl-select :app))")
and (cider-default-cljs-repl . custom)
Ah so. I’ll give it a shot. Thanks.
Yeah, that’s already what I had.
Probably this is not handling «preloads» from shadow, which are loading re-frame 10x.
boy, this is getting out of hands
[:app] Compiling ...
[:app] Build failure:
The required namespace "day8.re-frame-10x.preload" is not available.
I had dependencies in shadow-cljs.edn
and I think I need to move them all to deps.edn
now.
If you have all deps in deps.edn (like I have) then another gotcha might be that I had to explicitly specify guava dependency, otherwise shadow 2.20.11+ crashed for me. Took me also a while to figure out. So currently I have this for shadow in my deps.edn:
:cljs {:extra-deps {com.cognitect/transit-cljs {:mvn/version "0.8.280"}
day8.re-frame/http-fx-alpha {:mvn/version "0.0.2"}
day8.re-frame/tracing {:mvn/version "0.6.2"}
re-frame/re-frame {:mvn/version "1.3.0"}
thheller/shadow-cljs {:mvn/version "2.20.14"}
;; Maybe explicitly add deps for shadow.
;; For more info why this is needed
;; See
;; You can check what deps are needed on
;;
;; And maybe use
;; as a template and experiment what's missing/wrong.
;; Since 2.20.11 guava is not explicitly required by
;; shadowcljs anymore but apparently it's still needed
;; because it doesn't start without this pinned version.
com.google.guava/guava {:mvn/version "31.0.1-jre"}
}}
:cljs-dev {:extra-deps {binaryage/devtools {:mvn/version "1.0.6"}
com.lambdaisland/dom-types {:mvn/version "0.5.37"}
day8.re-frame/re-frame-10x {:mvn/version "1.5.0"}}}
Now I understand the cljs
namespace. 🙂
Thanks for this. I stumbled upon this new YouTube series of people showing their REPLs. Looks like a missing piece of the puzzle indeed.
Thank you so much for your time! Now everything works perfectly and I have a working setup!