Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

clojure - How to properly setup shadow-cljs for hot reload?

I've been trying to get shadow-cljs hot reload to work but I haven't been able to, I've tried multiple settings in my project.clj file but none have worked. This is what my project.clj looks like:

:shadow-cljs {:nrepl {:port 8777}
                
                :builds {:app {:target :browser
                               :output-dir "resources/public/js/compiled"
                               :asset-path "/js/compiled"
                               :modules {:app {:init-fn my-app.core/init
                                               :preloads [devtools.preload]}}

                               :devtools {:http-root "resources/public"
                                          :http-port 8080
                                          :http-handler my-app.handler/dev-handler
                                          }}}}

:aliases {"watch"        ["with-profile" "dev" "do"
                          ["shadow" "watch" "app"]]}

:profiles
  {:dev
   {:dependencies [[binaryage/devtools "1.0.2"]]
    :source-paths ["dev"]} ;; <- this is the default from the template pointing to "dev", I've tried chaning it multiple times.
  }

When I run lein watch I understand that it's just running shadow-cljs watch app which should run my "app" build. This is what my dev-handler looks like (referenced in :http-handler):

(def dev-handler (-> api-routes
                     wrap-params
                     wrap-json-response
                     wrap-keyword-params
                     wrap-json-params
                     wrap-multipart-params
                     wrap-reload
                     (wrap-resource "public")
                     (utils/cors-wrapper utils/cors-policy)
                     (utils/wrap-content-type-security)
                     (wrap-defaults (assoc-in site-defaults [:security :anti-forgery] false))))

I've tried changing the source-paths in my :dev profile to ["src"] and even tried including all inner folders as in ["src/clj" "src/cljs" "src/cljc"] with no success. I've even tried creating a new app from scratch with lein new re-frame making no changes whatsoever and running lein watch, code compiles and everything seems fine but whenever I change something in a cljs file (views.cljs for example) nothing is re-rendered/reloaded, I've gone to localhost:9630 which gives you a shadow-cljs dashboard listing your builds and clicked on the "force compile" button and see a clojurescript animation in my app's page but no re-rendering/reloading again. I notice that when shadow-cljs finishes compiling, there are 0 files compiled, is it getting the source-paths config from somewhere else? This is what it looks like when I'm trying to test it out:

enter image description here

EDIT: Maybe it's worth saying that I'm running ubuntu with xfce terminal and emacs from WSL2 within MobaXterm, could it have something to do with the code/app not hot reloading?

question from:https://stackoverflow.com/questions/65907176/how-to-properly-setup-shadow-cljs-for-hot-reload

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Everything seems to be running smoothly and as intended. It might be that the only thing you are missing is a lifecycle callback to trigger the actual re-render of your page.

See https://shadow-cljs.github.io/docs/UsersGuide.html#_hot_code_reload

In most re-frame/reagent apps that would be the function that calls reagent.dom/render (or reagent.core in case you are on old version).

I also wrote more about how this all works here.

... is it getting the source-paths config from somewhere else?

shadow-cljs looks at the JVM classpath however that is constructed on startup. You appear to be using lein so only project.clj will matter here and the classpath is constructed by adding all :source-paths, :resource-paths and so on. So if you have :source-paths ["src/clj" "src/cljs" "src/cljc"] that will be enough for it to be picked up, assuming of course the source files you are working with are actually in those dirs.

Can't comment on your setup otherwise. I used it fine with WSL2 but there are known issues if running inside containers (eg. docker) so I wouldn't rule out something being funky here that prevents shadow-cljs from actually "watching" the files.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...