How to connect a ClojureScript node REPL to my :node-library shadow-cljs project?
Asked Answered
P

2

7

Context

I am building a Node.js library with ClojureScript and shadow-cljs.
All development is done with ClojureScript but the build artefact is a NPM package. Example:

(ns com.example.answer)

(defn answer [] 42)

build... release... then

const answer = require('answer');
answer(); //=> 42

NB: I recently contributed the details of my build setup to this post.

My entire development environment is in a Docker container and I am using the "Visual Studio Code Remote - Container" extension.

The "Problem"

My build setup works fine (at least I think so!) but I'd like to implement a faster development feedback cycle.
In other words: I don't want to rebuild an entire NPM package just to test a few lines of change.

The Perfect World aka "the question"

In a perfect world I should be able to have a REPL open and be able to evaluate my ClojureScript code at all time.

No matter how I try to get there I seem to be blocked by the same underlying problem:

No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code.

What I tried

  1. With shadow-cljs only:

    Given the following shadow-cljs.edn file:

    ;; shadow-cljs configuration
    {:source-paths
    ["src"]
    
    :builds
    {:lib {:target :node-library
            :output-to "dist/index.js"
            :exports {:citation citegen.processor.main/citation}}}}
    

    First watch:

    root@97db64e5dfa3:/workspaces/citegen# cd packages/csl-processor/
    root@97db64e5dfa3:/workspaces/citegen/packages/csl-processor# yarn shadow-cljs cljs-repl lib
    yarn run v1.17.3
    $ /workspaces/citegen/node_modules/.bin/shadow-cljs cljs-repl lib
    shadow-cljs - config: /workspaces/citegen/packages/csl-processor/shadow-cljs.edn  cli version: 2.8.52  node: v12.10.0
    shadow-cljs - socket connect failed, server process dead?
    shadow-cljs - updating dependencies
    ...
    shadow-cljs - dependencies updated
    shadow-cljs - server version: 2.8.52 running at http://localhost:9630
    shadow-cljs - nREPL server started on port 36017
    [0:0]~cljs.user=>
    

    Then in another terminal: (note the error message)

    root@97db64e5dfa3:/workspaces/citegen# cd packages/csl-processor/
    root@97db64e5dfa3:/workspaces/citegen/packages/csl-processor# yarn shadow-cljs cljs-repl lib
    yarn run v1.17.3
    $ /workspaces/citegen/node_modules/.bin/shadow-cljs cljs-repl lib
    shadow-cljs - config: /workspaces/citegen/packages/csl-processor/shadow-cljs.edn  cli version: 2.8.52  node: v12.10.0
    shadow-cljs - connected to server
    [1:1]~cljs.user=> (inc 41)
    No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code.
    
  2. With VS Code Calva:

    Given the same shadow-cljs.edn file as above:

    enter image description here

    When I try to manually load the namespace with Calva: Load current namespace in REPL window, I get the same error:

    No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code.

Question: How do I get to that perfect world?

Pickaninny answered 23/9, 2019 at 10:52 Comment(0)
P
9

Thanks to Thomas Heller I have managed to get this to work.

What I didn't realise was that I needed to run the build artefact once in order to connect to the REPL.

This will effectively get rid of this error:

No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code.

Steps

  1. In VS Code open any ClojureScript file
  2. Press CMDSHIFTp and select Calva: Start a project REPL and connect (aka Jack-in)
  3. Wait until the REPL window opens
  4. Only then, open a new terminal and require your build artefact so that a connect to the REPL is made. e.g. node -e "require('./dist')"
  5. Open any ClojureScript file you want to evaluate in the REPL, press CMDSHIFTp and select Calva: Load current namespace in the REPL window

I have attached a screencast below. As you can see:

  • The namespace in the CLJS REPL window isn't set to undefined anymore
  • Any change to your ClojureScript file is both automatically recompiled and available in the REPL

enter image description here

Pickaninny answered 23/9, 2019 at 14:43 Comment(1)
This is a nice write-up. It would be a very good contribution to the Calva wiki. Maybe as the first content on a new page named "Using with shadow-cljs”, or something. Just sayn'.Gendarmerie
C
3

I would suggest reading the manual section on REPL Troubleshooting.

You most likely want to run shadow-cljs node-repl. This starts a REPL with a connected managed runtime. Otherwise you need something running node to load the code produced by :node-library as described in the manual.

You can do this manually if you like by running node and then require("./dist/index.js"). Once that is done the cljs-repl will be able to eval.

Cardsharp answered 23/9, 2019 at 12:14 Comment(2)
Thank you! Your answer triggered my "Aha" moment; I didn't realise that requiring the compiled Node.js module would connect to the REPL. I'll write up an answer with what worked for me.Pickaninny
For anyone's information, Calva gives you quick access to connect a node-repl. At Jack-in/connect, choose node-repl instead of the build id, when prompted about which REPL to connect to.Gendarmerie

© 2022 - 2024 — McMap. All rights reserved.