shadow-cljs

valerauko 2025-06-25T12:38:30.969029Z

Is there some way to make shadow-cljs emit a raw import? Webpack can't seem to find imports wrapped in shadow.esm.dynamic_import. Do I need to add a post-processing hook to hard-replace shadow.esm.dynamic_import > import in the output files?

thheller 2025-06-25T12:39:36.794609Z

(:require ["whatever" ...]) is a raw import, otherwise no not really

valerauko 2025-06-25T12:40:07.027019Z

I'd still need it to be a dynamic import for code splitting

thheller 2025-06-25T12:40:12.441589Z

the shadow.esm.dynamic_import is working around the closure compiler otherwise complaining about import() and bailing

thheller 2025-06-25T12:40:42.552029Z

so this is basically just hiding it from that, so if you were to add it via other means you'd just have to fight that again

thheller 2025-06-25T12:41:31.565179Z

haven't found a good alternative that closure is happy with

valerauko 2025-06-25T12:41:37.294649Z

i was thinking of just post-processing the shadow-cljs output files with awk and replace all instances of shadow.esm.dynamic_import

thheller 2025-06-25T12:42:08.441649Z

you could try that

valerauko 2025-06-25T12:43:34.170629Z

could i do something like that in a build hook?

thheller 2025-06-25T15:48:18.654699Z

I suppose so yeah

thheller 2025-06-25T15:50:17.359609Z

in the :optimize-finish stage you'll find the compiled modules under :shadow.build.closure/modules. its a vector. each entry will have an :output key which is the generated JS

thheller 2025-06-25T15:50:43.185219Z

however modifying this in any way is very likely to break the source maps

thheller 2025-06-25T15:51:01.178029Z

and it'll only work for release builds. dev builds look different and don't have that.

valerauko 2025-06-25T16:22:47.529709Z

i haven't tested the release build in operation, but in dev it worked first i made an exported thing like (def ^:export dynamic-import shadow.esm/dynamic-import) (since shadow.esm/dynamic-import isn't ^:export so it gets munged) in dev i just replaced all instances of my_ns.dynamic_import with import. this worked. in prd i first tried to find its new name which ends up in some $APP.foo("my_ns.dynamic_export",AB) kinda call. its invocations all looked like AB.c?AB.c("imported thing"):AB.call(null,"imported thing"). i replaced all these with import("imported thing") but haven't had time to test yet. at least webpack doesn't complain about it and code splitting works

valerauko 2025-06-26T05:40:53.430049Z

I was wondering if the "closure doesn't allow import()" is still a problem if I target es2020+?

thheller 2025-06-26T05:53:38.777039Z

its completely irrelevant to that. its a build thing. just like webpack the closure compiler will interpret import("./something.js") and try to actually process and bundle it. there is currently no option to tell it to ignore those

thheller 2025-06-26T05:54:05.418669Z

well technically there is an option, but it comes with a bunch of constraints and doesn't actually work 😛

valerauko 2025-06-26T06:59:13.775549Z

oh 😞