How to start with clj + shadow-cljs + rum

I would like to get started experimenting with a fullstack clojure/clojureScript application.
To learn to understand the basic structure I’d like to use the most basic tooling, no lein, no figwheel, no boot, no luminus. Only Clojure (+ring +reitit +rum) and ClojureScript (+rum +shadow-cljs)
What I try to get going is the following:

  • a Clojure Server that serves a serverside (pre-)rendered rum component that gets fully hydrated from cljs
  • all of that with that “great dynamic clojurey workflow” (instant live reloading)
  • a live clj REPL
  • a live cljs REPL

Can someone please point me in the right directions?
The most promising template I found was GitHub - mdiin/happlate: A template for awesome web apps, based on Hoplon, Postgresql and RPC communication. but I always get errors…

I would be really happy if someone could help me get started

You can look at my (opinionated) template GitHub - serioga/webapp-clojure-2020: Multi-page web application prototype with Clojure(Script)

It took me quite a while, but I have a good place to start now:

Please give some feedback

It is still not working. The first render with Shadow-Cljs works but when the file gets saved, shadow-cljs reloads and reexecutes the file and then the result is:

  45 | (rum/defc item [data]
  46 |   [:div.item
  47 |    [:div.picture (picture "")]
  48 |    [:div.title (:title data)]])
Use of undeclared Var projectname.core/data

All I do, is the following in src/cljs/projectname.cljs:

(ns projectname.core
  (:require [rum.core :as rum]))

(def item_data
  {:title "testitem"
   :main-picture-url ""})

(rum/defc picture [url]
  [:img {:src url :loading "lazy" :alt "Productpicture"}])

(rum/defc item [data]
   [:div.picture (picture "")] ;;(:main-picture-url data))]
   [:div.title (:title data)]])

(defonce item_comp (item item_data))

(rum/mount item_comp (js/document.getElementById "item-container"))

the defonce is already a desperate attempt to fix this… :frowning:

Okay, this seems to be a bug with rum. A bugreport was filed:

FWIW I just tested this and it is working completely fine without any warnings?

(ns projectname.core
  (:require [rum.core :as rum]))

(defonce app-state (atom {:text "Hello world!"}))

(rum/defc hello-world [data]
   [:h1 (:text @app-state)]
   [:h3 "Edit this and watch it change!" (:foo data)]])

(defn start []
  ;; start is called by init and after code reloading finishes
  ;; this is controlled by the :after-load in the config
  (rum/mount (hello-world {:foo "bar"})
             (. js/document (getElementById "app"))))

(defn ^:export init []
  ;; init is called ONCE when the page loads
  ;; this is called in the index.html and must be exported
  ;; so it is available even in :advanced release builds

(defn stop []
  ;; stop is called before any code is reloaded
  ;; this is controlled by :before-load in the config
  (js/console.log "stop"))


 :dependencies [[binaryage/devtools "0.9.7"]
                [rum "0.12.4"]
                ;; fork to support react 16
                ;; [ua.modnakasta/rum "0.11.0-2"]
                [org.roman01la/citrus "3.0.0" :exclusions [rum]]

running shadow-cljs watch app and http://localhost:8700/.

Anything I’m missing?

I am beginning to question my sanity xD.
I copy pasted the code you just quoted here and it WORKED!
I did copy it from the state where it didnt!!
maybe I am just not seeing right, and there is an obvious typo somewhere, if that is the case, I feel really sorry :slight_smile: