Fork me on GitHub
#shadow-cljs
<
2019-06-16
>
Mudge02:06:03

Why is the manifest.edn map in a list?

Mudge02:06:37

ah, for multiple modules I guess

Mudge02:06:50

makes sense

Mudge02:06:45

It seems like the manifest.edn should not be generated in the same place as the target output, because the target output needs to be public, but it seems that the manifest.edn should not

judepayne05:06:10

Hello, new to shadow-cljs; I'm in the process of migrating an application over from figwheel-main and am encountering an error with the npm module viz.js https://www.npmjs.com/package/viz.js. viz.js is an Emscripten transpile of graphviz (which is C) to asm javascript so the javascript itself (in full.render.js in the viz.js package) is pretty hairy!

judepayne05:06:37

I follow the instructions at the bottom of the viz.js author's page https://github.com/mdaines/viz.js/wiki/Usage and the shadow-cljs user guide (section 11) and require viz.js into my code as so

judepayne05:06:51

["viz.js/viz.js" :as Viz] ["viz.js/full.render.js" :refer (Module render)]

judepayne05:06:00

and get a shadow error

judepayne05:06:17

Caused by: RuntimeException: INTERNAL COMPILER ERROR. Please report this problem. An enclosing scope is required for change reports but node LABEL 15 [length: 2] [source_file: node_modules/viz_DOT_js/full.render.js] doesn't have one. Node(FOR): node_modules/viz_DOT_js/full.render.js:15:4095

judepayne06:06:17

so, not really needing viz.js to be attempted to be further compiled, I set the following option in my shadow-cljs.edn

judepayne06:06:25

:js-options {:js-provider :require}

judepayne06:06:43

but unfortunately this seems to cause breaks around other existing dependencies in my project, for example [io.nervous/kvlt "0.1.4"]

judepayne06:06:59

Any tips on how to get this particular npm module to work (as an npm module) would be much apprecicated.

thheller10:06:26

@mojo yeah the emscripten packages seem to confuse the closure compiler. :js-provider :require is only for node environments and doesn't work in the browser.

thheller10:06:14

but yeah this option is still missing

thheller10:06:44

> A hack to put Graphviz on the web.

thheller10:06:10

a 2MB+ package is really not that practical for the web šŸ˜›

judepayne10:06:28

Got it - thanks for the steer. Yes - as the description says it's a (clever) hack šŸ™‚ I also have Graphviz mounted as an AWS lambda but then realised that sending my company's data out over the web is not policy compliant hence the need for the hack! Would be supportive of the option to provide a list of modules which don't go through any compilation processing.

judepayne11:06:31

Worked perfectly - thank you

judepayne11:06:13

One other thing to mention. I had also tried the approach of requiring the .js files as set out in section 11.2 of your excellent documentation, but had no luck with that approach - it couldn't find the modules even though I'd followed the suggested directory structure. Is that approach also only for the

node
environments? If so, as a newbie coming to the documentation, that wasn't immediately obvious to me and could well be worth clarifying

judepayne11:06:48

lol - still yet to get the hang of backticking in Slack šŸ™‚

thheller11:06:36

not sure what you mean?

thheller11:06:04

the require you had was correct

judepayne11:06:24

yes - requiring as a node module. Well, when that didn't work and before posting here, I always tried the approach laid out in section 11.2.1 of your documentation - requiring the js files correctly. The reason I tried that as well was that pretty sure I read there that any source .js files under a js/ would not be passed through compilation

judepayne11:06:09

