Fork me on GitHub
#shadow-cljs
<
2020-01-10
>
Eric Ihli04:01:07

I'm trying to re-implement https://github.com/thheller/reagent-react-native/blob/master/src/main/test/app.cljs to get a better understanding of how things work. I got the gist of it, but I'm stuck wondering why I need to reset the component reference before calling forceUpdate on the wrapper. Can anyone shed light on that? See the following code for reference. Thanks. https://github.com/eihli/cljs-react-native-starter/blob/1e7721b9d82b0a2163fb83f03534c341e5a59a77/src/example/core.cljs

(defn make-reloader [comp]
  (let [comp-ref (atom comp)
    ;; ...
    (rn/AppRegistry.registerComponent "ExampleApp" (fn [] wrapper))
    (fn [comp]
      (when-let [wrapper @wrapper-ref]
        ;; Why do we need to reset the component here?
        ;; Why doesn't calling forceUpdate on the parent-most component
        ;; cause everything to re-render?
        ;; Is there a downside to doing it this way? Is there an alternative?
        (reset! comp-ref comp)
        (.forceUpdate @wrapper-ref)))))

Eric Ihli04:01:13

The alternative that I'm confused about is mentioned at https://code.thheller.com/blog/shadow-cljs/2019/08/25/hot-reload-in-clojurescript.html under the section "Hooking up React". Is this not a viable alternative because we don't have a dom in ReactNative? Is it not possible to call a reagent function that requires a real dom?

(defn ^:dev/after-load start []
  ;; dummy prop that always changes
  (reagent/render [ui {:x (js/Date.now)}] dom-root))

thheller09:01:22

@ericihli in react-native you must register a "root" component on startup which react-native will then render. you can only register it once though, you cannot replace it afterwards in hot-reload. thats what the wrapper is for.

Björn Ebbinghaus12:01:39

Is there a config key to specify the local repo location for the deps? Like with clojure you have: clojure -Sdeps '{:mvn/local-repo ".m2"}' I can't seem to find it.

thheller12:01:35

well do you use deps.edn or shadow-cljs.edn?

Björn Ebbinghaus12:01:29

deps are in deps.edn

thheller12:01:37

then you declare it there?

Björn Ebbinghaus13:01:25

I just want to set it in my CI and run it like this npx shadow-cljs compile ci-tests I don't want to permanently change it.

thheller13:01:59

if you use deps.edn you must use deps.edn related things to do stuff

thheller13:01:19

clojure -Sdeps '{:mvn/local-repo ".m2"} -m shadow.cljs.devtools.cli compile ci-tests

thheller13:01:11

or put it into the ~/clojure/deps.edn on the CI system

thheller13:01:36

there is no setting in shadow-cljs.edn to "modifiy" the deps.edn config

Björn Ebbinghaus13:01:59

the use of the cli ns is the solution. thank you!

Eric Ihli13:01:08

I mentioned above that I'm trying to better understand this https://github.com/thheller/reagent-react-native/blob/master/src/main/test/app.cljs Does anyone see a real difference between the render-root there and the following? Through my surface-level testing and current understanding, they appear to function the same.

(defn make-reloader [comp]
  (let [comp-ref (reagent/atom comp)
        wrapper (reagent/create-class
                 {:render
                  (fn []
                    (let [comp @comp-ref]
                      (if (fn? comp) (comp) comp)))})]
    (rn/AppRegistry.registerComponent "ExampleApp" (fn [] wrapper))
    (fn [comp]
      (reset! comp-ref comp))))

Filipe Silva13:01:30

heya is there a way using shadow-cljs run (or something else similar) of running clj-kondo like the lein/tools.deps example in https://github.com/borkdude/clj-kondo/blob/master/doc/jvm.md?

thheller13:01:25

shadow-cljs run clj-kondo.main?

Filipe Silva13:01:13

yeap that does it, will add to the guide there

thheller14:01:25

@filipematossilva might be worth mentioning that if a shadow-cljs server (or shadow-cljs watch) is running the startup will be much faster

thheller14:01:40

otherwise starting a new JVM instance with shadow-cljs and kondo loaded will take forever

kenny16:01:07

I'm working with highcharts and have it required like this ["highcharts/highcharts" :as highcharts]. I'm then importing the histogram module like this ["highcharts/modules/histogram-bellcurve" :as histogram]. There is some issue with how I'm using the histogram module that I'd like to debug. When clicking an item in a stacktrace in the browser that points to some code in the histogram module, I get minified code. Is there a way to use the non-minified code for development and switch to the minified in production?

kenny16:01:19

Changing the require to ["highcharts/modules/histogram-bellcurve.src" :as histogram] got me the source.

kenny17:01:18

Woah ok. I'm a bit out of depth in js land at this point but something is broken in either shadow or highcharts. So you have to initialize the highcharts histogram module like this

(ns example
  (:require
    ["highcharts/highcharts" :as highcharts]
    ["highcharts/modules/histogram-bellcurve" :as histogram]))

(histogram highcharts)
However, if I do that, I will get an exception saying e is not a function. It's pretty useless because the file is minified. So I switch the histogram require to point to the source JS file: ["highcharts/modules/histogram-bellcurve.src" :as histogram] . After running the code, I get an exception giving me more info: "correctFloat is not a function". This "correctFloat" function is provided by some Utilities module. I end up changing the highcharts require to ["highcharts/highcharts.src" :as highcharts] in hopes I get some more information. After changing the require, everything works! Using the highcharts/highcharts results in a function missing. Any idea why this would happen and whether this is a shadow issue or a highcharts issue?

kenny17:01:19

In the histogram-bellcurve.js file, there is this:

_registerModule(_modules, 'modules/bellcurve.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/derived-series.js']], function (H, U, derivedSeriesMixin) {
        var correctFloat = U.correctFloat,
I don't entirely know what this means but it appears that it is trying to lookup the correctFloat function at the path ["_modules"]["parts/Utilities.js"]["correctFloat"]. If I try to lookup that path in the browser console,
compute.ui.components.highcharts.h._modules["parts/Utilities.js"].correctFloat
=> undefined
I can, however, find other functions at that path
compute.ui.components.highcharts.h._modules["parts/Utilities.js"].arrayMax
=> fn

kenny17:01:39

It appears like the correctFloat is entirely missing from the place the histogram-bellcurve module is looking for it. Could this be because it was DCE'ed? I thought shadow doesn't do that with npm modules. Or perhaps it's a highcharts issue?

kenny17:01:36

It wouldn't appear to be a highcharts issue since I can create a histogram here: https://jsfiddle.net/4vtb6q5e/

kenny17:01:15

I can replicate this issue in both highcharts 8.0.0 and 7.2.1

kenny17:01:52

I ran the minified highcharts.js file through an unminifier and uploaded it here: https://gist.github.com/kennyjwilli/37d7856abdd56b4ee282a869fbe0abd0. On line 584 you can see the correctFloat being assigned to r: https://gist.github.com/kennyjwilli/37d7856abdd56b4ee282a869fbe0abd0#file-highcharts-unmin-js-L584. Line 116 has the definition for r: https://gist.github.com/kennyjwilli/37d7856abdd56b4ee282a869fbe0abd0#file-highcharts-unmin-js-L116. This function definitely exists in the code base then. Line 51 you can see it is defined within the parts/Utilities.js module: https://gist.github.com/kennyjwilli/37d7856abdd56b4ee282a869fbe0abd0#file-highcharts-unmin-js-L51

kenny17:01:12

So somewhere between the file definition and page render, the correctFloat function is removed.

kenny17:01:10

I added

<script src="https://code.highcharts.com/highcharts.js"></script>
to my index.html and set
:js-options {:resolve {"highcharts/highcharts" {:target :global
                                                :global "Highcharts"}}}
in shadow-cljs.edn. After doing so, things work as expected. It would seem like shadow is removing that function for some reason. Is there a way to fix this?

kenny18:01:04

Does shadow expect that the imported npm module be pointing to a non-minified or minified version of the source?

kenny18:01:15

It seems like requiring highcharts/highcharts.src work in development and results in a minified version in production. I guess I'll go with that for now. This was quite confusing.

thheller19:01:54

@kenny why ["highcharts/highcharts" :as highcharts]? the docs would suggest that ["highcharts" :as highcharts] would be the correct on to use?

thheller19:01:27

doesn't matter in this case but it makes things really hard to follow if you don't follow the official docs

kenny22:01:07

I could swear I tried that before and it didn't work. Just tried it again and it does.