Fork me on GitHub
#reagent
<
2018-01-09
>
alexh09:01:25

@juhoteperi what i get is React being included inline in my built JS file, and if I put react and react-dom in :exclusions, it fails to compile not finding the namespace

alexh09:01:20

if i use the empty-namespace trick that worked in 0.7.0, i get an artifact which doesn't actually refer to React anywhere

juhoteperi09:01:09

Are you trying to use React from CDN?

alexh09:01:07

effectively yes - it's from my own webpack bundle that exports React to window.

juhoteperi09:01:26

Tricky, I think you can do this by overriding the foreign-lib entry from Cljsjs.

alexh09:01:36

that's included elsewhere on the page before my cljs bundle

alexh09:01:42

ok - what might that look like?

juhoteperi09:01:40

Try adding this to compiler-options:

:foreign-libs
 [{:file "empty.js",
   :provides ["react" "react-dom" "create-react-class"],
   :requires [],
   :global-exports '{react React, react-dom ReactDOM, create-react-class createReactClass}}]

juhoteperi09:01:10

that whould point all the namespaces required by Reagent to empty file, and create the mapping from namespace to the global vars provided by the bundle

juhoteperi09:01:31

and if I recall correctly, this hopefully overrides the foreign-libs from Cljsjs with same provides

alexh09:01:12

i'll give that a shot

juhoteperi09:01:22

problem with the empty namespaces is that foreign libs and node modules currently take precedence over Cljs namespaces... which might be wrong but that's how Cljs is currently implemented

alexh09:01:10

still getting an error - do i need to actually create that empty.js and put it alongside project.clj?

juhoteperi09:01:13

oh and empty namespaces aren't quite enough because Reagent now uses React "like it were real namespace"

alexh09:01:54

yeah, if i turn of advanced optimisations i can see it producing var react = {}; and then failing to find everything

juhoteperi09:01:06

@alex339 Yes, you'll need the empty file, in project.clj you shouldn't use ' and you need to add ReactDOMServer if you use reagent.dom.server

alexh09:01:20

ok, this is weird. if i add the empty.js, i get

clojure.lang.ExceptionInfo: failed compiling file:target/cljsbuild-compiler-1/reagent/impl/component.cljs {:file #object[java.io.File 0x2464490e "target/cljsbuild-compiler-1/reagent/impl/component.cljs"]}
...<stacktrace>...
Caused by: java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.PersistentList

alexh09:01:29

still, getting somewhere!

juhoteperi09:01:30

I have some problems with Figwheel testing this, but the output looks correct

juhoteperi09:01:02

remove ' before the hash-map if you still have tha

alexh09:01:26

in :global-exports? ok

juhoteperi09:01:02

yeah, it is required if calling cljs-build-api/build from Clojure code, but not in project.clj as that is data not code

alexh09:01:10

ahh! this seems to have nearly done it - however the lines like these don't survive advanced optimisations:

reagent.impl.component.global$module$react = goog.global.React;

alexh09:01:22

if i use :optimizations :simple i get something that works

juhoteperi09:01:06

It should keep the .React part? other names can be changed

juhoteperi09:01:12

Have you excluded Cljsjs deps? Those are needed to provide the externs

alexh10:01:54

ah yes, i did - but if i don't exclude them, then the compiled artifact includes React inline, which is what i'm trying to avoid. 😞

alexh10:01:22

i could just copy the externs from the cljsjs repo

juhoteperi10:01:11

No, adding this foreign-libs entry should override the files from Cljsjs but allow using the externs

alexh10:01:15

it works! THANK YOU!

alexh10:01:54

ah, crap. spoke too soon

alexh10:01:42

it only seems to work if i exclude the dependencies and add the externs in

alexh10:01:46

otherwise react is inlined

alexh10:01:03

gotta pack it in for today, thanks for your help @juhoteperi

juhoteperi12:01:52

@alex339 I extended this document to mention this environment: https://github.com/reagent-project/reagent/blob/master/docs/0.8-upgrade.md I'll try to get the config working myself later

joshkh12:01:28

this might be more of a reactjs question in general, but here goes! i have a fairly complex table component (reagent powered by re-frame) that does lots of things including io in the background. i have to show this component about 30 times on a report page and when i do it completely chokes the browser for a few seconds. is there a way to solve this problem internally rather than hiding tables until they're in view? maybe something to do with reagent.core/flush?

mikethompson12:01:42

Sounds like you are creating a lot of new DOM

mikethompson12:01:31

If so, I'd guess that creating all that DOM will be what's slow

mikethompson12:01:41

Perhaps you might want to use the still-experimental re-frame-trace. Maybe.

joshkh12:01:39

thanks, @mikethompson. i'm pretty sure you're right - there are loads of elements that end up trying to be painted at once. i wasn't sure if adding ^:flush-dom to the event that stores the table data for viewing would help (about to test), but i have a feeling i'm barking up the wrong tree. i'll check out re-frame-trace and see where it takes me.

justinlee17:01:10

@joshkh If the problem turns out to be actual dom performance, you can checkout the react virtualized library, which is an incredibly sophisticated library and is designed to solve just this kind of problem. Note, it takes some doing to get it integrated into your project, but it does work as advertised.

joshkh18:01:10

i'll check it out @lee.justin.m! thanks for the tip, i hadn't heard of it before now.

lilactown22:01:06

I’m having a TON of trouble getting server-side-rendering working

lilactown22:01:24

the current example in reagent-cookbook is fairly outdated

lilactown22:01:38

are there any up-to-date documentation on getting server side rendering working for reagent?

lilactown22:01:31

so this is implementing a clojure API for rendering reagent’s hiccup syntax?

lilactown22:01:50

I really just want to get a node.js server up that runs (reagent.dom.server/render-to-string)

lilactown22:01:47

so far even just trying to require reagent.core.server into a node.js application causes it to fail to build

shaun-mahood22:01:08

That seems weird - I haven't tried it but I would expect it to work. Hopefully someone with some experience running it on node will come by and help.

lilactown22:01:45

OK, upgrading my CLJS dep to 1.9.946 helped things

lilactown22:01:53

now I’m getting “org.mozilla.javascript.EcmaError: TypeError: Cannot read property “renderToString” from undefined (rhino.clj#41)” in the REPL

lilactown23:01:18

cljs.user> (reagent.dom.server/render-to-string [:div "Hello"])
org.mozilla.javascript.EcmaError: TypeError: Cannot read property "renderToString" from undefined (rhino.clj#41)

lilactown23:01:50

when I deploy it to AWS Lambda (which is adding an additional boatload of complexity to this), I get the error Unable to import module 'index': Error

juhoteperi23:01:38

Reagent uses Node, not Rhino

lilactown23:01:31

same thing in Node.js

cljs.user=> (reagent.dom.server/render-to-string [:div "hello"])
repl:13
throw e__8630__auto__;
^

TypeError: Cannot read property 'renderToString' of undefined
    at reagent$dom$server$render_to_string (/Users/r627543/Code/fido/packages/functions/example/.cljs_node_repl/reagent/dom/server.js:22:62)

lilactown23:01:00

it seems to be a problem with how react is imported into the project,

lilactown23:01:17

i’m not sure how to filter the signal from the noise in the reagent repo