Fork me on GitHub
#shadow-cljs
<
2023-12-11
>
danielneal10:12:10

If I would like a macro to do one thing for a shadow-cljs release, and another at dev time, what can I switch on? I’m guessing goog-define will only be accessible in the cljs, rather than the clj.

thheller11:12:37

you can check (:shadow.build/mode &env). it'll be :release for release builds and :dev otherwise

thheller11:12:53

so (= :release (:shadow.build/mode &env)) in that if

danielneal12:12:17

Awesome! Thanks 🙂

danielneal10:12:38

(defmacro embed-image [image-path]
  (if release-build? ;; *** How to define release-build?***
    (let [image-bytes (io/file image-path)
          base64-str (-> image-bytes
                         io/input-stream
                         IOUtils/toByteArray
                         Base64/getEncoder
                         (.encodeToString))]
      (str "data:image/png;base64," base64-str))
    image-path))

Ellis19:12:40

We use :closure-defines like

:builds {:app {:dev {:closure-defines {goog.DEBUG true app.frontend.config/dev? true}}}}
and in app.frontend.config (goog-define dev? false)

danielneal19:12:56

@U043RSZ25HQ I think this only works for the cljs bit, I needed access at clj/macro expansion time. But Thomas already answered. Thanks for your help!

mikerod19:12:37

The :none optimized dev JS output from shadow is including this final line of:

SHADOW_ENV.evalLoad("shadow.module.main.append.js", false , "\nshadow.cljs.devtools.client.env.module_loaded(\x27main\x27);\n\ntry { my.app.here.client.app.main(); } catch (e) { console.error(\x22An error occurred when calling ()\x22); throw(e); }");
Where my.app.client.app.main() is my main exported fn that initializes the app. My “index page” also has a call to this same my.app.client.app.main() in it - which I’d think would be normal. The end result is that my init page is getting “double initialized” when navigating to the page the first time. This is problematic. What is the purpose of this SHADOW_ENV.evalLoad call?

thheller19:12:02

evalLoad has absolutely nothing to do with it, evalload exists for this purpose https://clojureverse.org/t/improving-initial-load-time-for-browser-builds-during-development/2518, link is old and everything described has been default for many years. but the idea is still the same

thheller19:12:25

:init-fn in your build config is controlling this, basically it calls that function when the script is loaded

thheller19:12:39

thus making the init call in the HTML redundant and should be removed

thheller19:12:09

if you instead wish to keep it in the HTML, you remove :init-fn and replace it with :entries [the.ns-that-had-init]

mikerod19:12:39

Ah yes, I had an :init-fn. Sorry I was trying to use console.trace() to figure out what was causing the “double call” and misdiagnosed.

mikerod19:12:56

I’d rather have my HTML call this to stick with what we have.

mikerod19:12:27

How can I make my modules entry without an init?

:modules {:main {:init-fn my.app.here/main}}
Do I need something here at all?

mikerod19:12:11

Oh, I think I can figure it out. Reaidng docs

mikerod19:12:37

Fixed it. Thanks!

mikerod22:12:35

I cannot find this in the doc or online q&a that I’ve seen. Does shadow-cljs support hot reloading of clojure file changes? Similar to https://figwheel.org/docs/hot_reloading.html section “Reloading Clojure code”

thheller22:12:02

only macro files are reloaded, besides that no

mikerod22:12:25

Hmm. That may be problematic for me trying to transition from fig main to shadow. I’d have to think about how to deal with that.

thheller22:12:33

didn't know there was such an option in figwheel, never seen that before

mikerod22:12:33

As a progress report though I guess. I have got a large cljs project that uses webpack with :bundle target and figwheel-main traditionally to have a working repl with shadow-cljs now. I kept using webpack (via :js-provider :external + some hooks) for now to ease the transition and test things. I think I have noticed consistently faster hot reloading for cljs at least. This was a main area of interest I had trying this. I haven’t explored releasing advanced output etc yet though. So I’d still have lots to do to really transition.

thheller22:12:45

could be easy to replicate I guess, never thought about it

mikerod22:12:10

Yeah, I just have gotten so used to figwheel doing it, I never considered not having it.

mikerod22:12:06

I also work on clj-only projects though, and I don’t typically use any hot reloading watcher stuff for those. Funny enough.

thheller22:12:33

feel free to open an issue. too tired to think about it now

mikerod22:12:05

Sure thing. Thanks for the quick feedback either way.

thheller22:12:06

> Figwheel does have limited support for recompiling ClojureScript files which depend on Clojure files. It will only recompile and reload ClojureScript files which are direct dependents of a changed Clojure file.

thheller22:12:13

I mean that makes it sounds like what shadow-cljs does?

thheller22:12:31

ie. loading .clj files that are relevant to the cLJS build

mikerod22:12:34

figwheel will reload if I chaange a clj-only file (only used on jvm-side)

thheller22:12:47

off to bed, gn8

mikerod22:12:59

Bye for now