8

In languages like Clojure and Scheme I do really enjoy writing code in REPL-driven mode, when you write a piece of code in an editor (Emacs in my case), send it to your REPL, play with it then go back to an editor, fix found issues and send code to REPL again.

I tried to do the same with Node.js, and it kind of works if I limit myself to usage of ES5 syntax only. But if I use ES6 features like const, let and class, I expectedly get errors on re-evaluation of my declarations:

> let foo = 1;
> let foo = 2;
TypeError: Identifier 'foo' has already been declared

Is there any Node.js REPL params, or maybe patched REPLs, or even some magical Emacs mode which will purge existing declarations when I re-evaluate my code? So that I will be able to write Node.js code this way without the need to constantly think about which syntax I am using and/or the need to restart REPL manually on each re-evaluation.

0

3 Answers 3

2
+50

if you are using nodejs-repl, you can eval (M-:) the following code :

(with-current-buffer "*nodejs*" 
  (setq kill-buffer-query-functions (delq 'process-kill-buffer-query-function kill-buffer-query-functions))
  (kill-process nil comint-ptyp) 
  (kill-buffer-and-window) 
  (run-with-timer 0.01 nil (lambda () (nodejs-repl))
))

This is not an optimal solution, but here's how it works :

  • It evals emacs lisp code in the current buffer
  • It kills the function that ask you if you want to kill the window (confirmation in the minibuffer)
  • It stops the process that allows the communication between nodejs and emacs, so it kills nodejs process (comint-ptyp)
  • It re-runs nodejs-repl

If you want to run it with another REPL, just change the buffer name and the command to 're-run'.

Hope it helps,

Best regards


EDIT

Here's a more suitable solution, add this to your .emacs or to the nodejs-repl.el :

(defun nodejs-repl-restart ()
  "restart the nodejs REPL"
  (interactive)
  (defvar nodejs-repl-code
    (concat "process.stdout.columns = %d;" "require('repl').start('%s', null, null, true, false)"))
  (with-current-buffer "*nodejs*"
    (kill-process nil comint-ptyp)
    (run-with-timer 0.01 nil (lambda ()
                  (setq nodejs-repl-prompt-re (format nodejs-repl-prompt-re-format nodejs-repl-prompt nodejs-repl-prompt))
                  (with-current-buffer "*nodejs*"
                (apply 'make-comint nodejs-repl-process-name nodejs-repl-command nil `("-e" ,(format nodejs-repl-code (window-width) nodejs-repl-prompt)))
                (nodejs-repl-mode) (erase-buffer) ))))) 

It almost does the same, but it doesn't kill the buffer and it erase it.

1

Node.js has good basis for REPL driven development. Multiple factors for approving it:

  • JavaScript is interpreted language and supports eval
  • Ability to write statefull programs and change this state in some way
  • Ability to connect to Node.js process via inspect protocol and execute arbitrary code, that can change internal state of program

ClojureScript projects, like nbb uses this possibilities for successful REPL driven development on Node.js directly. Also exists another tools, that allow to feel Clojure like REPL driven development, but using JavaScript/TypeScript:

  • node-remote-repl - command line tool for executing arbitrary file code on remote (likely localhost) Node.js process via inspect protocol. This command line tool can be integrated with any IDE, VSCode example provided. This project inspired by Clojure nREPL.
  • repl-ns - Implementation of namespace, inspired by Clojure namespace directly, which allows to write REPL driven development friendly code, with program state preserving by default.

node-remote-repl + repl-ns inspired by Clojure and allows to feel Clojure way of RDD in Node.js using JavaScript/TypeScript. By the way, RDD excellent for TUI developing, because it stateful often. ytdl-tui - TUI, which written totally using RDD and tools, mentioned above, feel free to use it as source of inspiration.

Few words about native Node.js REPL. I think it's toy tool, which allows to execute little snippets of code, but no good for big serious project.

1

I wrote Replete, an evaluator for JavaScript modules. It supports import statements, and evaluates code in the browser, Node.js and Deno. There is an Emacs plugin, among others.

Demo of Replete

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.