Fork me on GitHub
#shadow-cljs
<
2019-05-17
>
Juho Leinonen08:05:04

Hello, I’m using shadow-cljs to build a reagent + re-frame app. What should I call during development in the :after-load function so that all components would be re-rendered with the changes in the code? I have tried calling (r/render [main-view] (.getElementById js/document "app")) again in that function and reagent.core/force-update-all, but the changes don’t seem to appear in the browser. Sorry if it’s more of a reagent question.

thheller08:05:03

hey. the issue isn't reagent its re-frame. I can't remember the exact name but something like (re-frame.core/clear-subscription-cache!) or so (in the after-load)

thheller08:05:51

typically you just re-render everything via r/render

thheller08:05:06

(defn ^:dev/after-load start
  []
  (r/render [app]
    (.getElementById js/document "app")))

(defn ^:export init
  []
  (router/start!)
  (rf/dispatch-sync [:initialise-db])
  (start))

Juho Leinonen08:05:38

Thank you. I’ll take a look in that function and return with my findings then 🙂

Juho Leinonen10:05:04

That didn’t seem to work 😕 Maybe I have done something wrong elsewhere.

thheller12:05:49

@juholei look at the browser console. shadow-cljs tells you what it is doing. if all that looks in order your code might be doing stuff that can't be hot-reloaded properly

Juho Leinonen12:05:44

Yeah the after-load function gets called correctly with shadow-cljs and re-frame subscriptions and events get their changes loaded correctly, so I guess I have something wrong with my views somewhere.

thheller12:05:37

if you keep references to potentially reloaded code in the state somewhere this can be the problem

Juho Leinonen13:05:19

Yeah it might be just that. I just noticed if I make changes to my front end routing related files (using reitit), then the changed views also update. And reitit puts a reference to the current view component to the app state, so seems like that may be the problem. Thanks for your help 🙂

Jacob Haag16:05:47

Hey all, I am playing around with the :release portion of my shadow-cljs project and have noticed that the released artifacts are trying to connect to . I'm not sure why this is required and if not was wondering how to disable this, any ideas?

lilactown16:05:50

it looks like your build has the shadow-cljs development stuff included. are you sure you’re running your release code?

thheller16:05:29

yeah that doesn't look like a development build

thheller16:05:08

make sure you are loading the correct output files. by default those will be the same as your development files so you might have something cached if the server doesn't handle that properly

Jacob Haag16:05:19

Okay, currently I am outputting the release'd files to a different location than the dev's, however, I can take a look at the caching, that might be the issue

thheller16:05:43

and did you adjust your HTML to load those files?

thheller16:05:29

you can easily tell if you are loading the actual release build by the size and number of requests made

Jacob Haag16:05:55

That's a good point, I'll dig in there

teawaterwire18:05:18

Curiosity question: how does shadow implement hot reloading? It doesn't say what library it uses in the manual https://shadow-cljs.github.io/docs/UsersGuide.html#_hot_code_reload

thheller19:05:24

@teawaterwire what do you mean by library? shadow-cljs handles the reloading stuff, no library used

thheller19:05:46

as far as the reloading is concerned it is pretty trivial to do given that everything is evaled in the same scope and namespaced

thheller19:05:05

so unlike regular JS we can manipulate that scope easily and just replace definitions on the fly

teawaterwire19:05:42

oh I see - sweet! Everybody's talking about figwheel but Shadow is actually doing hot reloading on its own as well 🙂

teawaterwire19:05:58

(sorry I was under the impression that Shadow used a library underneath - I was wrong 😄 )

thheller19:05:40

most of the magic happens here

thheller19:05:09

would actually be much less code if it wasn't for all the async support

thheller19:05:11

works a bit differently in figwheel but figwheel made the concept popular

teawaterwire19:05:56

interesting! So many goodies included in Shadow 🌟

MatrixNorm20:05:16

Hi. Is there an example of smooth development workflow with service worker? Say I want to build main.js and service-worker.js. They should be independent: if service-worker.js recompiles main.js shouldn't reload and vice versa. If service-worker.js changes browser should be notified to run unregister/register code.

thheller20:05:05

I typically recommend using something like https://developers.google.com/web/tools/workbox/ for service workers

thheller20:05:36

don't feel like CLJS much to offer in that area since its 90% ugly js interop

MatrixNorm21:05:26

Most simple thing like

{:main                  {:entries  [foo.core]}
 :service-worker {:entries  [foo.sw]
                              :depends-on #{:main}
                              :web-worker true}}
kinda "works" because there is reload notification in a browser when code in foo.sw is updated. Of course nothing happens because service-worker.js is not included in a page. But at least there is a hope to hook into (defn handle-message [{:keys [type] :as msg}] or smth like that and run unregister/register code for service-worker. msg map has all info to get to know when foo.sw is recompiled.

thheller21:05:18

you can always trigger the sw reload from the REPL

thheller21:05:15

service workers are kinda special so I would probably make a separate build for them

MatrixNorm21:05:33

Thanks, I didn't think about repl

thheller21:05:52

since they'll be responsible for loading your actual app code you can't really make them dependent on the app code