Fork me on GitHub
#clojurescript
<
2018-03-18
>
justinlee06:03:32

Thanks @U0W0JDY4C. I’ll be sure to take a look tomorrow.

athomasoriginal16:03:04

This is a nice post, but I feel that some items, like "Lastly, the Clojurescript developer experience in terms of ergonomics, speed to delivery, extensibility, and bug-to-feature ratio is phenomenal" are not exactly valid. When working with large CLJS applications, setting up a workflow comparable to one in JS is not where I would expect it to be. I honestly found setting this up was considerably more challenging than webpack. I feel what I am trying to say is we say these things, but when people come to the language, they are consistently slapped in the face by the learning-curve.

athomasoriginal16:03:19

I too believe that CLJS should be the answer, but the learning curve often gets in the way of the good stuff.

lwhorton20:03:29

I think that’s kind of my point no? A steep learning curve with sufficient payoff on the other side should be reason enough to climb the curve

sound2gd10:03:13

Hi, I am working with shadow-cljs and re-frame but stucked when use devtools like this

sound2gd10:03:27

clojurescript
        :devtools {:after-load shadow-gen.core/mount-components
                   :preloads [devtools.preload
                              day8.re-frame-10x.preload]}

`

sound2gd10:03:04

it shows warnings like this

------ WARNING #3 --------------------------------------------------------------
 File: day8/re_frame_10x/view/parts.cljs:30:34
--------------------------------------------------------------------------------
  27 |               [:h1 "FX"]
  28 |               (render-registered re-frame.fx/kind)
  29 |               [:h1 "co-fx"]
  30 |               (render-registered re-frame.cofx/kind)
----------------------------------------^---------------------------------------
 Use of undeclared Var re-frame.cofx/kind
--------------------------------------------------------------------------------
  31 |               ]])
--------------------------------------------------------------------------------

sound2gd10:03:41

some has ideas how? thanks in advance

thheller10:03:18

@sound2gd should have been fixed. not sure if a new version was released yet though. https://github.com/Day8/re-frame-10x/pull/164

sound2gd10:03:22

(defn hook-browser-navigation! []
  (doto (History.)
    (events/listen
      HistoryEventType/NAVIGATE
      (fn [event]
        (secretary/dispatch! (.-token event))))
    (.setEnabled true)))
and the function hook-browser-navigation! will cause entire dom been removed, after debug I found it is js-reload which cause this

thheller10:03:19

make sure the (History.) is only done once and not again on live-reload.

sound2gd10:03:05

@thheller I copied from your repo , but when reload, it broked

thheller10:03:00

hmm I'll check it out

sound2gd10:03:30

thanks, here is my shadow-cljs config

;; shadow-cljs configuration
{:source-paths
 ["src/cljs" "env/dev/cljs/"]

 :dependencies
 [[org.clojure/clojurescript "1.9.946"]
  [re-frame "0.10.5"]
  [reagent "0.7.0"]
  [secretary "1.2.3"]
  [markdown-clj "1.0.2"]
  [cljs-ajax "0.7.3"]
  [day8.re-frame/re-frame-10x "0.2.0"]
  [binaryage/devtools "0.9.9"]
  ]

 :verbose true

 :builds
 {:app {:target :browser
        :output-dir "target/cljsbuild/public/js"
        :asset-path "/js"
        :dev
        {:compiler-options {:closure-warnings {:global-this :off}
                            :closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}
                            :source-map true
                            :optimizations :none
                            :pretty-print true}
         }
        :modules {:app {:entries [shadow-gen.app]}}
        :devtools {:after-load shadow-gen.core/mount-components
                   ;; :preloads [day8.re-frame-10x.preload]
                   }
        }}
 }

sound2gd10:03:38

app.cljs can not reload when having hook-browser-navigation! init function...

thheller10:03:13

like I said I think its not safe to create the History instance twice

sound2gd10:03:29

yes you are right

sound2gd10:03:04

working with fighwheel there is meta like ^:figwheel-no-load

sound2gd10:03:27

can shadow-cljs do something like this

thheller10:03:16

(defonce history-ref (volatile! nil))
(defn hook-browser-navigation! []
  (when-not @history-ref
    (let [history (History.)]
      (vreset! history-ref history)
      (doto history
        (events/listen
          HistoryEventType/NAVIGATE
          (fn [event]
            (secretary/dispatch! (.-token event))))
        (.setEnabled true)))))
try this

sound2gd10:03:03

it worked 🙂

sound2gd10:03:22

but a meta like ^:figwheel-no-load is needed because one can not run init! and destroy state every time

thheller10:03:01

why are you calling init! again?

sound2gd10:03:13

;; -------------------------
;; Initialize app

(defn mount-components []
  (rf/clear-subscription-cache!)
  (r/render [#'page] (.getElementById js/document "app")))

(defn init! []
  (rf/dispatch-sync [:initialize-db])
  (load-interceptors!)
  (hook-browser-navigation!)
  (mount-components))
init! only need run once, then use :after-load task

sound2gd10:03:04

my entry file is shadow-gen.app , the code is only call init! from core

thheller10:03:35

ah now I get it ... sorry I was confused by the setup

sound2gd10:03:39

when i change other file, it re-runed init!

sound2gd10:03:17

it's ok , thanks for your shadow-cljs work, it's great for cljs I think

sound2gd10:03:09

now I want some methods to prevent re-load from init! ....

thheller10:03:38

well you could do this

(defonce init-complete-ref (volatile! false))
(defn init! []
  (when-not @init-complete-ref
    (load-interceptors!)
    (fetch-docs!)
    (hook-browser-navigation!)
    (mount-components)
    (vreset! init-complete-ref true)))

thheller10:03:09

I will add support for some of the metadata stuff figwheel supports as well

thheller10:03:14

maybe later today

sound2gd10:03:14

thanks you , I export my init! function like this

(defn ^:export init! []
  (rf/dispatch-sync [:initialize-db])
  (load-interceptors!)
  (hook-browser-navigation!)
  (mount-components))
and call shadow_gen.core.init_BANG_(); from index.html and solved this

sound2gd10:03:35

html
    <script type="text/javascript">
     var context = "{{servlet-context}}";
     var csrfToken = "{{csrf-token}}";
     shadow_gen.core.init_BANG_();
    </script>

thheller10:03:50

thats a good way too

sound2gd10:03:54

entry been replaced to shadow-gen.core

sound2gd10:03:22

thanks for your help 🙂

benzap11:03:22

are atoms and volatile the same implementation in javascript?

thheller12:03:18

@benzap no, atom has watchers. volatile does not.

benzap12:03:59

when is the appropriate time to use each? I tend to use atoms, and I almost never use watchers

thheller12:03:34

personal preference I guess. the "overhead" of atoms without watchers is super minimal so probably safe to always use atom

benzap12:03:36

yeah, I figured the volatile stuff has much less overhead in the clojure-domain, i've just been seeing it a lot more lately

mfikes12:03:12

Yeah, I'd use atoms and volatiles as intended. For me, this is helpful to keep one mental model when switching to Clojure where the semantics matter a little more.

hmaurer12:03:19

Hi! I have a quick newbie question. I am working with Boot and Clojurescript, and I would like to build my code as a library that I can then import as a node module. It would also be fine if I could build my code as a single bundle.js with my exports set as globals, but right now Boot seems to generate a bunch of files (one for each namespace I think). Not sure how to get a single bundle

mfikes12:03:20

I have this dream that one day JavaScript may allow for multi-threaded, adopting a memory model similar to Java's. And in that case ClojureScript could perhaps be ready for it. Of course, lots of code would break. But, maybe properly using atoms instead of volatiles would be one tiny bit less than would break. 🙂 https://webkit.org/blog/7846/concurrent-javascript-it-can-work/

justinlee16:03:34

gah this is not a dream, it’s a nightmare 😛

benzap00:03:28

It will be strange to see people using core.async outside of a (go) block in clojurescript

mfikes12:03:16

@hmaurer If you use any of the Closure modes (`:whitespace` to :advanced) you get one file

mfikes12:03:16

And if you use :advanced you need to use ^:export to make symbols available to JavaScript

hmaurer12:03:51

@mfikes ah, thank you so much!

hmaurer12:03:16

also, is there a better way to compile a CLJS project to be imported in webpack/node than to use globals?

mfikes12:03:09

I've never used :output-wrapper. I wonder if that's what it is intended to do. https://clojurescript.org/reference/compiler-options#output-wrapper

hmaurer12:03:52

@mfikes I’ll check that. Thanks again 🙂

Oleh K.13:03:24

There is an option in react native packager to add custom transformer for files. I wonder if I could somehow to use shadow-cljs (or maybe lumo suites better) like a transformer for cljs files. It would be something like this: https://github.com/kristerkari/react-native-css-transformer/blob/master/index.js

thheller13:03:36

@okilimnik I saw your ticket. Didn't have time to look the react-native stuff yet. come on by #shadow-cljs, we can brainstorm later. trying to finish something else first.

Oleh K.13:03:36

@thheller okay, thank you

gfredericks14:03:05

I'm using sablono and react and am having trouble with checkboxes

gfredericks14:03:13

I can get a checkbox to initially show up with the correct state using the :checked property, but future changes to that property seem to be ignored in the UI

gfredericks14:03:06

is there anything special/weird about checkboxes?

justinlee16:03:20

let’s have one language where we never have to worry about concurrency

mfikes18:03:45

Well, the language is called "Clojure" and I'd hope ClojureScript as well in the future 😜

Josh Horwitz18:03:45

Are there any guides/examples of using ClojureScript for back end node projects? Trying to perhaps implement one at work