Fork me on GitHub
#shadow-cljs
<
2019-12-23
>
dpsutton00:12:51

That keyword doesn’t seem like it could possibly work

royalaid01:12:41

I think you might want [motion/div {:animate (clj->js {:scale 0.5})} "Hello"] or even [motion/motion.div {:animate (clj->js {:scale 0.5})} "Hello"]

royalaid01:12:55

But not having the setup in front of me makes it difficult

royalaid01:12:41

One thing you can try is to inspect the object motion in the browser console and see what attributes are on there to call into

fjolne08:12:20

in addition to @royalaid answer, there’s a good summary of programmatic vs data field access by David Nolen

thheller08:12:08

@grav turn on externs inference and add ^js tags for things it warns about. see https://shadow-cljs.github.io/docs/UsersGuide.html#infer-externs

grav11:12:06

Awesome, thanks!

thheller09:12:59

@bravilogy reagent interop with JS component is done via [:> (. motion -div) ...]. the slash notation (eg. motion/div) only works for actual namespace aliases, so things using :as in :require (eg. (:require ["thing" :as alias])) not :refer

mruzekw15:12:57

I’d like to try out the Patching Libraries feature mentioned here: https://shadow-cljs.github.io/docs/UsersGuide.html#_patching_libraries But I don’t see an example of how to do it. I’d like to patch com.fulcrologic.fulcro-native.alpha.components.

mruzekw15:12:37

My current src looks like

src
  main
    app
      ...

mruzekw15:12:26

Would I put com/fulcrologic/fulcro_native/alpha/components next to main or app?

thheller15:12:04

you put it so it matches the filename on the classpath

thheller15:12:22

so assuming your source path is src/main then src/main/com/fulcro....

mruzekw15:12:40

Okay, makes sense! I’ll try that out. Thanks

mruzekw15:12:00

A great feature btw

mruzekw15:12:13

I was so confused on how to do something like yarn link in the CLJS world

mruzekw15:12:01

Works! Thanks again

aisamu19:12:04

Hi! We might have run into a dashes-vs-underscores bug. The documentation states that we can access CLJS ns's on consumed JS files using a goog: prefix (i.e. import something from "goog:namespace") When we use such a JS file from Shadow and the CLJS ns contains dashes, things break.

;;;;;;;;;;;
;; company/name_with_dashes.cljs

