Fork me on GitHub
#shadow-cljs
<
2019-11-14
>
Quest02:11:36

@pez just wanted to say thanks for https://github.com/PEZ/rn-rf-shadow , got this up & running fast. a bit easier than my previous experience using re-natal I see that the README notes source-maps aren't working, but according to https://clojureverse.org/t/upgrading-the-react-native-support/4669/21 they might be after shadow-cljs 2.8.44. Will report back with my findings tomorrow

pez05:11:19

@quest , cool! I get a bunch of warnings and errors when starting things up, but things work. Do you have those messages as well, or have you found out how to fix it?

Quest00:11:25

I don't have the log from starting up, but I did notice a lot of deprecations & some other warning that seemed concerning. The app is working, though

Quest01:11:24

I can confirm that source maps & breakpoint debugging work in Chrome after Enable Remote JS Debugging is checked per https://facebook.github.io/react-native/docs/debugging (`CMD + M` on OSX.) Nice work @thheller

12
👍 8
conan09:11:58

In the shadow-cljs user guide (Section 4.1 Source Paths), it says: > It is not recommended to separate source files by extension (eg. src/clj, src/cljs, src/cljc). For some reason this is widely used in CLJS project templates but it just makes things harder to use. https://shadow-cljs.github.io/docs/UsersGuide.html#_source_paths I've always done this for two reasons, first to make it easy to specify what's included in my frontend and backend builds, but also just to have things nicely separated when I'm developing. I'd be interested to hear why shadow recommends not to do this? I'm always up for simplifying things

thheller09:11:01

