ClojureScript REPL Auto-Require

December 2, 2015

Let's say you have some namespaces that you would like to have automatically required and available when you launch your ClojureScript REPL. Perhaps these are utility namespaces that you tend to use only at the REPL, or maybe you'd just like to automatically require your app's main namespace.

Support for this exists in ClojureScript REPLs via an option named :repl-requires.

For our example, let's use Brandon Bloom's Fipp library for pretty-printing at the REPL, and let's also throw in a hypothetical math utility library (which we will use to compute squares of numbers at the REPL).

For each of the above, we simply need to ensure that the dependencies are on the classpath when we start up the REPL. We could use lein to manage the classpath, but to keep things even simpler, let's say we are using the browser REPL as detailed in the ClojureScript Quick Start. Assume we've manually copied fipp-0.6.3.jar into our our hello_world directory along with core.rrb-vector-0.0.11.jar, a transitive dep of Fipp. Also assume we have a src2/math_utis/core.cljs file with

(ns math-utils.core)

(defn square [x]
  (* x x))

Now, to cause the REPL to automatically require Fipp and our math util library upon startup we modify the repl.clj REPL start script so that it has a :repl-requires REPL option that sets up the require specs we want:

  :watch "src"
  :output-dir "out"
   '[[fipp.edn :refer [pprint]]
     [math-utils.core :as math-utils]])

We start up the REPL using a slight modification to the command provided in Quick Start, where we add Fipp, rrb-vector, and our src2 directory:

java -cp cljs.jar:fipp-0.6.3.jar:core.rrb-vector-0.0.11.jar:src:src2 clojure.main repl.clj

Now when you do this, you would normally see Waiting for browser to connect ..., but if you watch carefully, right after this you will see a couple of warnings about cljs.core/char? being replaced by fipp.visit/char?. These are just informational warnings from the compiler, but they are our first bit of evidence that Fipp is being automatically loaded and compiled.

Now if we go to http://localhost:9000 in a browser on our box and start the REPL, without doing anything more, we see our math-utils lib is available:

cljs.user=> (math-utils/square 3)

and we see that Fipp is also available:

cljs.user=> (pprint (range 5) 
  {:width 10})

But, doc is not available:

cljs.user=> (doc map)
WARNING: Use of undeclared Var cljs.user/doc at line 1 <cljs repl>
TypeError: undefined is not an object (evaluating '')

This is because, by specifying :repl-requires, we no longer get the default set of requires that are set up by the base REPL functionality. As of ClojureScript 1.7.170, these defaults are:

'[[cljs.repl :refer-macros 
    [source doc find-doc 
     apropos dir pst]]
  [cljs.pprint :refer [pprint] 
    :refer-macros [pp]]]

So, if you want any of that stuff, like the missing doc macro, be sure to simply include it in your :repl-requires value and you'll be good to go!

Tags: ClojureScript