The work above seems to be enough to get a Cider repl and code reload (from shadow-cljs) working. So if you start the ring server with clojure -A:run and then run a shadow-cljs repl on the :build id it will hot reload your cljs code.
On Thursday, 30 April 2020 11:06:43 UTC+1, Jag Gunawardana wrote: > > One things I forgot. For a landing/marketing page, the main business aim > is to get someone to signup/in so the difference between the prod and dev > app is that for dev, I use a redirect (as per the signup link), in > production I have an Nginx rule that redirects the user to an application > page. As I use the same docker in all environments I specify this with an > env var. Not sure anyone needs this detail, but it explains when I have to > two app setups. > > On Thursday, 30 April 2020 11:01:21 UTC+1, Jag Gunawardana wrote: >> >> Quick background: >> >> I often use static site generators for landing pages, marketing pages >> etc. Hugo is normally my goto product for this as the themes are good and >> it is easy enough to change them, but recently I felt that there has to be >> a better way when you want something (just slightly) beyond a static page. >> I also have limited time to learn things, and my Go templating was very >> rusty. I use more Clojure(script) these days, so thought that there must be >> a simple way to generate static pages from something like hiccup, with a >> bit of Clojurescript interaction where needed. I also wanted to have a >> sensible dev setup so that I wouldn't have to constantly stop and start >> servers. Finally I've tried to move to shadow cljs for Clojurescript, and >> I've tried to use deps.edn rather than lein/boot, so I wanted to keep doing >> this. I started with looking at Juxt Edge as I've had some success with >> this for servers in the past, but it seemed a bit heavy handed for my >> requirements. I found the following very helpful pages: >> >> https://github.com/magnars/stasis >> https://cjohansen.no/building-static-sites-in-clojure-with-stasis >> http://nickgeorge.net/programming/building-my-static-clojure-website/ >> and post that started this discussion above. >> >> I have the following directory structure: >> >> src/clj/mypages for Clojure >> src/cljs/mypages for Clojurescript >> resources/public/css >> resources/public/js >> resources/public/images >> >> Using the following: >> deps.edn >> >> {:paths ["src/clj" "resources" "src/cljs"] >> :deps >> {org.clojure/clojure {:mvn/version "1.10.1"} >> org.clojure/clojurescript {:mvn/version "1.10.597"} >> ring {:mvn/version "1.8.0"} >> ring/ring-defaults {:mvn/version "0.3.2"} >> hiccup/hiccup {:mvn/version "1.0.5"} >> stasis {:mvn/version "2.5.0"} >> optimus {:mvn/version "0.20.2"} >> com.taoensso/timbre {:mvn/version "4.10.0"}} >> >> :aliases >> {:cljs >> {:extra-deps {thheller/shadow-cljs {:mvn/version "2.8.93"}} >> :main-opts ["-m" "shadow.cljs.devtools.cli" "release" "build"] } >> :run >> {:main-opts ["-m" "mypages.server"]} >> :build >> {:main-opts ["-m" "mypages.static"]}}} >> >> shadow-cljs.edn >> >> ;; shadow-cljs configuration >> {:source-paths >> ["src/cljs"] >> >> :dependencies [] >> >> :builds >> {:build {:target :browser >> :output-dir "resources/public/js/" >> :asset-path "/public//js/" >> :modules {:main {:init-fn mypages.helpers/init}} >> :dev {:devtools {:repl-pprint true}} >> :devtools {:console-support false}}}} >> >> some standard ring code for development web server: >> >> src/clj/mypages/server.clj >> >> (ns mypages.server >> (:require [ring.adapter.jetty :refer [run-jetty]] >> [ring.middleware.reload :refer [wrap-reload]] >> [taoensso.timbre :as log] >> [mypages.pages.web :refer [dev-app prod-app]])) >> >> (defonce server (atom nil)) >> >> (defn start-server! [& [port mode]] >> (log/debug "Mode: " mode) >> (reset! server >> (run-jetty >> (case mode >> "dev" (wrap-reload #'dev-app) >> "prod" (wrap-reload #'prod-app) >> (wrap-reload #'dev-app)) >> {:port (if port (Integer/parseInt port) 8080) >> :join? false}))) >> >> (defn stop-server! [] >> (when @server >> (.stop @server) >> (reset! server nil))) >> >> (def -main start-server!) >> >> stasis needs some code to help generate the markup, and we use optimus to >> tidy up, optimise and serve assets. I only serve some css out of the >> resources/public dir, but you could dump some html in there is you wanted >> to. This is in src/clj/mypages/pages/web.clj >> >> (ns mypages.pages.web >> (:require [stasis.core :as stasis] >> [optimus.assets :as assets] >> [optimus.optimizations :as optimizations] >> [optimus.prime :as optimus] >> [optimus.strategies :refer [serve-live-assets]] >> [mypages.pages.layout :as layout])) >> >> (defn home-page [request] >> (layout/landing-page request)) >> >> (defn get-assets [] >> (assets/load-assets "public" [#".*\.(jpg|svg|png|js)$"])) >> >> (defn get-public [] >> (merge (stasis/slurp-directory "resources/public" #".*\.(html|css)$" >> :encoding "UTF-8") >> {"/" home-page})) >> >> (defn get-dev [] >> (merge (get-public) >> {"/signup/" layout/redirect})) >> >> (defn create-app [f] >> (optimus/wrap >> (stasis/serve-pages f) >> get-assets >> optimizations/all >> serve-live-assets)) >> >> (def dev-app >> (create-app get-dev)) >> >> (def prod-app >> (create-app get-public)) >> >> I have some template like functions that allow me to wrap the content >> (which I could possibly write in Markdown later e.g. blog posts) in >> src/clj/mypages/pages/layout.clj: >> >> (ns mypages.pages.layout >> (:require [hiccup.page :refer [html5]] >> [stasis.core :as stasis])) >> >> (defn redirect [request] >> (html5 >> [:head >> [:meta {:http-equiv "refresh" :content "0; URL=' >> https://server.com/auth/signup'"}]])) >> >> (defn landing-page [request content] >> (html5 >> [:head >> [:meta {:charset "utf-8"}] >> [:meta {:name "viewport" >> :content "width=device-width, initial-scale=1.0"}] >> [:title "MyPages"] >> [:link {:rel "stylesheet" :href " >> https://cdn.jsdelivr.net/npm/bulma@0.8.2/css/bulma.min.css"}] >> [:link {:rel "stylesheet" :href "/css/styles.css"}] >> [:script {:type "text/javascript" :src "/js/main.js"}] >> [:script {:defer true :src " >> https://use.fontawesome.com/releases/v5.3.1/js/all.js"}]] >> [:body [:p content]]) >> >> Then some code to generate the static pages when I want them in >> src/clj/mypages/static.clj >> >> (ns mypages.static >> (:require >> [stasis.core :as stasis] >> [optimus.export] >> [optimus.optimizations :as optimizations] >> [mypages.pages.web :as web])) >> >> (def export-dir "static") >> >> (defn export! [] >> (let [assets (optimizations/all (web/get-assets) {})] >> (stasis/empty-directory! export-dir) >> (optimus.export/save-assets assets export-dir) >> (stasis/export-pages (web/get-public) export-dir {:optimus-assets >> assets}))) >> >> (def -main export!) >> >> Finally I have my Clojurescript in src/cljs/mypages/helpers.cljs >> >> (ns mypages.helpers) >> >> (defn ^:export somefunc [] >> (js/alert "Not available yet .... sorry")) >> >> (defn ^:export init [] >> (js/alert "All ready now")) >> >> To build the Clojurescript you can use either of: >> >> npx shadow-cljs release build >> >> or >> >> clojure -A:cljs >> >> >> To work on the static pages, use: >> >> clojure -A:run >> >> This will reload when you change them. >> >> If you are making changes to the cljs regularly there is probably a neat >> of using the shadow-cljs dev web server and doing some sort of reload, but >> I haven't needed that yet, so have not done this. If anyone does, then >> please post up how. >> >> I add pages and required clojurescript and once this is ready I build the >> static site by first building the Clojurescript (as above), then build the >> static pages: >> >> clojure -A:build >> >> I then package it all up into a Docker with nginx serving the site. I use >> a Makefile in the CI to do this. >> >> The setup is fairly simple and could do with some refinement (hot reload >> of js would be next). I like that it gets me to something working quickly >> and it would be easy to being in something like Reagent if a few React >> components are needed. I really wanted something that was small and >> generated fast loading sites. I use re-frame for SPAs, but for some work >> this is overkill and this setup is better. I hope that this is of use, >> please ask any questions. >> >> Regards >> Jag >> >> >> On Wednesday, 29 April 2020 19:37:45 UTC+1, Blake Miller wrote: >>> >>> Jag, >>> >>> I think what you described is worth sharing. I like the simplicity of >>> that approach and the efficiency of the final artifact. >>> >>> -Blake >>> >> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/b40e6328-6766-49b6-b176-48b43a453c38%40googlegroups.com.