Fork me on GitHub

this is a bit confusing: (returns empty results)


hey again, I'm having a hard time wrapping my head around connecting to both a plain clojure nrepl and a figwheel clojurescript repl. I'm using a ring handler as described here: to write some clojure backend / API. I'm using Cider. I'd like to open a cider repl to the java process, in the same environment that is running the ring middleware, and another to the figwheel clojurescript repl. I finally "succeeded" through this clumsy procedure: 1. Clone 2. Open core.cljs 3. cider-jack-in-cljs, opens a cljs repl, it just works, yay! 4. Ok, now I need the clojure repl. So I found I could do this: :cljs/quit on the cljs repl, now the cljs repl is dead! 5. cider-jack-in-clj, finds the clojure repl started before. Connects! 6. Now I go back to the previous repl and I run: (figwheel.main.api/cljs-repl "dev")The cljs repl is alive again! To be honest I've spent the last whole week trying to open clj+cljs repls from cider... I consider this my break through haha. But I'm sure there must be an easier way! Would appreciate some directions! (I've read the docs a few times but couldn't find specifics of using cider-jack-in-clj&cljs, nor in figwheel-main nor sites)


I'm not saying this isn't possible (it sounds like you got it to work in a fashion) but I'm struggling to really imagine it being very ergonomic. I don't quite get how the editor would know what REPL to send code to for evaluation, for example.


There might be something going on with your setup. Locally, just cider-jack-in-clj&cljs works out of the box on the repo you've provided! (Gives me one clj and one cljs repl, and evaluating code works everywhere) I'd double check that the CIDER versions are up to date (on your user's profile and also on your emacs). It is ergonomic when it works - emacs knows which REPL to use by the file extension. You can also arbitrarily associate a buffer with a specific repl via sessman commands. (But I must confess that I'd never seen that command work before 😂. I usually start the repls from the command line and just connect with Cider)

👍 4

and it mostly works!


but it's been kinda hard to get it to work in the first place


@U1UQEM078 you mentioned you start the repl from the command line, how do you do that with figwheel? 1. When I start with a command like clojure -m figwheel.main -b dev -r the output shows a running HTTP server and that's that, it doesn't show the nREPL port. 2. Is the figwheel's nREPL able to handle both clj and cljs connections? 3. Should I just attempt to connect to clj and then to cljs in cider one after the other with the same port? (assuming I can find out which port is that)


Ok, the solutions I think I found.... 1) I still don't know, but I saw when cider launches a repl it uses nrepl-cmdline which seems to be saving the port a file on the root of the project (.nrepl-port)


2) I thin figwheel launches a single nREPL server, the cmds to cljs or clj are "redirected" through the use of the piggieback middleware, so I shouldn't try to run two nREPLS


3) is basically answered by 2).. 🙂


founds this project that solved the cider-jack-in-clj&cljs debacle for me:


the "secret sauce" seems to be the config on .dir-locals.el, which customize the way cider launches the repl:


it instructs cider to use the -A:cider alias cmd, and in deps.edn there's a corresponding alias that enables figwheel. There's also config to automatically select a repl of figwheel-main type and the dev build.


sigh, that was a lot to write. Hopefully it will help someone, maybe not 🙂


You should put this on a blog (or just a Gist)! It's useful information.


ah, good point, will do 🙂


> how do you do that with figwheel? Just like you'd do in a regular, non-figwheel project. Figwheel doesn't come with nrepl baked-in:

