Hi Jag,

Would love to learn more about your approach.  I have just gotten started 
with shadow-cljs.  I read about Stasis some time ago but havent actually 
used it.

TIA,

Ray

On Monday, April 27, 2020 at 8:24:22 PM UTC+8, Jag Gunawardana wrote:
>
> Thanks Gary for posting this up. Was a great help for a slightly different 
> use case. I was using static site generators like Hugo, but always found 
> that I ended up having to learn their internals/templating to make larger 
> changes. I also wanted to use Clojurescript and it was painful to do so. I 
> made a few changes:
>
> I used the Stasis library to turn my hiccup and assets into a static site 
> (but serve up with Ring in development).
> I used shadow-cljs to compile my Clojurescript.
> I also use deps.edn rather than Lein (even though Lein still feels easier).
> My final artifact was a largely static website, packaged up into an Nginx 
> docker. I have a small amount of clojurescript which gets built into one 
> main.js file.
>
> I can post up the details/a repo if anyone else wants to do similar.
>
> I always feel that you can do pretty much anything with Clojure(script), 
> but sometimes there is a bit of a dark art to getting there. I think I 
> would use this approach for any site that I would have used a static site 
> generator for now. 
>
>
> On Monday, 9 July 2018 17:14:22 UTC+1, Gary Johnson wrote:
>>
>> Howdy Clojurians,
>>
>> I recently started developing a new Clojure+Clojurescript web 
>> application, and I wanted to see if I could set up my development 
>> environment using just the Clojure CLI tools. After a good deal of digging 
>> around through tutorials on a number of different websites and a fair 
>> amount of experimenting, I've managed to create a very simple (IMHO) 
>> configuration that provides me with both development and production mode 
>> CLJS->JS compilation, development and production mode ring handlers, and 
>> the always delightful FIgwheel development environment all from just the 
>> simple "clojure" command. Since I haven't seen this before, I thought I'd 
>> share it with all of you in case it helps someone else out there who 
>> doesn't need (or want) all of leiningen or boot to develop a simple web app.
>>
>> Here goes:
>>
>> Step 1: Create your project structure like so:
>>
>> ├── cljsbuild.edn
>> ├── deps.edn
>> ├── figwheel.edn
>> ├── resources
>> │   └── public
>> │       ├── cljs
>> │       ├── css
>> │       │     ├── style.css
>> │       ├── images
>> │       └── js
>> ├── src
>> │   ├── clj
>> │   │   └── my_project
>> │   │       ├── handler.clj
>> │   │       ├── server.clj
>> │   │       ├── views.clj
>> │   └── cljs
>> │       └── my_project
>> │           ├── client.cljs
>>
>> Step 2: Make the deps.edn file (replace :deps and my-project.server 
>> namespace as necessary for your project)
>>
>> {:paths ["src/clj" "resources"]
>>
>>  :deps {org.clojure/clojure       {:mvn/version "1.9.0"}
>>         org.clojure/clojurescript {:mvn/version "1.10.312"}
>>         ring                      {:mvn/version "1.7.0-RC1"}
>>         ring/ring-defaults        {:mvn/version "0.3.2"}
>>         prone                     {:mvn/version "1.6.0"}
>>         compojure                 {:mvn/version "1.6.1"}
>>         hiccup                    {:mvn/version "1.0.5"}
>>         reagent                   {:mvn/version "0.8.1"}}
>>
>>  :aliases {:run        {:main-opts ["-m" "my-project.server"]}
>>            :cljsbuild  {:extra-paths ["src/cljs"]
>>                         :main-opts ["-m" "cljs.main" "-co" 
>> "cljsbuild.edn" "-c"]}
>>            :figwheel   {:extra-deps {org.clojure/tools.nrepl {:mvn/version 
>> "0.2.13"}
>>                                      cider/cider-nrepl       {:mvn/version 
>> "0.17.0"}
>>                                      com.cemerick/piggieback {:mvn/version 
>> "0.2.2"}
>>                                      figwheel-sidecar        {:mvn/version 
>> "0.5.14"}}
>>                         :main-opts ["-e" 
>> "(use,'figwheel-sidecar.repl-api),(start-figwheel!)"]}}}
>>
>>
>> Step 3: Make the cljsbuild.edn file (replace :main for your project)
>>
>> {:main          "my-project.client"
>>  :output-dir    "resources/public/cljs"
>>  :output-to     "resources/public/cljs/app.js"
>>  :source-map    "resources/public/cljs/app.js.map"
>>  :optimizations :advanced
>>  :pretty-print  false}
>>
>> Step 4: Make the figwheel.edn file (replace :ring-handler, :on-jsload, 
>> and :main for your project)
>>
>> {:nrepl-port       7000
>>  :nrepl-middleware ["cider.nrepl/cider-middleware"
>>                     "cemerick.piggieback/wrap-cljs-repl"]
>>  :server-port      3000
>>  :ring-handler     my-project.handler/development-app
>>  :http-server-root "public"
>>  :css-dirs         ["resources/public/css"]
>>  :builds [{:id           "dev"
>>            :source-paths ["src/cljs"]
>>            :figwheel     {:on-jsload "my-project.client/mount-root"}
>>            :compiler     {:main          "my-project.client"
>>                           :output-dir    "resources/public/cljs/out"
>>                           :output-to     "resources/public/cljs/app.js"
>>                           :asset-path    "/cljs/out"
>>                           :source-map    true
>>                           :optimizations :none
>>                           :pretty-print  true}}]}
>>
>>
>> Step 5: Write server.clj
>>
>> (ns my-project.server
>>   (:require [ring.adapter.jetty :refer [run-jetty]]
>>             [my-project.handler :refer [development-app production-app]])
>>   (:gen-class))
>>
>> (defonce server (atom nil))
>>
>> (defn start-server! [& [port mode]]
>>   (reset! server
>>           (run-jetty
>>            (case mode
>>              "dev"  #'development-app
>>              "prod" #'production-app
>>              #'production-app)
>>            {:port (if port (Integer/parseInt port) 3000)
>>             :join? false})))
>>
>> (defn stop-server! []
>>   (when @server
>>     (.stop @server)
>>     (reset! server nil)))
>>
>> (def -main start-server!)
>>
>>
>> Step 6: Write handler.clj
>>
>> (ns my-project.handler
>>   (:require [ring.middleware.defaults :refer [wrap-defaults site-defaults
>> ]]
>>             [ring.middleware.reload :refer [wrap-reload]]
>>             [prone.middleware :refer [wrap-exceptions]]
>>             [compojure.core :refer [defroutes GET]]
>>             [compojure.route :refer [not-found]]
>>             [my-project.views :refer [render-page]]))
>>
>> (defroutes routes
>>   (GET "/" [] (render-page))
>>   (not-found "Not Found"))
>>
>> (def development-app (wrap-reload
>>                       (wrap-exceptions
>>                        (wrap-defaults #'routes site-defaults))))
>>
>> (def production-app (wrap-defaults #'routes site-defaults))
>>
>>
>> Step 7: Write views.clj
>>
>> (ns my-project.views
>>   (:require [hiccup.page :refer [html5 include-css include-js]]))
>>
>> (defn render-page []
>>   (html5
>>    [:head
>>     [:title "My Project"]
>>     [:meta {:charset "utf-8"}]
>>     [:meta {:name "viewport" :content "width=device-width, 
>> initial-scale=1"}]
>>     (include-css "/css/style.css")
>>     (include-js "/cljs/app.js")]
>>    [:body
>>     [:div#app]
>>     [:script {:type "text/javascript"} "my_project.client.mount_root();"
>> ]))
>>
>>
>>
>> Step 8: Write client.cljs (replace Reagent with whichever front-end 
>> library you prefer)
>>
>> (ns my-project.client
>>   (:require [reagent.core :as r]))
>>
>> (defn root-component []
>>   [:div [:h1 "Hello world!"]])
>>
>> (defn ^:export mount-root []
>>   (r/render [root-component]
>>             (.getElementById js/document "app")))
>>
>>
>> Step 9: Write some CSS in resources/public/css/style.css
>>
>> #app {
>>   border: 2px solid green;
>> }
>>
>> Step 10: Try out your new dev tools!
>>
>> At this point, your project setup is complete, and you are ready to start 
>> developing your awesome new Clojure+Clojurescript web app. You have the 
>> following 3 project management commands available at your command prompt:
>>
>> *1. Compile Clojurescript to Javascript*
>>
>> To compile the Clojurescript files under src/cljs to Javascript under 
>> resources/public/cljs, navigate to the toplevel project directory and run:
>>
>> $ clojure -A:cljsbuild
>>
>> The main Javascript entry point file will be written to 
>> resources/public/cljs/app.js. The Clojurescript build options are read from 
>> the toplevel cljsbuild.edn file. They are set to use advanced compilation 
>> mode for a production build.
>>
>>
>> *2. Run your Web Application *
>>
>> To compile and run your web application, navigate to the toplevel project 
>> directory and run:
>>
>> $ clojure -A:run [port] [dev|prod]
>>
>> The website will then be available at http://localhost:3000 or on 
>> whichever port you specified. In dev mode, server-side exceptions will be 
>> displayed in the browser and Clojure source files will be reloaded whenever 
>> you refresh the page. These features are disabled in prod mode. If the 
>> second argument to run is omitted, it will default to prod mode.
>>
>>
>> *3. Launch Figwheel*
>>
>> To start the Figwheel server, navigate to the toplevel project directory 
>> and run:
>>
>> $ clojure -A:figwheel
>>
>> This will start an http-kit webserver on http://localhost:3000, which 
>> serves up the website in dev mode. It will also open an nREPL on port 7000, 
>> which provides the special command "(cljs-repl)" to switch from a Clojure 
>> REPL to a Clojurescript REPL. Finally, any changes to CLJS or CSS files 
>> will automatically be pushed to the browser when the
>> files are saved.
>>
>>
>> Okay, folks. That's all from me for now. Setting this all up was quite an 
>> interesting learning exercise, but I'm very happy with the results. I hope 
>> someone out there finds this setup useful for your next Clojure project. If 
>> someone has the power to add this tutorial to the Clojure website (or other 
>> documentation site), I think it would be a great addition.
>>
>> Also, someone should definitely make a *clj-new* project template from 
>> this setup. *I'm looking at you, Sean Corfield.* ;-D
>>
>> Have fun, everyone, and happy hacking!
>>
>> ~Gary
>>
>>

-- 
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/45ca024f-d4cb-4e02-97dc-771c02ab4e3c%40googlegroups.com.

Reply via email to