Node.js 中的 REPL 驱动开发
REPL Driven Development in Node.js
在 Clojure
和 Scheme
这样的语言中,我真的很喜欢在 REPL 驱动模式下编写代码,当你在编辑器中编写一段代码时(Emacs
在我的例子中), 将其发送到您的 REPL,使用它然后返回到编辑器,修复发现的问题并再次将代码发送到 REPL。
我尝试对 Node.js
做同样的事情,如果我限制自己只使用 ES5
语法,它就可以工作。但是,如果我使用 ES6
功能,如 const
、let
和 class
,我预计会在重新评估我的声明时遇到错误:
> let foo = 1;
> let foo = 2;
TypeError: Identifier 'foo' has already been declared
是否有任何 Node.js REPL
参数,或者是否有补丁 REPLs
,甚至是一些神奇的 Emacs
模式,当我重新评估我的代码时,它会清除现有的声明?这样我就能够以这种方式编写 Node.js
代码,而无需不断思考我使用的是哪种语法 and/or 需要在每次重新评估时手动重新启动 REPL
。
如果您正在使用 nodejs-repl
,您可以评估 (M-:
) 以下代码:
(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))
))
这不是最佳解决方案,但它是这样工作的:
- 它评估当前缓冲区中的 emacs lisp 代码
- 它杀死询问你是否要杀死的函数window(在迷你缓冲区中确认)
- 它停止了允许 nodejs 和 emacs 之间通信的进程,因此它杀死了 nodejs 进程(comint-ptyp)
- 重新运行s
nodejs-repl
如果你想 运行 它与另一个 REPL,只需将缓冲区名称和命令更改为 're-run'。
希望对您有所帮助,
此致
编辑
这是一个更合适的解决方案,将其添加到您的 .emacs
或 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) )))))
它的作用几乎相同,但它不会杀死缓冲区并将其擦除。
在 Clojure
和 Scheme
这样的语言中,我真的很喜欢在 REPL 驱动模式下编写代码,当你在编辑器中编写一段代码时(Emacs
在我的例子中), 将其发送到您的 REPL,使用它然后返回到编辑器,修复发现的问题并再次将代码发送到 REPL。
我尝试对 Node.js
做同样的事情,如果我限制自己只使用 ES5
语法,它就可以工作。但是,如果我使用 ES6
功能,如 const
、let
和 class
,我预计会在重新评估我的声明时遇到错误:
> let foo = 1;
> let foo = 2;
TypeError: Identifier 'foo' has already been declared
是否有任何 Node.js REPL
参数,或者是否有补丁 REPLs
,甚至是一些神奇的 Emacs
模式,当我重新评估我的代码时,它会清除现有的声明?这样我就能够以这种方式编写 Node.js
代码,而无需不断思考我使用的是哪种语法 and/or 需要在每次重新评估时手动重新启动 REPL
。
如果您正在使用 nodejs-repl
,您可以评估 (M-:
) 以下代码:
(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))
))
这不是最佳解决方案,但它是这样工作的:
- 它评估当前缓冲区中的 emacs lisp 代码
- 它杀死询问你是否要杀死的函数window(在迷你缓冲区中确认)
- 它停止了允许 nodejs 和 emacs 之间通信的进程,因此它杀死了 nodejs 进程(comint-ptyp)
- 重新运行s
nodejs-repl
如果你想 运行 它与另一个 REPL,只需将缓冲区名称和命令更改为 're-run'。
希望对您有所帮助,
此致
编辑
这是一个更合适的解决方案,将其添加到您的 .emacs
或 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) )))))
它的作用几乎相同,但它不会杀死缓冲区并将其擦除。