so wondered alternative approach is valid for the :browser target? (and I just hadn't got it quite right) - or only for other targets?

thheller11:06:13

no that is incorrect. quite the opposite actually. the files will go through :advanced optimizations

thheller11:06:48

node_modules will only do :simple which already fails for viz.js so :advanced is unlikely to work

judepayne11:06:04

The line that confused me was actually in the following section 11.2.3 - Notice how src/js is not added to :source-paths and will not be added to the classpath. Obviously, I must have speed read too much and jumped ahead thinking that between the two sections, there was a way to exclude .js files from the compiler but still be able to require them. my bad. thanks for clarifying

lilactown16:06:34

Iā€™m trying out that weird trick mfikes posted in #cljs-dev:

(do (declare ^{:arglists '([a b c] [a b & cs])} create-element)
    (set! create-element react/createElement))
and currently seeing this warning during compilation:
18 | (defn tag-render [{:keys [title body]}]
-------^------------------------------------------------------------------------
 Wrong number of args (5) passed to hiccup-next.react/create-element
--------------------------------------------------------------------------------
  19 |   #h/n [:div {:class "card"}
  20 |         [:div {:class "card-title"} title]
  21 |         [:div {:class "card-body"} body]
  22 |         [:div {:class "card-footer"}
--------------------------------------------------------------------------------

thheller16:06:46

how the heck is that even compiling? reader literals aren't supported like that?

lilactown16:06:53

šŸ˜„ what do you mean?

thheller16:06:10

#h/n this isn't supported (in shadow-cljs)

lilactown16:06:35

why not? itā€™s a perfectly valid nsā€™d symbolā€¦

thheller16:06:02

because its nonsense to do this in code

lilactown16:06:14

oh are custom reader tags not supported at all you mean?

thheller16:06:36

yes, no custom reader tags during compilation. at runtime is fine but not during compilation

thheller16:06:58

also the arglist trick is sort of a cheat an probably doesn't support varargs

lilactown16:06:03

hmm. I was getting some issues with the reader tags at first. I was able to work around it by having the CLJS namespace require the macro namespace

lilactown16:06:42

should I not expect reader tags to continue to work with shadow-cljs?

lilactown16:06:57

hereā€™s my current experiment: https://github.com/Lokeh/thumps

thheller16:06:58

they are not supported until I hear to compelling reason why they should be

thheller16:06:40

the issue is that you are doing things during read-time. so you basically have to turn of caching since it impossible to tell what its going to do

lilactown16:06:48

hmm. is there a significant difference between doing things at read-time vs. macro-time from the perspective of caching?

thheller16:06:10

(ns my-app.core
  (:require [hiccup-next.core]
            [hiccup-next.react :refer [<>]]))

(defn Mycomponent [props]
  (let [name (goog.object/get props "name")]
    (<> [:div {:style {:color "green"}}
         [:span "Hello, " name]
         [:ul
          (for [n (range 10)]
            (<> [:li {:key n} n]))]])))

(react-dom/render (<> [MyComponent {:name "Sydney"}])
  (. js/document getElementById "app"))

thheller16:06:42

what do read-tags give you that you can't already do with function/macros?

ā˜ļø 4
thheller16:06:55

I totally get their use for actual data

thheller16:06:59

not so much for pure code

thheller16:06:03

the difference with read-tags versus macros is that their dependency is never declared in the code

thheller16:06:27

so by looking at the ns form you can't tell that the namespace is gonna use hiccup-next.react unless you require it

thheller16:06:39

and if you require it you could just use a normal macro/refer

lilactown16:06:58

I am starting to see the tradeoffs yes Iā€™m just still not sure about your mention of caching. probably my naivety about how shadow-cljs works

lilactown16:06:28

honestly itā€™s just an experiment. I kind of like the aesthetics of #hiccup vs (hiccup)

lilactown17:06:13

you get the whole data-is-code / code-is-data thing goinā€™ on šŸ˜› aesthetically

thheller17:06:42

except its not

lilactown17:06:56

and it allows you to seamlessly do things like shove elements over the wire and back (which is something weā€™re doing at work atm in a different way)

thheller17:06:53

the caching issue is due to the undeclared dependency stuff I mentioned

thheller17:06:11

your code doesn't declare that is depends on something and therefore won't be invalidated if that something changes

lilactown17:06:52

ah yes, I have experienced this while developing the reader tag code

lilactown17:06:05

but I donā€™t expect that would impact people consuming it

lilactown17:06:50

ah, unless they register a new element keyword e.g. (register-element! :my-app/foo FooComponent)ā€¦

lilactown17:06:51

actually that would be in the react namespace which is required everywhere itā€™s used

lilactown17:06:12

although itā€™s still global mutable state in a macro namespace so would probably still have issues

thheller17:06:27

yes quite bad

lilactown17:06:20

the one concrete thing I think I like about #h/n ... vs (h/n ...) is ease of typing šŸ˜› I basically write hiccup like I have been trained with Reagent / hx, then stick the tag on the beginning at a few places and Iā€™m done

lilactown17:06:31

but itā€™s not a strong technical argument

lilactown17:06:13

how mad will you be if other people start using it?

thheller17:06:13

couldn't care less šŸ˜›

lilactown17:06:31

cool! šŸ˜„

thheller17:06:55

FWIW I have been down this road in CLJ when it was introduced

thheller17:06:15

I need a bunch of time stuff so I naturally added things like #time/duration {:minutes 30} etc

thheller17:06:29

I also used it over the write and stuff so it felt great

thheller17:06:14

until it got a total maintenance disaster and caused all sorts of weird issues with AOT

thheller17:06:50

in the end (time/duration {:minutes 30}) works just as well and has no such issues

thheller17:06:35

so if anyone wants to learn that lesson that is fine by me

thheller17:06:47

but I won't be debugging any issues related to it šŸ˜‰

lilactown17:06:03

šŸ˜¬ šŸ˜…

lilactown17:06:29

yeah I havenā€™t tried it in CLJ much at all

lilactown17:06:11

I started down the road of creating a CLJ implementation of React string rendering againā€¦ then got frustrated and gave up for now

lilactown17:06:04

I was telling roman01la that I think it would be really nice to have a react.clj lib that was separate from a specific hiccup library / ui framework like rum / hx / uix / etc.

lilactown17:06:18

that would take some normalized format {:type "div" :props {...}} and implement turning those trees into an HTML string

lilactown17:06:58

and then the rest of us can muck about with syntax / macros / extensions and processing on top of it instead of copying + pasting and rewriting the same code

lilactown17:06:35

but itā€™s a lot of work. thereā€™s a lot of corners of HTML to cover

lilactown17:06:49

I donā€™t think rum does it šŸ’Æ

thheller17:06:08

well the only way you are going to solve that properly is by not using react šŸ˜‰

lilactown17:06:18

haha, well I think either way we have to write the code to cover those corners šŸ˜› just Reactā€™s already done it in the browser for us!

lilactown17:06:13

I am seeing a clear benefit of separating hiccup and the underlying rendering engine (whether it be Reactā€™s VDOM or something else)ā€¦ thereā€™s lots of different things we can do to improve the hiccup syntax experience, extensions, etc. that doesnā€™t really have anything to do with rendering HTML

thheller17:06:48

semantics are all that matter

thheller17:06:11

otherwise is just changing (:require [hiccup-next.react :refer [<>]]) to (:require [[something.else :refer [<>]])

thheller17:06:33

one thing I did in my experiments is making events declarative

thheller17:06:57

[:div {:onClick (fn [e] ...)} ...] is bad for server rendered code

šŸ’Æ 4
thheller17:06:04

and annoying on the client

thheller17:06:21

[:div {:on-click [:foo 1 2 3]} ...] good on the server and client

lilactown17:06:59

right! and separating the syntax from the engine that actually produces the resulting HTML/JS allows others to extend the semantics further without breaking compatibility with the engine

thheller17:06:41

yes, things should be as declarative as possible

lilactown17:06:45

put another way, we could build that semantic on top of React and it would continue to work with other React components once parsed & compiled

thheller17:06:11

I'm not interested in react anymore personally

lilactown17:06:19

yes, thatā€™s just an example

lilactown17:06:16

one of the reasons people have asserted that React isnā€™t needed and is inefficient is because we have hiccup. that we should use hiccup, instead of Reactā€™s VDOM

lilactown17:06:53

and I was kind of on board with this argument for awhile, but now I think that coupling the syntax we use for writing code to the rendering engine is probably bad

lilactown17:06:23

there are other reasons to eschew React, but I think that ā€œusing hiccup AND <underlying VDOM implementation> is inefficientā€ is a problem with hiccup, not the VDOM šŸ˜›

thheller17:06:56

the true superpower we have is macros so we should use them

thheller17:06:03

hiccup in itself is still too inefficient

lilactown17:06:12

yes! 100% agreed