https://clojurians.slack.com/archives/C5K1SHR6X/p1768930579542659
sorry, can't help with anything duct related. no clue how it works.
Debugger and console output brings us to this file. /devtools/client/shared.cljs
yeah I can explain this error. you seem to have a :server build (in shadow-cljs.edn). you once started a watch for that. the output still lives and gets loaded in the browser. it tries to connect to the server for hot-reload/repl, but the watch is no longer running.
Well spotted!
Apologies for the noise - I should really fork shadow-cljs and remove the logs that direct people here. Duct tries to use shadow-cljs as a library for compiling/hot-loading CLJS, but shadow-cljs is designed as a command-line tool and doesn't do well when taken out of its natural environment. I've been resisting forking shadow-cljs into a "library friendly" version that pulls out the CLI stuff - largely because that sounds like a lot of work! - but it might be time for me to bite the bullet.
I wouldn't really say its designed as a command line tool, given that I never use it like that myself 😛
Oh, I mean in terms of that it expects configuration to come from a particular file, for hot-reloading to occur via a file-system watcher, things like that. I found it hard to use if I wanted to supply a configuration directly, or if I wanted to control reloading. shadow-cljs seems to have been designed as a tool first, rather than as a library with a tool sitting on top, if that makes sense.
Which is fine, of course. It's designed for a particular use-case and I'm trying to use it in a way it wasn't designed to be.
yes, that is true. it is designed to be a tool. an embeddable one, but nonetheless not customizable in the things you mentioned
I mean technically all that is possible, just has no official API
Yeah, and I've delved into the code, but there's a lot of hard-coded stuff around what it expects that make it difficult to use in that way. Hence my thought to try and and separate out the "tool" parts from the "library" parts.
And trying to use the shadow-cljs in that way also sometimes produces error/warning messages with "shadow-cljs" in, which means people bother you and not me when things go wrong. Something I'd like to fix! 🙂
why separate it out though? I mean what is lacking with what it already does? Isn't it less work for you to just use what is there and be able to just follow what everyone else is doing? including all the existing docs and examples?
only to save a 10 line shadow-cljs.edn file? (or whatever the goal is)
There are a few main reasons: a general one and a couple of more specific ones.
The broadest reason is that tools in Clojure tend to exist on top of libraries with well defined APIs, which allows them to be used more flexibly than if they were tools alone, and aligns with Rich's ideas about simplicity. To give an example, Kaocha uses its own configuration file like shadow-cljs, but also has a kaocha.api namespace that makes it very pleasant to integrate with. This recently allowed me to write more complex and unusual test setups than would be possible with the tool alone.
The first more specific reason is that I want to ensure that when a Duct application is reset (i.e. reloaded/refreshed), the client-side and server-side are reset at the same time. This keeps both sides of the application in sync. I also want control over when a reset happens: I don't want to reset when I'm in the middle of changing several files. Having a file watcher compile the ClojureScript separately every time I save a file works against my development process.
The final reason is that Duct has "modules" which are ways of "expanding" a small, general configuration into a larger, more specific one, while still allowing the user to override specific parts of the expansion. For example, the ClojureScript module in Duct sets up shadow-cljs according to the environment, and also adds in a static file handler to serve the assets that shadow-cljs makes. Using a separate file for shadow-cljs configuration means I can't benefit from Duct's more sophisticated configuration management.
there is a :autobuild false option so that the file watch doesn't trigger an automatic compile. and then there is an api method to actually trigger it (shadow.cljs.devtools.api/watch-compile! :the-build)
That's actually what I https://github.com/duct-framework/compiler.cljs.shadow/blob/37f6568cf60c26d1dc405e18571c46f5e1bc5709/src/duct/compiler/cljs/shadow.clj#L51, though the warning console message still pops up.
which warning?
the server not running? assuming this :server is the actual config and that it is running I'd suspect this to be a cache issue
your http server may serve the old files, or rather tell the browser it can continue to use them
or things are loaded out of order and the watch isn't actually running by the time the JS is loaded
The warning about the watch server not running. I haven't had time to investigate the issue in detail - as far as I can tell the reloading all works - it compiles the files and hot-reloads them when triggered. Because of that I haven't bothered looking into why the warning message pops up.
still had the code open you linked yesterday. just noticed that there seems to be an extra config here https://github.com/duct-framework/compiler.cljs.shadow/blob/37f6568cf60c26d1dc405e18571c46f5e1bc5709/src/duct/compiler/cljs/shadow.clj#L28