I have an existing clj/cljs project that is based on Leiningen and uses Figwheel. I would like to try out Shadow CLJS. So basically add it to my project.
I’m trying to follow the guide at https://shadow-cljs.github.io/docs/UsersGuide.html but I don’t think that I am quite getting it. It is recommended to use a “standalone” Shadow version and not integrate with Lein. How do I do that (follow the recommendation) when I have an existing Lein project? Or do I need to integrate with Lein?
You’ll need a shadow-cljs.edn and configure your build there. Once thats done you can use shadow-cljs.edn to manage your dependencies or continue doing so via project.clj. It is fine to use lein for server-side CLJ stuff and shadow-cljs.edn for CLJS related things. I do that in all my projects but some people prefer to have everything in project.clj.
You might get a better feeling for how shadow-cljs works by following the quickstart and setting up a little dummy project.
I get hundreds of warnings that the Chrome devtools cannot load map-files, e.g., DevTools failed to load SourceMap: Could not load content for https://dev.bass4.com/assets/public/js/cljs-runtime/re_com.misc.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE.
I’m running the app behind a reverse proxy, could that be it?
The user guide says that “If the popular middleware cider-nrepl is found on the classpath (e.g. it’s included in :dependencies), it will be used automatically.” cider-nrepl was included as a lein plugin (from the figwheel config) so I kept it there, does that mean that it is used by shadow-cljs? How can I check that it is running? What does cider-nrepl do? (please excuse my ignorance!)
This is because your :asset-path in the config looks incorrect. That should match the path you use to access the .js files from the HTML. Dunno where the /assets comes from but the public is most definitely wrong. Maybe just :asset-path "/js"?
It is only relevant if you use emacs. The middleware provides stuff like code completion, documentation lookups, etc.
Ah yes. I removed all cider-nrepl and piggieback stuff and I am able to connect to the nREPL from Cursive.
Coming from Leiningen I’m used to using profiles to include different dependencies in dev and production builds and also to have an “env” folder where profile dependent namespaces are included. For instance, I only want to use Orchestra in development to instrument all speced functions. So orchestra is included as a dependency in the Leiningen dev profile and I call Orchestra’s instrument function in a namespace that is in the env/dev folder. The corresponding namespace in the env/prod folder does not require the orchestra namespace.
Is it possible to achieve the same effect using Shadow CLJS? Note that I am using Leiningen for my dependency management.
In shadow-cljs by default all builds only include what they actually require. See this post. This means that the dev/prod separated :source-paths are usually pointless and thus not supported.
As far as instrument is concerned I would recommend creating a single ns that does this and including it via :preloads into the build. That will ensure its only active during development.
Thanks! I tried it out and it sort of works. Problem is that instrument needs to run after all other namespaces have been loaded so that the functions have been speced. Or am I missing something?
:preloads by definition are loaded first but they still follow :require rules. So just simply require your main app namespace in that ns and you should be good. If not just :require the problematic namespaces as well.
It works, but only if I include [thheller/shadow-cljs "2.11.7"]among my regular lein dependencies. If I include Shadow CLJS in my dev dependencies, lein uberjar fails with Can't find 'shadow.cljs.devtools.cli' as .class or .clj for lein run:
Problem is, that including Shadow CLJS among my regular dependencies adds >40 MB to my uberjar file. I assume that none of that code is really needed?
Can I somehow let uberjar :prep-tasks access Shadow CLJS without including it as a dependency that is included in the uberjar?
Oh yeah, sorry! I looked at your source, and it looks like that would also compile Shadow CLJS into the uberjar. The alias looks very much like the :prep-tasks that I tried above.