$ clj -Acider -Sdeps '{:deps {nrepl/nrepl {:mvn/version "0.6.0"}}}' -m nrepl.cmdline
nREPL server started on port 49712 on host localhost - 
[Figwheel] Starting Server at 
[Figwheel] Starting REPL
Then we can connect to the nrepl with a client. (cider is a client, but so is this other command line tool)
$ clojure -Sdeps '{:deps {reply {:mvn/version "0.4.3"}}}' -m reply.main --attach localhost:49712
REPL-y 0.4.3, nREPL 0.6.0
user=> (require '[figwheel.main.api :as fig])
user=> (fig/start "dev")
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
(i.e. where we were with `-A:figwheel` or `clojure -m figwheel.main -b dev -r`, but using nrepl)
Note that it'll also complain of other missing pieces (e.g. piggieback middleware for CLJS support). Either you add them to the project, to your user profile, or use the jack-in-* commands (which add those for you)


thx! took me a while but I figured out cider jack in was running the repl cmd line


clojure -A:cider -Sdeps '{:deps {nrepl {:mvn/version ""0.6.0""} cider/piggieback {:mvn/version ""0.4.2""} cider/cider-nrepl {:mvn/version ""0.23.0""}}}' -m nrepl.cmdline --middleware '[""cider.nrepl/cider-middleware"", ""cider.piggieback/wrap-cljs-repl""]'

👍 4

Another attempt: I figured I could start an nREPL server with known port for the java REPL and then call figwheel's API to start the "dev" build in the background. I thought it would create an additional nREPL server for the CLJS side, so I could print the repl-env and get a different port to cider-jack-in-cljs with. I WAS WRONG 😛

Joe Corneli17:02:38

Hi, I am having trouble getting a ClojureScript REPL up and running with Figwheel Main.

Joe Corneli17:02:50

Here is a log of my interaction with the system.

Joe Corneli17:02:03

$ lein repl
2020-02-05 17:31:01.428:INFO::main: Logging initialized @4623ms to org.eclipse.jetty.util.log.StdErrLog
"To start a cljs repl call `(figwheel/cljs-repl \"app\")`"
"where `app` is the build you want to attach to."
nREPL server started on port 3888 on host - 
REPL-y 0.4.3, nREPL 0.6.0
Clojure 1.10.1
OpenJDK 64-Bit Server VM 1.8.0_242-8u242-b08-0ubuntu3~18.04-b08
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (use 'figwheel-sidecar.repl-api)
(use 'figwheel-sidecar.repl-api
user=> (start-figwheel!)
Figwheel: Starting server at 
Figwheel: Watching build - admin
Compiling build :admin to "resources/public/js/admin.js" from ["src/cljs" "src/cljc" "test/cljs"]...
WARNING: cljs.core/<=, all arguments must be numbers, got [#{nil js/Number} number] instead at line 1193 resources/public/js/admin/clojure/test/check/generators.cljc
WARNING: cljs.core/<=, all arguments must be numbers, got [#{nil js/Number} number] instead at line 1193 resources/public/js/admin/clojure/test/check/generators.cljc
WARNING: Cannot resolve property getElementById for inferred type js/HTMLDocument in expression (. js/document getElementById "app") at line 14 src/cljs/com/openmarkets/exchange/ui/shopping/core.cljs
Successfully compiled build :admin to "resources/public/js/admin.js" in 36.858 seconds.
user=> (figwheel-sidecar.repl-api/print-config)
{:id "admin",
 :source-paths ["src/cljs" "src/cljc" "test/cljs"],
 :figwheel {:build-id "admin"},
 :watch-paths ["src/cljs" "src/cljc" "test/cljs"],
 :compile-paths ["src/cljs" "src/cljc" "test/cljs"],
 {:infer-externs true,
  :output-dir "resources/public/js/admin",
  :optimizations :none,
  :output-to "resources/public/js/admin.js",
  :source-map-timestamp true,
  :asset-path "",
  :devcards true,
  :external-config {:re-frisk {:enabled true}},
{:id "shared",
 :source-paths ["src/cljs" "src/cljc" "test/cljc"],
 :figwheel {:build-id "shared"},
 :watch-paths ["src/cljs" "src/cljc" "test/cljc"],
 :compile-paths ["src/cljs" "src/cljc" "test/cljc"],
  :asset-path "",
  :output-to "resources/public/js/shared.js",
  :output-dir "resources/public/js/shared",
  :external-config {:re-frisk {:enabled true}},
  :infer-externs true,
  :source-map-timestamp true,
  :optimizations :none}}
{:id "shopping",
 :source-paths ["src/cljs" "src/cljc" "test/cljc"],
 :figwheel {:build-id "shopping"},
 :watch-paths ["src/cljs" "src/cljc" "test/cljc"],
 :compile-paths ["src/cljs" "src/cljc" "test/cljc"],
  :asset-path "",
  :output-to "resources/public/js/shopping.js",
  :output-dir "resources/public/js/shopping",
  :devcards true,
  :infer-externs true,
  :source-map-timestamp true,
  :optimizations :none}}
user=> (cljs-repl)
Launching ClojureScript REPL for build: admin
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild id ...)        ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once id ...)             ;; builds source one time
          (clean-builds id ..)            ;; deletes compiled cljs target files
          (print-config id ...)           ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
          (figwheel.client/set-autoload false)    ;; will turn autoloading off
          (figwheel.client/set-repl-pprint false) ;; will turn pretty printing off
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application

Joe Corneli17:02:14

It just sits there at that point

Joe Corneli17:02:38

My further actions: > <Browse to> > <Notice error: ClojureScript could not load :main, did you forget to specify :asset-path?>

Joe Corneli17:02:20

:asset-path is there in the configs, but maybe in the wrong place?


At the top of that output it says to run (figwheel/cljs-repl \"app\") in the repl, where app I assume is admin in your case. Did you try that?

Joe Corneli18:02:53

It leads to the same result

Joe Corneli18:02:59

Sitting there waiting for Figwheel to connect

Joe Corneli18:02:49

I've started it a different way now, inside of CIDER -- so that I can get all the dependencies

Joe Corneli18:02:56

I don't see the same error in the browser

Joe Corneli18:02:09

In fact, I see this: > [] WebSocket opened on <ws://exchange-cljs.test:9500/figwheel-connect?fwprocess=73e2bb&fwbuild=admin&fwsid=c9b0b578-b41a-4b36-bf6d-8e47d1fbd6d2&fwsname=Shelia>

Joe Corneli18:02:23

So that suggests to me that the application is indeed connecting to Figwheel

Joe Corneli18:02:46

But still on the REPL I have the same "Prompt will show when Figwheel connects to your application" message

Joe Corneli18:02:19

Maybe the issue is that Figwheel has already started elsewhere, so my REPL version is superfluous

Joe Corneli18:02:50

Is there a way to connect from user> to an existing Figwheel, rather than run (start-figwheel!)?

Joe Corneli18:02:11

Aha, I have at least extracted information about it:

Joe Corneli18:02:31

user> (figwheel/repl-env "admin")
{:output-dir "target/public/cljs-out/admin",
 :bound-printer #<Atom@68b97064: nil>,
 :ring-server-options {:host "", :port 9500},
 :broadcast false,
 :out-print-fn nil,
   #object[org.eclipse.jetty.server.Server 0x623ea2af "Server@623ea2af{STARTED}[9.4.12.v20180830]"]>,
 :open-url-fn #function[figwheel.main.api/repl-env/fn--8708],
 :port 9500,
 :output-to "target/public/cljs-out/admin-main.js",
 :focus-session-name #<Atom@437e775a: nil>,
 :prevent-server-tear-down true,
 :err-print-fn nil,
 :node-proc #<Atom@dc17c43: nil>,
 :print-to-output-streams true,
 #<Atom@65caaa34: #function[clojure.core/bound-fn*/fn--5749]>,
 :open-url "",

Joe Corneli18:02:24

OK, woah, I am in

Joe Corneli18:02:09

I'm not sure what changed

🎉 8