Clojure China

关于 Node.js 环境连接 nREPL

#1

Calcit Editor 最近把 Socket REPL 的支持换成了 nREPL, 所以过程当中把 nREPL 了解了一下.
Socket REPL 类型 Unix 字符串流, nREPL 是通过编码和数据结构来传递的.
细节要看文章了… 还是 ClojureVerse 站长写的…

Node 当中是用的 npm 模块, 虽然文档没写很好, 但是用下来是能跑的.

我用 CoffeeScript 试验用的一些脚本.

client = require('nrepl-client').connect port: 59734
client
  .once 'connect', () ->

    # client.clone (err, result) ->
    #   console.log 'cloned', err, result

    # expr = '(shadow.cljs.devtools.api/repl :client)\n';

    # client.lsSessions (err, result) ->
    #   console.log 'lss', err, result

    # #   client.close result[0].sessions[0], (err, result) ->
    # #     console.log 'close', err, result

    newSession = '290ec7da-f66c-4e2a-9b1d-8604a50a282a'

    # code = '(def a 1)'
    # code2 = """
    #   ; (js/alert "gooo")
    #   (println a)
    # """

    client.stdin '(println (range 30))\n\n', (err, result) ->
      console.log err, result

    # client.eval code2, 'app.main', newSession, (err, result) ->
    #   console.log 'eval', err, result


    #   client.eval '(println 1)', ns, session, (err, result) ->
    #     console.log 'eval', err, result

大致使用要注意一些事情,

  • nREPL 有 session 的概念, 所有 .eval(...) API 有个 session id 要传递, 可选的.
    代码启动的 Session 似乎是临时的, 所以先要调用 .clone() 创建一个新的 session.
  • .eval(...) 有个默认的参数 ns, 表示的是代码执行的 ns. 听说默认值是 user.
  • .eval(...) 之后的返回值是 Vector, 然而长度是不固定的,
    而且根据返回内容是 error / out / value 有多种细微不同的结构.
  • lsSession() 接口可以获取到当前存在的 Session, 数组里面是可以的 session.
    就像前面说的, 似乎发送代码用的是临时的 session, 这个 session id 没啥用的的.

虽然整个 API 是回调写法的, 用起来不是那么舒服… 但是不出 bug 也算不错了.

我的场景里是用 nREPL 连接 shadow-cljs 的运行环境, 然后发送代码到运行时. 还够用.