Using shadow-cljs
shadow-cljs
is one of the most popular toolchain for doing ClojureScript
development these days. In this section we’ll discuss how to set it up and
use it together with CIDER.
Setting up shadow-cljs
This section assumes you’ve already installed node.js. |
Installing shadow-cljs
is pretty straight-forward. You can do it via npm
or yarn
:
$ npm install -g shadow-cljs $ yarn global add shadow-cljs
While it’s not necessary to do a global installation that’s generally the recommended approach.
Starting a shadow-cljs REPL
Using cider-jack-in-cljs
Provided you’ve configured your project correctly, you can simply use
cider-jack-in-cljs
:
-
Press C-c C-x j s (or do
M-x cider-jack-in-cljs
) -
When prompted for the ClojureScript REPL type to start, select
shadow
This will automatically start the shadow-cljs server and connect to
it. You’ll also be prompted for the shadow-cljs build to use. Select
your desired build (e.g. app
) and you should see something like:
shadow.user> To quit, type: :cljs/quit [:selected :app] cljs.repl>
CIDER will extract the list of available builds automatically
from the shadow-cljs.edn file in the root of the current project.
|
You can get rid of the prompts for the REPL type and the target build
by creating a .dir-locals.el
file with the following contents in the
root of your project.
((nil . ((cider-default-cljs-repl . shadow)
(cider-shadow-default-options . "<your-build-name-here>")
(cider-shadow-watched-builds . ("<first-build>" "<other-build>")))))
Using cider-connect-cljs
Alternatively you can start the server manually with something like:
$ shadow-cljs watch app
And connect to it with cider-connect
.
…For that to work, shadow-cljs.edn
contents like the following are assumed:
:dependencies [[cider/cider-nrepl "0.39.1"] ;; mandatory (unless it's inherited from deps.edn or otherwise present in the classpath of shadow-cljs's JVM process)
[refactor-nrepl/refactor-nrepl "3.9.0"]] ;; refactor-nrepl is optional
:nrepl {:middleware [cider.nrepl/cider-middleware ;; it's advisable to explicitly add this middleware. It's automatically added by shadow-cljs (if available in the classpath), unless `:nrepl {:cider false}`
refactor-nrepl.middleware/wrap-refactor] ;; refactor-nrepl is optional
:port 50655} ;; optional - if not specified, a random free port will be used
If cider-nrepl isn’t in your
classpath you should make sure it’s there. You can do this by correctly filling
the shadow-cljs.edn configuration file
residing in the root of your project, as described above. Alternatively you can set
cider-repl-auto-detect-type to nil , as the auto-detection of
REPL types doesn’t work without cider-nrepl .
|
If you already have a running server watching a build (for instance
you have already run npx shadow-cljs watch :dev
), you can use the
shadow-select
CLJS REPL and specify :dev
when prompted.
Using shadow-cljs with deps.edn and custom repl initialization
In case you want to manage your dependencies via deps.edn, you can use a
custom cljs-repl init form. This supposes you have shadow-cljs in your deps.edn
dependencies.
{:paths ["src"]
:deps {...
thheller/shadow-cljs {:mvn/version "2.15.6"}
...
}
:aliases {:dev {:extra-paths ["dev"]}}}
Create a :dev
alias with an extra source path of "dev" and add the following namespace
(ns user
(:require [shadow.cljs.devtools.api :as shadow]
[shadow.cljs.devtools.server :as server]))
(defn cljs-repl
"Connects to a given build-id. Defaults to `:app`."
([]
(cljs-repl :app))
([build-id]
(server/start!)
(shadow/watch build-id)
(shadow/nrepl-select build-id)))
Supposing your build-id is :app
, add the following to your .dir-locals.el
((nil . ((cider-clojure-cli-aliases . ":dev")
(cider-preferred-build-tool . clojure-cli)
(cider-default-cljs-repl . custom)
(cider-custom-cljs-repl-init-form . "(do (user/cljs-repl))")
(eval . (progn
(make-variable-buffer-local 'cider-jack-in-nrepl-middlewares)
(add-to-list 'cider-jack-in-nrepl-middlewares "shadow.cljs.devtools.server.nrepl/middleware"))))))
cider-jack-in-cljs
should then work out of the box.
Configuration
You can tweak the command used by cider-jack-in-cljs
to start the shadow-cljs
server
via the following configuration variables:
-
cider-shadow-cljs-command
(its default value isnpx shadow-cljs
) -
cider-shadow-cljs-parameters
(its default value isserver
)
All of this results in the following default command to start the shadow-cljs server:
$ npx shadow-cljs server
The command is visible in the minibuffer when you’re doing cider-jack-in-cljs
.
As noted earlier you can also set a default build via cider-shadow-default-options
:
(setq cider-shadow-default-options "app")