Using Backend Languages for Frontends

Why ClojureScript is an awesome idea!

6
Cities

21
Countries

≈900
Employees

>1000
Services

Remote
First

Why CLJ?

  • Simple
  • Interop
  • Functional
  • LISP

Why CLJS?

  • Simple
  • Interop
  • Ecosystem
  • Tooling

But ...

  • Curve
  • Community
  • Adoption
  • Performance
nil
Powered by https://github.com/viebel/klipse
Powered by https://roman01la.github.io/javascript-to-clojurescript/

First Steps in a Project


Important files
  • deps.edn
  • shadow-cljs.edn
  • package.json
     
     
Framework: reframe
  1. Events
  2. Effects
  3. Queries
  4. Views
  5. DOM

deps.edn


          {
           :paths    ["src"]
           :deps      {org.clojure/clojure        {:mvn/version "1.10.3"}
                       org.clojure/clojurescript  {:mvn/version "1.10.844"}}
          
           :mvn/repos {"central" {:url "https://repo1.maven.org/maven2/"}
                       "clojars" {:url "https://repo.clojars.org/"}}
          
           :aliases   {:watch      {:main-opts  ["-m" "shadow.cljs.devtools.cli" "watch" ":app"]
                                    :extra-deps {thheller/shadow-cljs {:mvn/version "2.12.5"}}}
                       :run-server {:main-opts ["-m" "cljs-webshop.core"]}}
          }
        

shadow.cljs


          {
            :deps true
            :nrepl {:port 8777}
            :builds {:app {:target :browser
                           :modules {:base {:init-fn cljs-webshop.core/init}}
                           :output-dir "resources/public/js/compiled"
                           :asset-path "/js/compiled"}}
          }
        
1 Event dispatch Sending events
2 Event handling Take actions
3 Effect handling Sideeffects where data are actions
4 Query Extracting data from 'app state'
5 View Render UI
6 Dom Done by Reagent/React

Domino 1 - Event Dispatch


          (defn delete-button [item-id]
            [:div.garbage-bin 
              :on-click #(re-frame.core/dispatch [:delete-item item-id])])
        

Domino 2 - Event Handling


          (re-frame.core/reg-event-fx   ;; a part of the re-frame API
            :delete-item                ;; the kind of event
            del-item)                   ;; the handler function for this kind of event
        

          (defn del-item
            [coeffects event]                 ;; `coeffects` holds the current state of the world
            (let [item-id  (second event)     ;; extract id from event vector
                  db       (:db coeffects)    ;; extract the current application state
                  new-db   (dissoc-in db [:items item-id])]   ;; new app state
              {:db new-db}))                  ;; a map of the necessary effects 
        

Domino 3 - Side Effect Handling


          (re-frame.core/reg-fx         ;; part of the re-frame API
            :db                         ;; the effects key 
            (fn [val]                   ;; the handler function for the effect
              (reset! app-db val)))     ;; put the new value into the ratom app-db
        

v=f(s)


A view, v,
is a function, f,
of the app state, s.

Domino 4 - Query State from DB


          (defn query-items
            [db v]         ;; db is the current value in app-db, v the query vector
            (:items db))   ;; not much of a materialised view
        

          (re-frame.core/reg-sub  ;; part of the re-frame API
            :query-items          ;; query id  
            query-fn)             ;; function to perform the query 
        

Domino 5 - Subscribe the View


          (defn items-view
            []
            (let [items  (subscribe [:query-items])]  ;; source items from app state
              [:div (map item-render @items)]))       ;; assume item-render already written
        

Domino 6 - DOM

tbsschroeder (link)
Dr. Tobias Schrรถder (link)
tobias.schroeder@metro.digital (link)