Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

  • ClojureScript v1.10
  • Node.js v12
  • shadow-cljs v2.8.55
  • Visual Studio Code Calva extension (running in a VS Code remote container)

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?

like image 211
customcommander Avatar asked Sep 23 '19 10:09

customcommander


2 Answers

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

like image 187
customcommander Avatar answered Sep 20 '22 11:09

customcommander


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.

like image 29
Thomas Heller Avatar answered Sep 18 '22 11:09

Thomas Heller