Fork me on GitHub
#fulcro
<
2018-08-18
>
Pontus08:08:14

I generated a build report with shadow-cljs and I noticed I'm getting a dependency (43KB) on Garden even though I haven't used the fulcro-css functionality at all. Is that expected? In this part of the book it looked like it wouldn't get included if it wasn't used: http://book.fulcrologic.com/#_css_support, but maybe it's referring to other fulcro-css related dependencies?

thheller08:08:29

FWIW garden unfortunately relies on multi-methods which closure can't remove as dead code and since they in turn access a lot of other code pretty much nothing of the lib can be removed.

Pontus12:08:05

ah alright then

tony.kay15:08:23

Hm. I didn;t realize that. I think the value of having the css stuff integrated tightly like it is has great advantages, but I prefer not to bloat people’s code when they don’t use something. That’s why I changed the server stuff to dynamic deps. I wonder if there’s a way I can change the code to make that more opt-in without sacrificing the integration for those that use it.

tony.kay15:08:53

@thheller newer versions of cljs have require that works outside of ns…does it work with adv compile? Could I use a goog-define to let people opt out of cljs deps/features?

tony.kay15:08:24

actually, this might be doable…`primitives` requires fulcro-css.css, but only because the macro could emit code for it. If I drop that require, then I think none of garden would be picked up (which is only used from the css ns…at that point the macro would cause errors for people that use the css features but don’t have the css namespace in their require.) That would be a breaking change, though, since those users are used to it “just working”.

tony.kay15:08:54

Hm…I tried the goog-define thing…does not seem to work

thheller15:08:12

@tony.kay the require outside ns is "fake". you can't do dynamic requires like in clojure at all. the require can only be in the top level and not inside any conditionals or so

thheller15:08:31

it only exists so you can have namespace without ns which I don't quite see the point in (from a build tool perspective)

tony.kay15:08:42

oh, I see 😞

tony.kay15:08:56

is there any way to ask the cljs compiler not to complain about the lack of a FQNS in the ns decl? E.g. force it to assume “some other place” has required it for dep analysis?

tony.kay15:08:21

Because anyone using the CSS features will have to require the CSS stuff in the place where they inject it…so it will be “somewhere”

tony.kay15:08:54

meh…that isn’t going to work at dev time, probably, since you might define a component with CSS before you’ve ever injected it.

tony.kay15:08:27

Seems the only way to fix that kind of thing is to make separate nses for the “light” vs. “heavy” versions

thheller15:08:29

yeah its surprisingly complicated

thheller15:08:50

you could pass the css in instead

thheller15:08:11

but thats just lots more boilerplate to write by hand every time

thheller15:08:14

so probably not worth

tony.kay15:08:44

There is another approach I could take actually…move the protocol

tony.kay15:08:00

(or not use a protocol at all)…that’s all primitives really uses from the css ns

tony.kay15:08:44

That would break ppl using defui, but it is a simple break, and I hope ppl have long moved away from it

tony.kay15:08:04

that way you’d only get the dep if you injected the css

tony.kay15:08:58

I think that’s a reasonable thing to put in 2.6, actually…thanks @thheller for bouncing that around with me

tony.kay15:08:15

@pontus.colliander thanks for the bloat note 🙂

🙂 8
thheller15:08:14

one concept I have been playing with for a bit is using an extensible macro

thheller15:08:38

so you have a defmacro in a namespace coupled with a defmulti

thheller15:08:53

lets call it fulcro.main

thheller15:08:13

if the user require fulcro.css from CLJS it has a companion fulro.css CLJ file

thheller15:08:27

which can do defmethod fulcro.main/that-macro :css ...

thheller15:08:10

that way the defsc macro could become extensible and wouldn't have the garden dep

thheller15:08:57

and I sort of enforced the import by using namespaced keywords

tony.kay15:08:06

I played with something similar to make defsc extensible…but it was a nightmare to work with because of the “thinking in two domains” problem…the extensions were written in clj, but emitting cljs…but also emitting clj for SSR….whew it was hard to think about

thheller15:08:25

ie. not :css but the user would be ::css/foo

thheller16:08:01

yeah its a lot more complicated if you add SSR into the mix

tony.kay16:08:28

and I don’t like how “forgetting a require” breaks your syntax…multimethods are annoying (but convenient) 🙂

tony.kay16:08:22

I’d rather people just wrap defsc in their own macro to make extensions…I think that form of composition is ultimately more tractable

tony.kay16:08:45

and defsc supports the :protocols bit, so you can extend the underlying component that way

thheller16:08:47

:css (css/make [:.items-wrapper {:background-color "blue"}]) instead of :css [[:.items-wrapper {:background-color "blue"}]] is also not ultra bad

thheller16:08:33

would be so much nicer if we could do dynamic requires but I have not yet figured out a proper way to get there without completely breaking :advanced 😛

tony.kay16:08:12

Can you do reader tags (from data-readers) in ns?

tony.kay16:08:39

maybe a JVM -Dboo and a data-reader that elides a form if JVM prop boo is set?

tony.kay16:08:01

(ns name #boo (:require x))

tony.kay16:08:19

I mean, that’s sorta how we did that kind of thing in C 🙂

thheller16:08:41

its an absolute nightmare from a caching perspective and you'd probably have to sacrifice caching entirely for that

tony.kay16:08:53

ah, right…cache invalidation

tony.kay16:08:04

one of the two hard problems in CS

tony.kay16:08:55

well, unless it was a compiler feature, in which case you’d see that the flag had changed from last compile?

thheller16:08:21

but its not exactly nice to work with

thheller16:08:42

since now the user has to set special flags when compiling your stuff

tony.kay16:08:18

yeah, and it won’t work with standard cljs compiler 😞

tony.kay16:08:04

Having to define something in order to elide a thing is ok, but for this problem moving the protocol is viable, since only defsc should be a user of the protocol unless you’re using ancient defui

tony.kay16:08:36

@pontus.colliander 2.6.0-RC8 on clojars. You should no longer see garden if you don’t use co-located CSS

🎉 4
tony.kay16:08:36

This does create a minor breaking change for users of defui…the will have to change the protocol name from fulcro-css.css/CSS to fulcro-css.css-protocols/CSS…a minor global search/replace.

tony.kay16:08:00

a savings, as you pointed out, of about 50k

Josh Horwitz16:08:29

Out of curiousity, why are the factory functions necessary instead of just creating a component and using it directly?

tony.kay16:08:12

React: You have to define a “class” (or function in js-land), and the factory is how you make instances

tony.kay16:08:21

in base react createElement is the factory, but Fulcro also does some magic in the factory, and that is what factory in primitives generates for you…a factory to emit a React instance (element) with some bits that help with the whole data integration story of Fulcro

Josh Horwitz17:08:39

Ok great, thanks for the explanation

Josh Horwitz18:08:08

Re-reading the queries sections of the book, seems to be the hardest part to wrap my head around