shadow-cljs

김태희(taehee kim) 2025-08-07T05:47:10.240369Z

Can we provide build specific env for macros (.clj files) like closure-defines ?

김태희(taehee kim) 2025-08-07T05:52:06.687859Z

Usage scenario we have builds dev, test, and storybook we have several test specific macros. (codegen, build time optimization, etc...) we are using System/getenv in macro .clj files, goog-define + closure-defines in cljs files we want to disable the macro according to the env. but we can't use goog-define in macro files. but when the builds share single server, we can't provide different process environment variables

thheller 2025-08-07T06:13:21.131909Z

do these macros also target clojure? I mean generate code running in clojure? or do they only generate code that gets converted to JS?

김태희(taehee kim) 2025-08-07T06:14:51.435419Z

> do they only generate code that gets converted to JS?

김태희(taehee kim) 2025-08-07T06:15:08.452989Z

we are trying to use https://github.com/mhuebert/shadow-env?tab=readme-ov-file'

thheller 2025-08-07T06:15:21.102429Z

you can get any options from the build config in the macro, but those won't be available during "normal" CLJ compilation, so wouldn't be available there

👀 1
thheller 2025-08-07T06:16:12.217659Z

that lib looks like a bad idea IMHO

😂 1
김태희(taehee kim) 2025-08-07T06:16:36.802469Z

how can we get build config from macro?

thheller 2025-08-07T06:17:59.444409Z

just to be clear you are looking for something like this

(defmacro a-macro [& body]
  (case (get-desired-target)
    :storybook
    `(foo :storybook)
    :test
    `(test :test)
    ;; default
    `(normal :cljs)))

👀 1
thheller 2025-08-07T06:18:07.776799Z

and want the (get-desired-target) thing?

김태희(taehee kim) 2025-08-07T06:18:29.987239Z

yes. exactly

김태희(taehee kim) 2025-08-07T06:19:00.584319Z

i want to get current :shadow.build/build-id

thheller 2025-08-07T06:21:49.195339Z

ok, so what you are looking for is the cljs.env/*compiler* atom

🙌 1
thheller 2025-08-07T06:22:43.572749Z

basically the entire compiler state is in there and you can get most things. some are more nested than others though

thheller 2025-08-07T06:23:06.394769Z

the convention is to use the :compiler-options {:external-config {:foo "bar"}} map

thheller 2025-08-07T06:23:29.610099Z

which you could get via (get-in @cljs.env/*compiler* [:options :external-config :foo])

김태희(taehee kim) 2025-08-07T06:24:57.228189Z

I see. Thank you for helping us!

thheller 2025-08-07T06:24:57.752559Z

if you want the build-id you can get that via (get-in @cljs.env/*compiler* [:shadow.build.cljs-bridge/state :shadow.build/build-id])

👀 1
thheller 2025-08-07T06:25:52.889599Z

:shadow.build.cljs-bridge/state contains basically all the shadow-cljs build state. instead of :shadow.build/build-id you can also get :shadow.build/config which is the entire config

thheller 2025-08-07T06:26:29.117889Z

be aware that you cannot just use everything from that map though

thheller 2025-08-07T06:26:38.843639Z

only some options are respected when it comes to caching

thheller 2025-08-07T06:27:03.477269Z

so just adding things randomly may lead to the compiler not knowing about them and not taking them into account for caching

thheller 2025-08-07T06:27:09.497899Z

which can lead to stale caches

✅ 1
thheller 2025-08-07T06:27:57.997409Z

:compiler-options {:external-config {:foo "bar"}} is generally recommended place, since the compiler knows about this and any changes made to the :external-config map will invalidate the caches

🙌 1