Fork me on GitHub
#shadow-cljs
<
2024-01-18
>
Ulises MC07:01:48

Hi all :) I hope someone know about this: I'd like to add a custom transformation to the JS code compiled by shadow-cljs, preferably, before writing to the disk. I was thinking that maybe the best way to do this is by using the Build Hooks. But the info there is really big :thinking_face: idk where to look at. At the end shadow writes many of these things:

SHADOW_ENV.evalLoad("my_ns", "goog.provide(... my compiled JS code ...")
I want to transform ... my compiled js code... One option is look at all the "goog.provides"'s content and apply my transformation. Another option is adding metadata to the namespace or functions (so cool!) And only applying the transformation to the namespace/fns having that data. My questions: Is it possible to add that transformation as part of the BuildHooks? Is it possible to look at the metadata and apply the transformation only on certain namespaces/fns? It would be really good in terms of performance to only apply the transformation to the changed code, not to the whole compiled thing. Thanks in advance!

thheller08:01:38

what transformations do you have in mind?

thheller08:01:46

yes, you can do that in build hooks but you kinda have to be careful about what you are doing as you may potentially break caching. also possibly weird issues when not respecting how watch works (incremental compiles)

thheller08:01:04

yes, you can look at all metadata in build hooks

thheller08:01:14

not sure what your intent is though as the generated JS isn't exactly easy to process

Ulises MC14:01:25

Thanks for the reply! Any hint about what are the involved keys? Just want to pass a babel plugin to the JS output.

thheller14:01:13

to do what?

thheller14:01:39

I'm asking because I want to safe you the time of doing something that is maybe covered elsewhere

Ulises MC14:01:12

Oh yeah, sorry. Involved keys in build hooks to check the metadata, and to apply a babel plugin to the JS code related to that metadata.

thheller14:01:29

what babel plugin? what does that do?

thheller14:01:42

and what does the metadata provide for it to do?

thheller14:01:01

I mean have you looked at the actual JS output? are you sure the babel plugin is going to be able to do what you want to do?

Ulises MC14:01:36

About the metadata, nothing specific, it would work just as a flag to apply the plugin

thheller14:01:00

you are being very vague so I'm just gonna tell you want you want to know and skip trying to safe time

thheller14:01:12

the build state the build hook receives contains all the data

thheller14:01:25

you can tap> it and look at it in the inspect UI

thheller14:01:30

I'd suggest clicking arround

Ulises MC14:01:47

And yes, I'm sure about the pluging working as expected, I applied the plugin to the strings passed to evalLoad in index.js and it works well. I'll share the plugin link in a sec

thheller14:01:50

the relevant bits are in :sources which is a map of all the sources revelant to the build

thheller14:01:00

in :output you find the generated :js code

thheller14:01:23

you want the build hook to run in stage :compile-finish

thheller14:01:32

its all just clojure data

thheller14:01:56

the analyzer data you find in [:compiler-env :cljs.analyzer/namespaces your.ns :defs your-var :meta]

thheller14:01:16

again look at it in the UI, pretty self explanatory from there

thheller14:01:36

:js is the field being later generated into the evalLoad argument, and is the final JS being loaded

Ulises MC14:01:08

you are being very vague so I'm just gonna tell you want you want to know and skip trying to safe time> Sorry, I'm on my phone rn 😅 And also I say nothing concrete/specific because it's something to be created, the metadata can be whatever I find better. The plug-in link (animated babel parser for react-native): https://github.com/software-mansion/react-native-reanimated/tree/main/plugin/src

Ulises MC14:01:41

Thanks for all the explanation!!

Ulises MC16:02:06

@thheller Hello again, I recently tried this approach and it worked as expected! Thanks for your help. Now I'm wondering if there's a key in the build-state that lets me know what were the files/namespaces modified by the user, and that need to be recompiled. I've checked the build-state but I didn't find something meaningful. I just noticed during :compile-prepare there's a key (I forgot the name) that has less files listed compared to the same key at :compile-finish (that has all the files) and I'm getting that difference. I guess there should be a better way to know it. Thanks in advance!

thheller17:02:35

there is :shadow.build/build-info and that has a :compiled key

thheller17:02:07

which is a set of resource ids that got compiled

thheller17:02:22

resource id is the key in the :sources and :output maps

thheller17:02:55

watch works by removing :output prior to compiling it again

thheller17:02:30

so if you want you can keep state in :output yourself, so for files you have processed you can set a boolean or something

thheller17:02:40

if that is not set it means it needs processing

Ulises MC02:02:18

Ok thanks again!

souenzzo16:01:08

I moved an old codebase from #C1A38UB5X into shadow-cljs Using the shadow-cljs build report I was able to remove 64 files//7kLOC from the repo, of unused namespaces 🙂 Thank you thheller!

👏 2
😮 3
Ulises MC16:02:06
replied to a thread:Hi all :) I hope someone know about this: I'd like to add a custom transformation to the JS code compiled by shadow-cljs, preferably, before writing to the disk. I was thinking that maybe the best way to do this is by using the Build Hooks. But the info there is really big :thinking_face: idk where to look at. At the end shadow writes many of these things: SHADOW_ENV.evalLoad("my_ns", "goog.provide(... my compiled JS code ...") I want to transform `... my compiled js code...` One option is look at all the "goog.provides"'s content and apply my transformation. Another option is adding metadata to the namespace or functions (so cool!) And only applying the transformation to the namespace/fns having that data. My questions: Is it possible to add that transformation as part of the BuildHooks? Is it possible to look at the metadata and apply the transformation only on certain namespaces/fns? It would be really good in terms of performance to only apply the transformation to the changed code, not to the whole compiled thing. Thanks in advance!

@thheller Hello again, I recently tried this approach and it worked as expected! Thanks for your help. Now I'm wondering if there's a key in the build-state that lets me know what were the files/namespaces modified by the user, and that need to be recompiled. I've checked the build-state but I didn't find something meaningful. I just noticed during :compile-prepare there's a key (I forgot the name) that has less files listed compared to the same key at :compile-finish (that has all the files) and I'm getting that difference. I guess there should be a better way to know it. Thanks in advance!