shadow-cljs

niwinz 2025-11-24T12:48:15.975849Z

@thheller hey, one question, is shadow exposes something on the analyzer (like :shadow.build/ns->mod ..) that can be used to resolve from module-name to the file path (like we have in the manifest.json)?

niwinz 2025-11-24T13:49:15.134679Z

I think i found it myself: [:shadow.build.cljs-bridge/state :shadow.build.modules/config]

thheller 2025-11-24T14:37:03.887559Z

which path are you referring to?

niwinz 2025-11-24T14:38:15.936619Z

the compiler output path. I'm migrating from :broser target to :esm, and on browser target we have used the modules loader, which one is only available under :browser target

niwinz 2025-11-24T14:39:50.681929Z

I have build a lightweight approach (witthout module manager and module loader) that loks like

thheller 2025-11-24T14:40:19.470289Z

there is a new loader mechanism for esm thats generally "better" I think

thheller 2025-11-24T14:40:36.135999Z

basically you apply :lazy-loadable to a var metadata

thheller 2025-11-24T14:40:55.074169Z

(defn my-thing {:lazy-loadable true} [a b] ...)

thheller 2025-11-24T14:41:25.435229Z

then (shadow.esm/load-by-name 'foo.bar/my-thing) give you a promise that'll resolve to a function for that var

thheller 2025-11-24T14:42:16.266379Z

that should make all other needs to know the module name or path obsolete?

niwinz 2025-11-24T14:42:30.725519Z

oh, interesting, i will look on it. In any case our approach works for us and is drop-in replacement for the previous approach without big code changes

niwinz 2025-11-24T14:43:00.554809Z

maybe in other iteration i will look on using the load-by-name

thheller 2025-11-24T14:43:10.798159Z

load-by-name is just a function, so requires to special macro magic and can easily be integrated into other helper things

thheller 2025-11-24T14:43:51.555359Z

{:lazy-loadable "foo"} and (load-by-name "foo") also works

niwinz 2025-11-24T14:44:26.853109Z

that i'm not cleary understand

niwinz 2025-11-24T14:44:48.589529Z

what do you mean with {:lazy-loadable "foo"}, where it should be?

thheller 2025-11-24T14:44:56.887299Z

you can use your own name I mean. doesn't need to be a fully qualified symbol

thheller 2025-11-24T14:45:01.704659Z

on the var metadata

thheller 2025-11-24T14:45:11.963229Z

(defn my-thing {:lazy-loadable "foo"} [a b] ...)

niwinz 2025-11-24T14:45:20.475149Z

ok ok, now is clear

niwinz 2025-11-24T14:45:35.569269Z

i go to experiment with it, thanks

thheller 2025-11-24T14:48:06.132239Z

to be clear it yields a function, so

(js-await [var (shadow.esm/load-by-name "foo")]
  (let [actual (var)]
    (actual 1 2)))

👍🏽 1
thheller 2025-11-24T14:48:40.200879Z

(its not actually a var, just a zero arity function to get the latest reference)

thheller 2025-11-24T14:49:01.100959Z

this is because of hot-reload or REPL which may redefine things, so every time the function is called you get the latest value

niwinz 2025-11-24T14:49:53.404949Z

yep, i'm aware of it, in any case thanks for clarification

niwinz 2025-11-24T17:07:07.883839Z

I'm playing a bit with it and looks very interesting, but i have some case that does not looks to be working. I have a custom macro for define react components as function, it mimics the defn and looks like this

niwinz 2025-11-24T17:08:47.056119Z

on that macro, all this metadata is assigned to the symbol metadata but looks like shadow passes before that... or something that i'm not understand right now, still researching

niwinz 2025-11-24T17:12:28.267949Z

nah, that was my fault, it works as expected, ignore previous chat

👍 1