I have a dependency from x.cljs -> y.clj (using a macro that builds a data structure) -> z.clj (in a separate library, included via a lein checkout). Shadow-cljs doesn't recompile when I modify z.clj, so I don't get hot reload for changes to z.clj – in fact I need to restart shadow-cljs for the changes in z.clj to be reflected in x.cljs. Is there some trick I can use to get hot reload here?
FWIW the code in y.clj is basically
(def route-data
(set (map (fn [] ...) z/all-routes)))
(defmacro make-href
"Variant of make-href* that tries to validate the route at compile time."
[route]
(if-let [kw (if (keyword? route)
route
(as-> (:route route) $ (when (keyword? $) $)))]
(if (contains? route-ks kw)
`(make-href* ~route)
(-> (str "Failed to build href for route: " (fmt/ppr-inline route)
"\nDefined routes: " (fmt/ppr-inline route-ks))
(ex-info {})
throw))
`(make-href* ~route)))CLJ reloading is limited, so I'd recommend something like clj-reload to get something that is more optimized for CLJ
or you can always just edit the file and reload it from the REPL directly
but it still has limits in how far shadow-cljs follows CLJ dependency graphs
cool, thanks
I didn't know about clj-reload; here I am still using tools.namespace like a caveman
Wondering if some one can help, I am stuck with a stale build error which I can't figure out the cause of I am running
clj -M:cljs:cljs-dev:portfolio:shadow-run watch portfolio
shadow-cljs - HTTP server available at
shadow-cljs - server version: 2.28.20 running at
shadow-cljs - nREPL server started on port 40763
shadow-cljs - watching build :portfolio
[:portfolio] Configuring build.
[:portfolio] Compiling ...
[:portfolio] Build completed. (852 files, 0 compiled, 0 warnings, 7.40s)
Which seems to work modifying and saving triggers a rebuild, I have this shadow config
{:deps {:aliases [:cljs]}
:jvm-opts ["-Xms1g" "-Xmx1g" "-XX:+UseG1GC"]
:dev-http {8090 ["projects/frontend-web/resources/public/" "classpath:public" "components/"]}
:nrepl {:middleware [refactor-nrepl.middleware/wrap-refactor]}
:builds {:app {:output-dir "projects/frontend-web/resources/public/cljs-out"
;:asset-path "projects/frontend-web/resources/public/"
:target :browser
:compiler-options {:infer-externs :auto :output-feature-set :es6}
:modules {:base {:entries []}
:main {:init-fn com.app.example-web.dev/launch
:depends-on #{:base}}
:portfolio {:init-fn com.app.portfolio-components.core/launch
:depends-on #{:base}}}
:devtools {:after-load app.main/reload!}}
:worker {:output-dir "projects/frontend-web-worker/resources/public/js-worker"
:asset-path "js-worker"
:target :browser
:compiler-options {:infer-externs :auto :output-feature-set :es6}
:modules {:web-worker {
:init-fn com.app.web-worker.core/init-worker
:web-worker true}}
:devtools {:after-load app.main/reload!}}
:portfolio {:output-dir "projects/frontend-web/resources/public/cljs-out/"
:asset-path "."
:target :browser
:compiler-options {:infer-externs :auto :output-feature-set :es6}
:modules {:main {:init-fn com.app.portfolio-components.core/launch}}
:devtools {:after-load app.main/reload!}}}}
What is the mechanism that makes shadow reload the app ? feel free to point me at documentation that explains this
reloading the browser shows any code changes but shadow is not doing its hotreload magic and always shows the build as stale what ever I change so just trying to debug what stale build actually means.that error usually means that there is a "competing" shadow-cljs instance. could be that its running twice? maybe in a second terminal or so?
or it could be an old file you are actually loading because of some old references. did you maybe change the :output-dir or :modules config recently?
make sure your html is loading the files this is actually generating, so the cljs-out/base.js and cljs-out/main.js files
dunno why there is a :portfolio module in the :app build when there is an extra :portfolio separate build? seems like that isn't needed?
also why are you downgrading to :output-feature-set :es6? you really target 2015 browsers?
:infer-externs :auto is the default and does not need to be set
seems like this config for :app would suffice
{:output-dir "projects/frontend-web/resources/public/cljs-out"
:asset-path "/cljs-out"
:target :browser
:modules {:main {:init-fn com.app.example-web.dev/launch}}
:devtools {:after-load app.main/reload!}}Thanks for these suggestions, I know I do not have another instance of shadow running. So I will try the other suggestions, also if you just watch without connecting any idea I would expect it would not be stale, not at a machine to test but will let you know, if nothing else may help others or myself when searching :)
what you need to verify is that the .js files you are loading are produced by the actual shadow-cljs
so best is to shut down shadow-cljs, delete all generated files and start, verifying that the files you deleted actually get generated and that there are no duplicates in other folders
could also just be browser cache is thats not setup properly, but :dev-http usually does that by default
if a service-worker is involved that might different
Awesome think I understand now, its where I have changed things over time I think I started of having portfolio as a separate build, then realized I could use the modules to code split to make the app and portfolio run at the same time by having index.html and portfolio.html and loading the relevant js files in each. I have not worked on the project for a while and come back to it and forgot that, you are correct though removing the cljs-out folder cleared up everything then I could see that portfolio.js was not created but main.js was which is whats specified in the :portfolio build where as :app generates base.js main.js and portfolio.js. Thanks so much @thheller I will make the other changes as well, most likely it me copying and pasting on some of the settings from known working configs.
I recommend leaving portfolio stuff out of the main build. it'll just get you in trouble for production builds.
npx shadow-cljs watch app portfolio can just build 2 builds in parallel, so multiple builds is no issue
that's awesome it had never occurred to me I could chain them