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.
|
Note
|
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.
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>
|
Note
|
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>")))))Alternatively you can start the server manually with something like:
$ shadow-cljs watch appAnd connect to it with cider-connect.
…For that to work, shadow-cljs.edn contents like the following are assumed:
:dependencies [[cider/cider-nrepl "0.55.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|
Note
|
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.
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.
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")
Here are a few useful sections from shadow-cljs's own documentation: