Node.js REPL

2022-02-26 10:30 更新

REPL即Node自帶的交互式解釋器,它可以實現(xiàn)如下的任務:

  • 讀?。≧ead)- 可以讀取用戶的輸入,解析輸入的Javascript數(shù)據(jù)結構并存儲在內存中。
  • 執(zhí)行(Eval)- 可以執(zhí)行輸入的Javascript數(shù)據(jù)結構。
  • 打印(Print)- 打印輸出結果。
  • 循環(huán)(Loop)- 對上述的步驟進行循環(huán),如果需要退出,則用戶需要兩次按下ctrl-c按鈕。
穩(wěn)定性: 3 - 穩(wěn)定

Read-Eval-Print-Loop (REPL 讀取-執(zhí)行-輸出循環(huán))即可作為獨立程序,也可以集成到其他程序中。

REPL提供了一種交互的執(zhí)行JavaScript并查看輸出結果的方法??梢杂脕碚{試,測試,或僅是用來試試。

在命令行中不帶任何參數(shù)的執(zhí)行node,就是REPL模式。它提供了簡單的emacs行編輯。

mjr:~$ node
Type '.help' for options.
> a = [ 1, 2, 3];
[ 1, 2, 3 ]
> a.forEach(function (v) {
...   console.log(v);
...   });
1
2
3

若想使用高級的編輯模式,使用環(huán)境變量NODE_NO_READLINE=1打開node。這樣會開啟REPL模式,允許你使用rlwrap

例如,你可以添加以下代碼到你的bashrc文件里。

alias node="env NODE_NO_READLINE=1 rlwrap node"

repl.start(options)

啟動并返回一個REPLServer實例。它繼承自[Readline Interface][]。接收的參數(shù)"options"有以下值:

  • prompt- 所有輸入輸出的提示符和流,默認是>.

  • input- 需要監(jiān)聽的可讀流,默認為process.stdin.

  • output- 用來輸出數(shù)據(jù)的可寫流,默認為process.stdout.

  • terminal- 如果stream被當成TTY,并且有ANSI/VT100轉義,傳輸true。默認在實例的輸出流上檢查isTTY

  • eval- 用來對每一行進行求值的函數(shù)。默認為eval()的異步封裝。參見后面的自定義eval例子。

  • useColors- 寫函數(shù)輸出是否有顏色。如果設定了不同的writer函數(shù)則無效。默認為 repl 的terminal值。

  • useGlobal- 如果為true,則repl將會使用全局對象,而不是在獨立的上下文中運行scripts。默認為false

  • ignoreUndefined- 如果為true,repl不會輸出未定義命令的返回值。默認為false。

  • writer- 每個命令行被求值時都會調用這個函數(shù),它會返回格式化顯示內容(包括顏色)。默認是util.inspect

如果有以下特性,可以使用自己的eval函數(shù):

function eval(cmd, context, filename, callback) {
  callback(null, result);
}

在同一個node的運行實例上,可以打開多個REPLs。每個都會共享一個全局對象,但會有獨立的I/O。

以下的例子,在stdin、 Unix socket和 TCP socket上開啟REPL :

var net = require("net"),
    repl = require("repl");

connections = 0;

repl.start({
  prompt: "node via stdin> ",
  input: process.stdin,
  output: process.stdout
});

net.createServer(function (socket) {
  connections += 1;
  repl.start({
    prompt: "node via Unix socket> ",
    input: socket,
    output: socket
  }).on('exit', function() {
    socket.end();
  })
}).listen("/tmp/node-repl-sock");

net.createServer(function (socket) {
  connections += 1;
  repl.start({
    prompt: "node via TCP socket> ",
    input: socket,
    output: socket
  }).on('exit', function() {
    socket.end();
  });
}).listen(5001);

從命令行運行這個程序,將會在stdin上啟動REPL。其他的REPL客戶端可能通過Unix socket或TCP socket連接。telnet常用于連接TCP socket,socat用于連接Unix和TCP sockets

從Unix socket-based服務器啟動REPL(而非stdin),你可以建立長連接,不用重啟它們。

通過net.Servernet.Socket實例運行"full-featured" (terminal) REPL的例子,參見: https://gist.github.com/2209310

通過curl(1)實例運行REPL的例子,參見: https://gist.github.com/2053342

Event: 'exit'

function () {}

當用戶通過預定義的方式退出REPL將會觸發(fā)這個事件。預定義的方式包括,在repl里輸入.exit,按Ctrl+C兩次來發(fā)送SIGINT信號,或者在input流上按Ctrl+D 來發(fā)送"end"。

監(jiān)聽exit的例子:

r.on('exit', function () {
  console.log('Got "exit" event from repl!');
  process.exit();
});

Event: 'reset'

function (context) {}

重置REPL的上下文的時候觸發(fā)。當你輸入.clear會重置。如果你用{ useGlobal: true }啟動repl,那這個事件永遠不會被觸發(fā)。

監(jiān)聽reset的例子:

// Extend the initial repl context.
r = repl.start({ options ... });
someExtension.extend(r.context);

// When a new context is created extend it as well.
r.on('reset', function (context) {
  console.log('repl has a new context');
  someExtension.extend(context);
});

REPL 特性

在REPL里, Control+D會退出??梢暂斎攵嘈斜磉_式。支持全局變量和局部變量的TAB自動補全。

特殊變量_(下劃線)包含上一個表達式的結果。

> [ "a", "b", "c" ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
4

REPL支持在全局域里訪問任何變量。將變量賦值個和REPLServer關聯(lián)的上下文對象,你可以顯示的講變量暴露給REPL,例如:

// repl_test.js
var repl = require("repl"),
    msg = "message";

repl.start("> ").context.m = msg;

context對象里的東西,會以局部變量的形式出現(xiàn):

mjr:~$ node repl_test.js
> m
'message'

有一些特殊的REPL命令:

  • .break - 當你輸入多行表達式時,也許你走神了或者不想完成了,.break可以重新開始。
  • .clear - 重置context對象為空對象,并且清空多行表達式。
  • .exit - 關閉輸入/輸出流,會讓REPL退出。
  • .help - 打印這些特殊命令。
  • .save - 保存當前REPL會話到文件。

    .save ./file/to/save.js

  • .load- 加載一個文件到當前REPL會話

    .load ./file/to/load.js

下面的組合鍵在REPL中有以下效果:

  • <ctrl>C- 和.break鍵類似,在一個空行連按兩次會強制退出。
  • <ctrl>D- 和.exit鍵類似。


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號