NEVER MIND - this is because Lottie has an expression that needs to use eval and it silently fails due to CSP not having unsafe-eval. Nothing to do with shadow-cljs. I'm having an annoying issue with LottieReact - it works fine on dev, but on release it seems to behave very weirdly - some segments of the animations play, some others do not. Searching online doesn't give any clue - there used to be an error but seems to have been since fixed. I wonder if there's a way in shadow-cljs to bypass any optimisations that might happen but only for that library?
The weird behavior is that in an animation with say 120 frames, frames 90-120 play just fine, whereas frames 0-89 seem to be stuck. The logs show that time progresses though.
The animation is an inline JSON structure. I wonder if that file becomes minified somehow? It night explain it.
See edit re eval
Hello. How to write a macro in a .clj file which emits code prefixed with js/?
This code
(defmacro log [text]
`(js/console.log ~text))
causes this compiler error:
Error in phase :compile-syntax-check
RuntimeException: No such namespace: js
clojure.lang.Util.runtimeException (Util.java:221)
clojure.lang.Compiler.resolveIn (Compiler.java:7913)
...
You need to make sure not to emit that code on the JVM. Here's one way to do it, I don't know if there's a better approach:
(defmacro alert [text]
(if (:ns &env)
`(js/alert ~text)
`(println ~text)))
The problem is that it tries to exand js on the JVM where it is not available. You can flip it. (.log js/console ~text) . But why would you want a macro at all?
this should be a function.
This is just a simplified example. My real macro is more complex.
Ahh. Sorry. @christian767’s solution will work independent of complexity 🙂
problem is that the backtick wants to expand the js alias and can't find it, so the usual trickery should work, as in (~'js/alert ~text)
but yes, if this is also emitting code for CLJ its usually better to go with a helper function and let that sort out the platform specific stuff, while the macro just call uses the regular fn
Why is the macro emitting code for CLJ? Or how do I disable it?
it doesn't. unless you use it from CLJ code of course
you didn't post the full trace. so no clue what you are doing 😛
ok, so I must have a reference from a .clj or .cljc file, right?
https://code.thheller.com/blog/shadow-cljs/2019/10/12/clojurescript-macros.html
Thank you!
I strongly recommend a .cljs files + a .clj file. .cljc just makes this more complicated and if only targetting CLJS not worth that hassle
Yes, I am refactoring from .cljc to .cljs+.clj
with the setup in the blog post above I'd recommend something like
;; my/util.clj
(ns my.util)
(defmacro foo [& body]
`(log :yo))
;; my/util.cljs
(ns my.util
(:require-macros [my.util]))
(defn log [x]
(js/console.log x))that sidesteps the whole problem of the macro having to emit any js/* things
Problem with this is that wen calling js/console.log indirectly the browser dev tools show the wrong source reference on every log message
yeah if you care about that then better do it in the macro
@witek https://github.com/status-im/status-mobile/tree/develop/src%2Fquo%2Fcomponents%2Ficons Here we have a macro that emits js/require for all the files in a folder, then from cljs it's called. Just sharing if you need a reference