Development Guide

Our docs are on GitHub, and all contributions are welcome. Suggest an edit or report a problem.

This guide covers the basics of developing your Edge application.

Things you will learn in this guide:

  • How to start a REPL

  • Working on Edge without an integrated editor

  • Connecting your editing environment to Edge

  • Starting your server system

Identify development aliases

The Clojure tools define the concept of an "alias". Aliases determine which dependencies and code are available to Clojure. You can activate multiple aliases at the same time.

Generally, Edge modules use one of two aliases:

  1. For projects with ClojureScript and/or Sass -A:dev:dev/build:build

  2. For everything else -A:dev

Open the deps.edn file, and look at the :aliases key to determine which one to use.

The presence of :dev/build in the :aliases is enough to inform you that it’s used for dev.

Starting Clojure

Usually you will want to work on Edge with an integrated editor. However, sometimes for demonstration purposes or for beginners it is easier to start with a REPL launched from the terminal.

If you’re using an integrated editor, you will likely need an nREPL server. Emacs can start Clojure automatically with an nREPL, or for other editors you can start an nREPL with your terminal REPL.

Terminal REPL

Edge provides a rebel script to start a REPL with rebel-readline. Run it from the directory of your module, it takes the same parameters you would pass to clj.

You will always need your development aliases.

acme.api$ ../bin/rebel -A:dev
[Edge] Starting development environment, please wait…
[Rebel readline] Type :repl/help for online help info
[Edge] Loading Clojure code, please wait...
[Edge] Now enter (go) to start the dev system
dev=>

When you’re using ClojureScript, also pass the --cljs flag to ../bin/rebel:

acme.app$ ../bin/rebel --cljs -A:dev:dev/build:build
[Edge] Starting development environment, please wait…
[Rebel readline] Type :repl/help for online help info
[Edge] Loading Clojure code, please wait...
[Edge] Now enter (go) to start the dev system
dev=>

If you’re using an integrated editor without jack-in support (e.g. VSCode Calva or Vim Fireplace) then you should also pass the --nrepl flag. This will start an nREPL on port 5600.

acme.app$ ../bin/rebel --cljs --nrepl -A:dev:dev/build:build
[Edge] Starting development environment, please wait…
[Edge] Starting nREPL server on port 5600
[Edge] nREPL client can be connected to port 5600
[Rebel readline] Type :repl/help for online help info
[Edge] Loading Clojure code, please wait...
[Edge] Now enter (go) to start the dev system
dev=>

Emacs / CIDER

First you should open your deps.edn file. Then you must run a different command for:

Clojure

M-x cider-jack-in-clj

ClojureScript

M-x cider-jack-in-clj&cljs

Your development aliases will be automatically set.

If you jack-in with ClojureScript then your system will be automatically started. Check the ClojureScript REPL buffer to see the website address on which to open your browser.

Starting your system

Edge uses the concept of a "system". A system holds your state (e.g. web servers or database connections) and things that need that state (e.g. resource handlers need database connections).

From the dev namespace, type (go) to start the dev system.

dev=> (go)
[Edge] Website listening on: http://localhost:4040
[Edge] Now make code changes, then enter (reset) here
:initiated
Note for Editor REPLs

Editor REPLs usually default to the user namespace, you can spot this as your prompt will look like:

user=>

To go from here to dev, type (dev)

user=> (dev)
dev=>

As a shortcut, you can type both (dev) and (go) together

user=> (dev)
dev=>
[Edge] Website listening on: http://localhost:4040
[Edge] Now make code changes, then enter (reset) here
:initiated

Making code changes

When developing Clojure will reload the code inside of the running process, instead of restarting the process. To do this, type (reset) at the REPL.

dev=> (reset)
:reloading (clojure.tools.deps.alpha.specs clojure.tools.deps.alpha.extensions clojure.tools.deps.alpha.extensions.git clojure.tools.deps.alpha.util.coll clojure.tools.deps.alpha.util.io clojure.tools.deps.alpha.reader clojure.tools.deps.alpha.extensions.deps clojure.tools.deps.alpha.util.maven clojure.tools.deps.alpha.extensions.pom clojure.tools.deps.alpha.extensions.local clojure.tools.deps.alpha.extensions.maven clojure.tools.deps.alpha clojure.tools.deps.alpha.script.print-tree edge.bidi.ig clojure.tools.deps.alpha.libmap clojure.tools.deps.alpha.script.parse clojure.tools.deps.alpha.gen.pom clojure.tools.deps.alpha.script.make-classpath clojure.tools.deps.alpha.script.generate-manifest edge.system edge.system.meta edge.yada.ig acme.api.foo clojure.tools.deps.alpha.repl dev-extras dev user clojure.tools.deps.alpha.script.resolve-tags edge.rebel.main)
:resumed

This function will:

  1. Call (stop) against your system

  2. Reload namespaces which have changed - :reloading indicates which ones are being reloaded this time

  3. Call (go) again to resume your system

The first call to (reset) reloads all namespaces, but subsequent calls only reload changed namespaces:

dev=> (reset)
:reloading ()
:resumed
vim-replant’s refresh

If you are using replant, then the refresh functionality will automatically detect Edge’s stop/start functions.

This means you don’t need to type (go) or (reset).

Use emacs key bindings

Emacs refresh is configured to automatically run suspend/resume for you.

cider-refresh is bound differently in Emacs and Spacemacs.

Emacs

C-c M-n r

Spacemacs

, s x

This means you never need to type (go) or (reset).

ClojureScript

If you’re using CIDER then you can skip this section.

A ClojureScript REPL is available with Edge. Ensure that you have started your system with (go) and you have opened your browser to your ClojureScript application (that’s the http://localhost:xxxx link when you type (go)).

Now run the cljs-repl function to connect to your browser:

dev=> (cljs-repl)
Prompt will show when REPL connects to evaluation environment (i.e. a REPL hosting webpage)
Figwheel Main Controls:
          (figwheel.main/stop-builds id ...)  ;; stops Figwheel autobuilder for ids
          (figwheel.main/start-builds id ...) ;; starts autobuilder focused on ids
          (figwheel.main/reset)               ;; stops, cleans, reloads config, and starts autobuilder
          (figwheel.main/build-once id ...)   ;; builds source one time
          (figwheel.main/clean id ...)        ;; deletes compiled cljs target files
          (figwheel.main/status)              ;; displays current state of system
Figwheel REPL Controls:
          (figwheel.repl/conns)               ;; displays the current connections
          (figwheel.repl/focus session-name)  ;; choose which session name to focus on
In the cljs.user ns, controls can be called without ns ie. (conns) instead of (figwheel.repl/conns)
    Docs: (doc function-name-here)
    Exit: :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
JavaScript environment will not launch automatically when :open-url is false
ClojureScript 1.10.339
cljs.user=>

From here, send yourself a message to test the connection works:

cljs.user=> (js/alert "Hello, world")
nil

This will wait until you click "OK" in your browser.

Last updated 2019-04-24 07:22:14 +0100