We publish all our demos here in one place. This is how we fiddle around with our many demos at work.
This repo is structured to allow multiple "fiddles" (little apps) to run simultaneously on the same merged local dev classpath, with some common dev infrastructure (e.g. routing and example databases). Prod classpaths are isolated, so that each fiddle can be deployed individually and separately.
This is all done in a rather tiny amount of LOC, so we feel it is reasonable to expect you to understand it:
-
local dev: the dev entrypoint uses a clever reader trick to drive Clojure/Script namespace
:require
directives from a config file,electric-fiddle.edn
. -
prod: the prod entrypoint runs only one fiddle at a time, with an isolated classpath. Prod has a mandatory build, which bakes the Electric application client program. At compile time, both the electric user application version number (derived from git) and the fiddle entrypoint namespace are known statically, and built into both the client assets and also the server asset
resources/electric-manifest.edn
. At runtime, the prod entrypoint uses the reader trick to lookup the name of the entrypoint to run.
For a minimalist starter example, see https://github.com/hyperfiddle/electric-starter-app which is able to eliminate most of this dynamism by hardcoding the user application entrypoint and classpath.
Begin with an example "Hello World" fiddle:
$ clj -A:dev
INFO dev: {:host "0.0.0.0", :port 8080, :resources-path "public", :manifest-path "public/js/manifest.edn"}
INFO dev: Starting Electric compiler and server...
shadow-cljs - nREPL server started on port 9001
[:dev] Configuring build.
[:dev] Compiling ...
[:dev] Build completed. (231 files, 2 compiled, 0 warnings, 2.46s)
INFO electric-fiddle.server-jetty: 👉 http://0.0.0.0:8080
- Navigate to http://localhost:8080
- Corresponding source code is in
src/hello_fiddle
In electric-fiddle.edn
, under :loaded-fiddles
, add electric-tutorial
:
{:loaded-fiddles [hello-fiddle
+ electric-tutorial ; requires :electric-tutorial alias and `npm install`
]
}
Restart your REPL with the required dependencies:
npm install
clj -A:dev:electric-tutorial
Navigate to http://localhost:8080 (or refresh your browser tab). The pages shows a new entry for electric-tutorial
.
mkdir src/my_fiddle
- Add the following to
src/my_fiddle/fiddles.cljc
:
(ns my-fiddle.fiddles
(:require [hyperfiddle.electric :as e]
[hyperfiddle.electric-dom2 :as dom]))
(e/defn MyFiddle []
(e/client
(dom/h1 (dom/text "Hello from my fiddle."))))
(e/def fiddles ; Entries for the dev index
{`MyFiddle MyFiddle})
(e/defn FiddleMain [ring-req] ; prod entrypoint
(e/server
(binding [e/http-request ring-req])
(e/client
(binding [dom/node js/document.body]
(MyFiddle.)))))
- Add
my-fiddle
toelectric-fiddle.edn
>:loaded-fiddles
. - add your dependencies to deps.edn (under an alias) and package.json
- Restart your REPL with your new deps alias
Deploys one fiddle at a time.
# "Hello World" prod build
clojure -X:build:prod build-client :hyperfiddle/domain hello-fiddle
clojure -X:build:prod build-client :hyperfiddle/domain hello-fiddle :debug false :verbose false :optimize true
clj -M:prod -m prod
# With extra dependencies
npm install
clojure -X:build:prod:electric-tutorial build-client :hyperfiddle/domain electric-tutorial
clj -M:prod:electric-tutorial -m prod
# http://localhost:8080/electric-tutorial.tutorial!%54utorial/electric-tutorial.demo-two-clocks!%54wo%43locks
# Uberjar
clojure -X:build:prod uberjar :hyperfiddle/domain hello-fiddle :build/jar-name "app.jar"
java -cp app.jar clojure.main -m prod
# Fly.io deployment
fly deploy --remote-only --config src/hello_fiddle/fly.toml