Aye itโs static children. Thanks!
Thanks!
With core.async, does one still need to load cljs.core.async.macros
manually?
(ns repro
(:require-macros [cljs.core.async.macros :refer [go alt!]])
(:require [clojure.core.async :as async]))
Can one also write (async/alt! ...)
now without requiring the macro namespace?I'm asking for @amorokh but I'm also curious myself.
(:require [clojure.core.async :as async :refer (go alt!)])
is fine, as is async/alt!
. no need for .macros
unless you are on a really old version.
^ @amorokh
ah, great, thanks!
I have a clojurescript library filled with reagent components. Another project I work on uses plain old React, and it wants to consume those components. I figure, essentially, I have to find a compiler that has a target that knows how to make commonjs modules. At first I tried shadow-cljs to do that. It might have worked, but when rendering the components that I have imported I see a lot of this:
Objects are not valid as a React child (found: object with keys {children}). If you meant to render a collection of children, use an array instead.
So. two part question:
1. Am I barking up the wrong tree with shadow? Is there an alternative I should try?
2. If โnoโ to question 1, then (a shot in the dark here) do you have any leads what the problem might be?Did you make sure to reactify the components? https://github.com/reagent-project/reagent/blob/master/doc/InteropWithReact.md#creating-react-components-from-reagent-components
No. I had not seen this document. Iโll check it out.
Why is the LazyVar
in CLJS cljs/spec/gen.alpha/cljc not just a delay?
https://github.com/clojure/clojurescript/blob/5e88d3383e0f950c4de410d3d6ee11769f3714f4/src/main/cljs/cljs/spec/gen/alpha.cljc#L15
From the Closure compiler docs, it sounds like dead code elimination works at the function level (i.e. if you don't call a function, its definition will be eliminated from the final bundle). But in my own testing with CLJS (with tools-deps and target-bundle), it seems like it works at the namespace level. If I require a namespace (not even use it), that entire namespace and all code that it transitively requires gets included. Is that the expected behavior?
are you testing with :advanced
optimizations? there are some exceptions that aren't removed by DCE but it does work at a function level
yes
as far as CLJS is concerned requiring a namespace will pull in all of it and its dependencies. :advanced
may move stuff between "namespaces" and delete unused stuff.
but for examples multimethods are never removed by DCE. so if you have code that has a defmulti
and defmethod
then that is never removed and all the code they call isn't either.
nope, just regular functions. just requiring a namespace is adding hundreds of KBs to my final advanced optimizations JS bundle
I would have expected it to all be eliminated by DCE
since I'm not calling any of the fns yet
hard to say. depends very much on what the code actually does.
DCE definitely does work and if the code is written with that in mind it will be removed entirely
Is there any way to get more insight into the decisions the closure compiler is making there and why?
it is kinda hard to debug or even tell what code is actually staying alive. in shadow-cljs there are build-reports which make this a whole lot easier but there is nothing comparable for :target :bundle
https://shadow-cljs.github.io/docs/UsersGuide.html#_build_report
as far as the closure compiler there is no way I'm aware of to debug this in more detail
besides :pseudo-names true
to actually even tell what any of the code even is of course ๐
it might be that you require some namespaces that require JS code (eg. react, react-dom). that won't be removed either.
yeah there is some of that, but it is closure-compatible so I've tried running it through the closure compiler too and the final bundle size didn't change. could be I just screwed that up somehow though. really hard to tell what closure is doing. ๐
thanks for the insight, though. very useful.
"final bundle size didn't change" doesn't sound like you are using :advanced
? or what are you comparing it too? :advanced
will definitely make everything much much smaller even if it doesn't "remove" any code?
I am using advanced, in the before and after of that test.
advanced is much smaller than the other optimizations, to be sure
I'm just trying to figure out why I'm seeing this unexpected behaviour w/r/t DCE
yeah its kinda tough to tell why something isn't removed. requires a lot of digging through pseudo-named code to figure out and avoiding the pitfalls
@cap10morgan understanding and leveraging DCE in a precise way is a bit of black art
but if you're transitively depending on React or JS stuff, it's pretty much expected to balloon your bundle
you can't eliminate that stuff, and code that uses stuff that Google can't see isn't safe to eliminate
if you do some simple tests with pure ClojureScript code you'll see that pretty much what you would expect from DCE is true
because everything written in pure ClojureScript barring multimethods and specs (which mutate a global store) are free floating JS fns or JS types which can be understood by Closure