Fork me on GitHub
#shadow-cljs
<
2018-03-12
>
orestis09:03:54

I have been doing some electron work in plain JS recently — one side is the “server” side which is Node with some extra electron APIs you require. The other side is the client side with also some extra APIs. I think it could be treated as just two separate targets…

mhuebert10:03:38

Would anyone else also find it useful to be able to specify a vector of functions for :before-load and :after-load in devtools options?

mhuebert10:03:18

I end up making on-reload! functions which only exist to trigger cleanup/reset behaviour from namespaces which have no other relationship to each other

thheller10:03:33

@orestis wasn't the browser/renderer side also able to use require?

orestis10:03:13

@thheller I think so, yes — but I haven’t dug that deep yet.

orestis10:03:46

IIRC you are able to require the electron APIs from both sides, but the browser side gets access to the “remote” part of that.

orestis10:03:56

So some kind of built-in RPC I think.

orestis10:03:42

I’m not sure how that works, but for shadow to do its thing you should just be able to expose a require function, no?

thheller10:03:46

@mhuebert I could certainly add that but it sounds like you have some global state that needs refreshing? global state is tricky when it comes to reloading.

orestis10:03:10

I might toy around with shadow and electron today as a break.

thheller10:03:18

@orestis either way you can definitely build something with shadow. if require is possible you might get away with one build instead of two though.

mhuebert10:03:04

@thheller the 3 things I currently do on reload are (1) clear a global error state which is set when a react component throws, (2) re-render react component tree from root, and (3) I have a logging lib which uses logging groups, and open groups need to be closed on refresh

orestis10:03:07

I’ll have to check and see what the assumptions are — because one side is definitely no-browser, whereas the other side yes-browser.

thheller10:03:50

@mhuebert you could do this in :before-load maybe?

mhuebert10:03:54

@thheller I think if i would clear the error state before load, that would trigger a re-render before the new (possibly-fixed) views have been loaded

mhuebert10:03:16

the logging stuff could be though

thheller11:03:06

and just calling the other on-reload! fns directly from your one on-reload! doesn't work?

mhuebert11:03:07

that does, it was just mildly awkward because i didn’t have any existing namespace which could require all of the namespaces which had functions to be called

mhuebert11:03:36

so i had to create a separate thing in a utility library which all of these namespaces could then require, and register on-load functions

mhuebert11:03:45

eg

(defonce on-reload* (atom {}))

(defn on-reload
  "Register a callback to fire when page reloads (during development)"
  [key f]
  (swap! on-reload* assoc key f))

(defn reload!
  "Fire registered reload callbacks"
  []
  (doseq [f (vals @on-reload*)]
    (f)))

thheller11:03:46

the trouble with a vector of multiple :after-load fns is that it can't control async

mhuebert11:03:29

i wasn’t thinking about that for my case

mhuebert11:03:42

this will be fine for now

thheller11:03:30

I was thinking about this zero-conf stuff a bit. we could certainly have some other ways to configure these hooks

thheller11:03:52

eg. (ns my.awesome.stuff {:shadow/after-load some-fn-in-this-ns} ...)

thheller11:03:09

ns meta doesn't hurt since it doesn't end up in optimized code

mhuebert11:03:22

as a library author, if someone uses re-view it would be nice to say “and add re-view.render-loop/render to your :after-load option”

mhuebert11:03:45

yeah that would be cool

mhuebert11:03:57

better than having to give instructions

thheller11:03:30

could also just put it on the fn itself

thheller11:03:43

(defn ^:shadow/after-load on-reload! [] ...)

thheller11:03:25

compiler could even be smart and just ignore those fns when compiling release builds

mhuebert11:03:18

i guess the downside is that for a library that is less good, as you don’t want to impose specific tooling on users. not that metadata imposes it, but you don’t want (defn ^:shadow/after-load , ^:figwheel/after-load ...) (*I can’t remember what metadata figwheel all uses, i remember something like ^:figwheel-always)

thheller11:03:51

sure we could do something generic that other tools could support as well

thheller11:03:16

I think this is only an issue with global state though which you shouldn't have in the first place 😛

mhuebert11:03:48

haha. in a dream world

thheller11:03:05

I always unmount in :before-load just to avoid things interfering with reload

tianshu15:03:24

seems there're two styles for configuration for clojure now lein style and tools.deps style: paths vs source-paths, deps vs dependencies, repos vs repositories. will it be a good idea to support both or insisting on the lein style or just like user use tools.deps with shadow-cljs?

thheller16:03:31

@doglooksgood don't know about allowing two different styles in shadow-cljs.edn itself but maybe