@conan splitting source paths makes sense sometimes. splitting by file extension does not IMHO. say you write a macro file for CLJS that is never used in CLJ. do you put it in src/clj just because? src/cljc just makes sharing annoying too. I pretty much always use setups like src/main/my/amazing/frontend/* and src/main/my/amazing/server/*

thheller09:11:32

still easy to separate out files when building uberjars etc. just exclude my/amazing/frontend*

thheller09:11:56

src/frontend and src/backend works too

thheller10:11:18

my main gripe is separating by file extension thats all

conan10:11:13

Hmm, I see. It's sharing the code between the two that my src/cljc folder is for

thheller10:11:30

src/main/my/amazing/shared works fine too

conan10:11:52

I like the idea of being explicit about what each folder is for though, with frontend and backend for example. I've never come across a situation where that wasn't a 1:1 mapping with file extension though

thheller10:11:06

have you written macros?

conan10:11:37

Only very occasionally, but also only ever in clj, for use in clj

conan10:11:20

Anyway, this all feels like preference, so it's good that there's lots of flexibility. There's no technical advantage as far as shadow is concerned though?

conan10:11:17

I can definitely see how the macro situation would cause me to rename my folders though

thheller10:11:26

if this setup works for you then use it

thheller10:11:28

I just think it is unnecessary confusing

thheller10:11:53

shadow-cljs doesn't care what the names are as long as the source-path is setup correctly

thheller10:11:17

so historically there may have been reasons as to why separating made sense

conan10:11:59

oh good post, that answers a question i had about why :modules is needed too, thanks!

Lucas Barbosa13:11:41

Hey guys, Was there any significant change in the websocket connection from the browser to the repl from 2.8.68 to 2.8.69? If I do the update, my application doesn't connect to the repl anymore :thinking_face:

Lucas Barbosa13:11:18

This message does not show up on the browser console in 2.8.69 to me:

shadow-cljs: WebSocket connected!
browser.cljs:26 shadow-cljs: REPL session start successful

Lucas Barbosa13:11:56

I wish I had more useful information, but this is what appears in my browser's console in 2.8.69:

Installing CLJS DevTools 0.9.10 and enabling features :formatters :hints :async
client.cljs:356 Installing Fulcro Inspect {}
This is what appears in 2.8.68:
Installing CLJS DevTools 0.9.10 and enabling features :formatters :hints :async
client.cljs:356 Installing Fulcro Inspect {}
browser.cljs:26 shadow-cljs: WebSocket connected!
browser.cljs:26 shadow-cljs: REPL session start successful
Is there something I can do to provide more helpful context?

thheller13:11:33

assuming you are running shadow-cljs watch the-build?

Lucas Barbosa13:11:37

In 2.8.68 I'm able to connect emacs to the repl using CIDER. In 69, I get a "no client connected to the repl" sort of message and I can't evaluate stuff

thheller13:11:56

any clue in the browser console?

thheller13:11:12

there should be a websocket request open?

thheller13:11:18

maybe that is timing out or something?

Lucas Barbosa13:11:31

I will take a look on the network tab. Didn't try it before, just a sec

thheller13:11:02

you can try checking if shadow.cljs.devtools.client.browser exists in the browser console?

Lucas Barbosa14:11:48

Ok, so, on 2.8.69, there is no websocket connection attempt on the network tab in the console, and shadow.cljs.devtools.client.browser.cljs is loaded in the browser (prints in the thread)

thheller14:11:14

> (prints in the thread)

thheller14:11:17

what does that mean?

Lucas Barbosa14:11:26

Printscreens in the slack thread xD

thheller14:11:25

please actually run what I pasted in the browser console

thheller14:11:51

if that namespace is loaded it should have connected directly on startup? no clue why it wouldn't have?

Lucas Barbosa14:11:48

Yes, the reference exists

Lucas Barbosa14:11:45

If I type shadow.cljs.devtools.client.browser.cljs in the console, I get an object back

thheller14:11:15

I'm assuming without the last .cljs?

thheller14:11:23

because that would be wrong?

Lucas Barbosa14:11:44

oops, excuse me. Yes, without the .cljs suffix

thheller14:11:56

what is shadow.cljs.devtools.client.env.enabled?

thheller14:11:35

oh. do you use lein or deps.edn?

thheller14:11:34

hit up shadow-cljs clj-repl then ( "goog/base.js"). I'm guessing you have an old closure-library version

thheller14:11:04

should be 0.0-20191016-6ae1f72f

Lucas Barbosa14:11:59

Yes, we do use lein here!

shadow.user=> ( "goog/base.js")
#object[java.net.URL 0xdad8889 "jar:file:/Users/lucas.barbosa/.m2/repository/org/clojure/google-closure-library/0.0-20170809-b9c14c6b/google-closure-library-0.0-20170809-b9c14c6b.jar!/goog/base.js"]

Lucas Barbosa14:11:13

we do have a mismatch :thinking_face:

thheller14:11:23

yes, that is the rather old one

thheller14:11:45

[com.google.javascript/closure-compiler-unshaded "v20191027"]

   [org.clojure/google-closure-library "0.0-20191016-6ae1f72f"]
   [org.clojure/google-closure-library-third-party "0.0-20191016-6ae1f72f"]

thheller14:11:55

you can add those manually I guess

dpsutton14:11:00

@thheller what made you suspect an out of date google closure?

thheller14:11:03

the .env/enabled is a goog-define and goog.define was changed in the latest closure compiler/library release

👍 4
p-himik14:11:57

shadow-cljs displays an empty error message when I do something stupid with macros:

;; test.clj
(defmacro dummy []
  `(defmulti x ~identity))

;; test.cljs
(dummy)
The error:
------ ERROR -------------------------------------------------------------------
 File: /.../test.cljs
Error in phase :compilation

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Not sure if that could be handled at all.

Lucas Barbosa14:11:27

I’ll try the dependency bump and let you guys know! Thanks for the awesome support @thheller !

Derek15:11:49

Is there a way to not include a component in a release build? I guess other than module splitting, some sort of function/macro that depends on :shadow.build/mode

isak16:11:01

Are you using advanced? If so, you can just rely on dead code compilation. Here is an example: https://github.com/day8/re-frame/blob/69a3fcd411369fff65404e7d6a924ce1968e2dba/src/re_frame/registrar.cljc#L37-L39

Derek16:11:06

I’ll give this a shot. Thank you

4
orestis15:11:01

I’m trying to implement code splitting based on https://code.thheller.com/blog/shadow-cljs/2019/03/03/code-splitting-clojurescript.html , but instead of reagent I’m using hx. Everything works fine, but hot reloading doesn’t seem to work. Shadow does detect the changed code, and does reload the changed namespace, and does call the “after-load” fn, but then React seems to skip over rendering the lazy component.

orestis15:11:25

I’m using the “trick” to wrap the component in an extra level, but doesn’t seem to have any effect.

thheller16:11:14

@orestis what did you try? the demo.util used in that post should be working with hot-reload

thheller16:11:34

but you can't skip the step done in demo.util

orestis16:11:03

(defn lazy-component* [loadable]
  (React/lazy
   (fn []
     (js/console.log "still lazy?")
     ;; React lazy expects a promise, that returns an ES6 module with a React Component as default export
     (-> (shadow.lazy/load loadable)
         (.then
          (fn [root-el]
            (if-not js/goog.DEBUG
              ;; in production mode, just do that
              #js {:default root-el}
              ;; in dev mode, we need wrap the loaded component one
              ;; extra level so live-reload actually works since React
              ;; will keep a reference to the initially loaded fn and
              ;; won't update it
              #js {:default (fn [props]
                              (js/console.log "lazy render")
                              (js/console.log (@loadable #js {}))
                              (React/createElement @loadable props)
                              (hx/f [LazyComponentWrapper {:loadable loadable :props props}])
                              (hx/f [LazyWrap {:loadable loadable :props props}])
                              )})))))))

orestis16:11:18

I can’t even get the “lazy render” to log out.

orestis16:11:39

^There’s a bunch of experiments with different approaches, but non of them work.

thheller16:11:49

yes cause they are all wrong 😛

thheller16:11:25

the :default (fn [props] is called ONCE on initial load

orestis16:11:32

*They work with the first render, but not on the hot reload.

thheller16:11:32

it'll never be called again

thheller16:11:51

so whatever will be happening again ... must deref the loadable

thheller16:11:11

(r/reactify-component (fn [props] [@loadable props]))

orestis16:11:24

Right, so I need to close over the loadable, and deref it again on render, right?

orestis16:11:40

That’s what the LazyComponentWrapper thing does, but it doesn’t seem to have any effect.

orestis16:11:49

(hx/defnc LazyComponentWrapper [{:keys [loadable props]}]
  (js/console.log "LOADABLE  dereffed" @loadable)
  [@loadable (bean props)])

orestis16:11:57

The log doesn’t even print.

thheller16:11:24

well that might be hx short circuiting because neither loadble nor props changed?

thheller16:11:33

dunno what it actually does

orestis16:11:51

I think it’s React short-circuiting, because it’s a functional component.

thheller16:11:11

react doesn't short circuit, unless you memo stuff

orestis16:11:58

hx doesn’t either — unless I’m very confused.

orestis16:11:54

I’m knackered for the day, but thanks for the confirming the general approach — return a wrapper that will deref the loadable on every render, to get the latest version.

orestis16:11:43

I’ll try a minimal shareable repro and see what happens.

thheller23:11:02

aaaaaaaaaaaaaarghh ... sabotaged by vscode ...

thheller23:11:48

trying to write a description of the component stuff I've been working on and vscode just deleted half of it ...

😭 8
😬 8
thheller23:11:35

seriously .. I don't even know how it got into the state it is in now ... pressing undo/redo just makes arbitrary changes and makes things worse

pez05:11:45

Is this in a regular editor? Are you using macos? Checking because I have similar issues in Calva's REPL window, but only on Mac.

thheller09:11:03

windows, regular vscode + vim

thheller23:11:58

guess I'm done with vscode

isak23:11:25

are you using vim-mode? i heard it has wierd interactions with the normal undo/redo system

thheller23:11:36

indeed I do

Quest01:11:24

I can confirm that source maps & breakpoint debugging work in Chrome after Enable Remote JS Debugging is checked per https://facebook.github.io/react-native/docs/debugging (`CMD + M` on OSX.) Nice work @thheller

12
👍 8