Fork me on GitHub

I’m not sure if this is some common question, but I searched the channel and wasn’t able to find anything. I’m using nREPL with IntelliJ IDEA, and every time after I connect to the nREPL instance I have to manually execute:

(shadow/repl :dev-android)
(ns cljs.user)
I’m wondering if this can be automated somehow?


it cannot. well I suppose you can create a keybinding for it via custom repl commands


the (ns cljs.user) you don't really need though?


without this one, I can’t execute things like (def some-binding "some stuff") - REPL assumes cljs.user namespace which doesn’t exist


cljs.user always exists by default?


well, somehow - in this particular case - it doesn’t


did you set :repl-init-ns in your build config?


also which shadow-cljs version? there were a few where this didn't exist until a user connected, maybe you are on one of those?


nope, let me try that. 2.18.0


Connecting to remote nREPL server...
Clojure 1.10.3
(shadow/repl :dev-android)
To quit, type: :cljs/quit
=> [:selected :dev-android]
(def test-var "something")

Execution error (TypeError) at (<cljs repl>:1).
undefined is not an object (evaluating 'cljs.user.test_var = "something"')
=> :repl/exception!
(ns cljs.user)
=> nil
(def test-var "something")
=> #'cljs.user/test-var
That didn’t help. Anyway - that’s not a big deal, just a minor inconvenience, probably related to my setup.


ah react-native. yeah some people have reported strange behavior there. can't verify since I can't get react-native running anymore


yeah, RN setup. ok, I’ll just keep typing stuff and probably assign shortcuts 🙂


Not sure if it could be solved with shadow. How can I retain the line number where the error occurs?


thats react-native. it is displaying this stacktrace. dunno why the tracktrace is incomplete


Hi, I am trying to understand some behaviour. If I refer: ["mui-address-autocomplete" :default AddressAutocomplete] the build takes 5-8s [:web] Build completed. (12803 files, 2 compiled, 0 warnings, 7.42s) Removing the refer: [:web] Build completed. (1684 files, 2 compiled, 0 warnings, 0.90s) The lib is: "mui-address-autocomplete": "^2.0.4". Any hints?


@danbunea 12803 files vs 1684 files explains the time difference? recompile will be faster. the files are included because I guess thats all the transitive deps of the mui-address-complete?


If I use --config-merge {:cache-root ".some-other-location"} and .some-other-location does not exist yet, a new shadow-cljs server instance will be started, right? Is there a better way to make sure that it's a new server instance and not an existing one? Just encountered an issue where modifying a CLJ file haven't changed the code that shadow-cljs run executes. Took me a while to realize that I had a watch running.


config merge only merges build configs. cache root is not a build setting and as such does not have any effect


Ah, right. But is there a way to always start a new server for some particular command?


just don't run it via shadow-cljs for one


or use the --force-spawn there


can't think of a reason why you'd do any that though?


Having a single server instance per project limits your development capabilities because you have to think whether you need to reload something via shadow-cljs' REPL or restart the server or whether just running it will be enough. I'd much rather have each separate CLI command just do its own thing, in isolation, without touching any global runtime.


> just don't run it via shadow-cljs for one Well, I use shadow.cljs.devtools.api in that script, and sounds like running it via just clj would make it more work for me, with manual start of a server instance.


> whether you need to reload something via shadow-cljs' REPL or restart the server


oh wait you were building a thing that was embedding shadow-cljs for something right?


So, I have a watch running somewhere in the background, and the same command has started a shadow-cljs server instance. Now that instance has loaded all the relevant CLJ files and all the dependencies. Fast forward a few hours, I'm about to cut a new release of the app. It requires a bunch of things and I run them all via a single call to shadow-cljs run. But my previous work has changed the release script a bit, and has added a new dependency specifically for that part. So, not thinking about it, I execute shadow-cljs run and... bad stuff happens. Old behavior, before the changes above. It was rather tedious to debug because I started to think that I had maybe a compiled and outdated class somewhere, or a copy of the script somehow. Took me a bit to realize that shadow-cljs server was running in the background.


> oh wait you were building a thing that was embedding shadow-cljs for something right? Not anymore, no. Well, apart from that piece of code that creates shadow-cljs config so I can figure out some run time parameters to feed them to other scripts.


Sounds like --force-spawn is just what I need though, as I could use it just for that release script. Still, makes me think that I myself would probably prefer an explicit flag that did the reverse. I.e. the default behavior for shadow-cljs would be to start a new server instance each time, and some flag would make it reuse some specific instance. But that's just me - I barely use that "connect to existing instance" feature.


I mean I would probably recommend just using clj or lein for stuff like this?


unless this "release" task is really only doing CLJS related things


if it does something else too a more generic runner might make sense


But that would make me have to explicitly start shadow-cljs server, no? Given that I use shadow.cljs.devtools.api/release in that very script or watch in other places of that script.


Yeah, release/watch/test - they all have a bunch of non-CLJS steps that are nonetheless tied to either CLJS or something shadow-cljs-related. To be specific, I need to generate some JS code from ANTLR4 grammar before running shadow-cljs. And I need to run sass there as well, and some other CSS-related things.


release doesn't require a server instance and doesn't start one


But it definitely uses an existing one! :)


> But that would make me have to explicitly start shadow-cljs server, no?


or I'm confused what you are talking about. server is only a thing because of watch basically. if that didn't exist there would be no server mode.


Right, then it would mean that for watch I'd have to use shadow-cljs run and for release I'd have to use clj. Ehh, I'd rather just pass --force-spawn to the release CLI command.


it is still useful for most other tasks but still


that is fine. just saying that you shouldn't start another server if a server is already running


so whatever you do in the run don't start a server if you use --force-spawn


Right, makes sense. I'm not starting a server manually anywhere. There's {:shadow/requires-server true} in a couple of places, but not around the release-related code.


well that would start a server if you run that via run


how are you running sass?


have you tried a setup using npm-run-all?


I'm finding that very convenient


pretty much my standard setup these days


As I mentioned - I have a lot of things other than just sass, and I can't run them all independently via npm run. There's a dependency graph, and right now it's expressed explicitly in the code:



But starting another server is not that huge of a deal, right? It seems to take roughly 4 seconds on my end - I don't care about that amount of extra time when it's just for cutting a release.


you are confusing me by saying server


call it a JVM


if you only run release related tasks then you only start a new JVM


starting a new JVM takes time yes


Oh, so if I run shadow-cljs without --force-spawn where there's another instance running somewhere, it will skip starting not just a shadow-cljs server instance specifically, but a whole JVM?


yes, thats the whole point


starting shadow-cljs itself is cheap and fast. getting the JVM up and running is the slow part


like 90% of the time is spent loading namespaces and stuff


In that case, I had a wrong mental picture. I thought it was slow to start the shadow-cljs server instance for some reason, and that two JVM instances would communicate with each other to reuse a single running shadow-cljs server instance.


no. the shadow-cljs CLI script is written in CLJS and only runs node. that part talks to the server instance over tcp when present


or starts a JVM if not


Yeah, now the whole thing is getting much clearer. :) I used to be confused about a few things in shadow-cljs code base, specifically the CLI part being written in CLJS. Thanks!