(ns company.name-with-dashes)
(def ^:export Thing '...)

;;;;;;;;;;;
;; company/folder-with-dashes/helper.js
import {Thing} from 'goog:company.name-with-dashes'

;;;;;;;;;;;
;; company/component.cljs

(ns company.component
  (:require ["company/folder-with-dashes/helper.js" :as helper]))
While running tests involving company.component via :browser-test, shadow issues a warning:
shadow-cljs - failed to load module$node_modules$company$folder_with_dashes$helper
shadow.js.jsRequire @ js.js:71

failed to load company.component.js ReferenceError: with is not defined
    at Object.shadow$provide.module$node_modules$company$folder_with_dashes$helper (helper.js:xx)
    at Object.shadow.js.jsRequire (js.js:63)
    at Object.shadow.js.require (js.js:97)
    at eval (/js/cljs-runtime/company.component.js:xx)
    at eval (<anonymous>)
    at Object.goog.globalEval (test.js:827)
    at Object.env.evalLoad (test.js:2174)
    at test.js:2373
env.evalLoad @ test.js:2176
Digging into module$node_modules$company$folder_with_dashes$helper reveals:
...
var _immutable = require("module$node_modules$immutable$dist$immutable"),
_googCompany = global.company.name-with-dashes
                              ;; ^ can't have dashes on JS symbol, right?
Other than renaming the involved files, would there be a workaround for this?

thheller19:12:46

maybe try _ instead of -? otherwise rename ...

aisamu19:12:28

Using dashes (e.g. import {Thing} from 'goog:company.name_with_dashes') fails with The required namespace "company.name_with_dashes" is not available, it was required by "..." 😕

thheller19:12:21

hmm yeah. feel free to open an issue, should be easy to fix

👌 4
thheller19:12:27

just won't get to it in the next few days

aisamu19:12:32

OK! NP - you really shouldn't:christmas_tree:simple_smile !

Eric Ihli19:12:40

Is it expected that when I reload a ReactNative app in the emulator while connected to the app's repl that the repl will lose connection to the app and an npx react-native run-android will be required to get the repl back? Here's the workflow that I'm using.

bash$ npx react-native run-android
emacsλ (inf-clojure-connect "localhost" 5555)
shadow.cljs => (shadow/repl :app)
cljs.user => (+ 2 2)
4
;; Make some code changes and reload the app in the emulator to render them.
cljs.user => (+ 2 2)
;; Long delay
Timeout while waiting for REPL result.
Then the only way I've found to get the REPL working again is to re-launch the emulator with npx react-native run-android. It's a painfully slow development loop, so I feel like I'm doing something wrong.

thheller19:12:58

its a bug in react-native android. it keeps the old websocket connections open so shadow-cljs can't tell that they are gone

thheller19:12:58

you can try (shadow/repl-runtime-clear) in the CLJ REPL

thheller19:12:16

and then (shadow/repl :app) again

thheller19:12:27

(shadow/repl-runtimes) should list all connected runtimes

thheller19:12:44

why are you reloading the app though?

Eric Ihli19:12:50

:thumbsup: That worked. Thanks. Saved me a lot of time troubleshooting.

thheller19:12:21

hot-reload should take care of things?

Eric Ihli19:12:08

Would hot-reload make a difference? Wouldn't that cause me to get into this disconnected state every time I save a file rather than just when I manually reload?

thheller19:12:47

not the react-native hot-reload or live-reload

thheller19:12:05

the one shadow-cljs provides

thheller19:12:54

or do you want an actual app reload?

Eric Ihli19:12:33

Maybe I don't need to reload as often as I was. Most of my reloads are when I get a runtime error and the screen pops up that says "esc to dismiss" and "rr to reload" and I just hit "rr" to reload.

Eric Ihli19:12:01

But with shadow's autobuilding/live-reloading maybe I could just make the code change, save the file, and hit "esc"?

thheller19:12:14

hmm I actually don't know

thheller19:12:23

I don't do react-native development myself

thheller19:12:29

no idea if it can recover from errors

Eric Ihli20:12:13

Looks like it theoretically might be able to, but it's not working for me. https://facebook.github.io/react-native/docs/fast-refresh If you edit a module that only exports React component(s), Fast Refresh will update the code only for that module, and re-render your component. You can edit anything in that file, including styles, rendering logic, event handlers, or effects.

theasp21:12:31

@thheller how should a build hook print to stdout? This appears to print nothing, but works!

(defn exec [cmd]
  (let [{:keys [exit out err]} (apply sh cmd)]
    (if (zero? exit)
      (when-not (str/blank? out)
        (println out))
      (println err))))

(defn nexe
  {:shadow.build/stage :flush}
  [state src dest]
  (case (:shadow.build/mode state)
    :release
    (let [cmd ["nexe" "--output" dest src]]
      (print (fmt "Executing: %s" cmd))
      (exec cmd))

    true)
  state)

theasp21:12:00

Nevermind, it does print... Needed to restart the shadow-cljs server

thheller22:12:17

@ericihli fast-refresh doesn't work for CLJS. if you've never seen the hot-reload from CLJS in action I'd suggest looking at an example that has it built-in

Eric Ihli22:12:41

Thanks. I'm trying to spin up the app from the link you pasted above right now. I'll dig through that code before going back to my own project again.

thheller22:12:42

another example I made with just react-native, no expo

sparkofreason22:12:34

I'm trying to do the bare minimum to run some CLJS code in a REPL for a library I'm developing. Is there a good example project I can crib from for configuring using deps.edn and Atom/chlorine?

mauricio.szabo22:12:03

I think shadow support deps.edn. As for Atom, you'll connect to a socket repl (Chlorine will probably detect the port) and then use "Connect Embedded" from the command pallette

sparkofreason22:12:08

I'm just missing something in the configuration. I was able to connect the socket REPL, executed "Connect Embedded", but trying to eval from a .cljs file gives an error about not being connected to a ClojureScript REPL.

thheller23:12:47

@dave.dixon shadow-cljs node-repl or shadow-cljs browser-repl

thheller23:12:00

no clue how to connect to those using atom/chlorine though

thheller23:12:31

regular nrepl should work. when in CLJ you can select them via :node-repl or :browser-repl build ids

mauricio.szabo12:12:21

Chlorine connects to a socket-repl, and then you just run a command that will start the ClojureScript REPL (and then you'll be connected in both CLJ and CLJS

mauricio.szabo12:12:24

No need to configure any port on Shadow-CLJS side too, it'll detect the current port based on .shadow-cljs/socket.port (or something like that :))

thheller23:12:36

however that works in atom ..

4
Eric Ihli23:12:35

Ah hah. Zeroing in on my hot-reload/repl disconnect woes. I see in your example app you have a way of storing a reference to the root and you just swap it out in the after-load handler.

(defonce root-ref (atom nil))
(defonce root-component-ref (atom nil))
(defn render-root [root]
  (let [first-call? (nil? @root-ref)]
    (reset! root-ref root)
    ;; ...
And then re-natal has something similar.
(def cnt (r/atom 0))
(defn reloader [] @cnt [core/app-root])
;; Do not delete, root-el is used by the figwheel-bridge.js
(def root-el (r/as-element [reloader]))
I didn't copy from an example and don't have anything like that in my code.