Skip to content

REPL

[Stable: 2 - Stable]

Stable: 2 Stability: 2 - Stable

ソースコード: lib/repl.js

node:repl モジュールは、スタンドアロンプログラムとして、または他のアプリケーションに含めることができる Read-Eval-Print-Loop(REPL)実装を提供します。次のようにアクセスできます。

js
import repl from 'node:repl'
js
const repl = require('node:repl')

設計と機能

node:repl モジュールは、repl.REPLServer クラスをエクスポートします。実行中は、repl.REPLServer のインスタンスは、ユーザー入力の個々の行を受け取り、ユーザー定義の評価関数に従ってそれらを評価し、結果を出力します。入出力はそれぞれ stdinstdout から行うことも、任意の Node.js ストリーム に接続することもできます。

repl.REPLServer のインスタンスは、入力の自動補完、補完プレビュー、単純な Emacs スタイルの行編集、複数行入力、ZSHのような逆 i 検索、ZSHのような部分文字列ベースの履歴検索、ANSI スタイルの出力、現在の REPL セッション状態の保存と復元、エラー回復、およびカスタマイズ可能な評価関数をサポートしています。ANSI スタイルと Emacs スタイルの行編集をサポートしていない端末は、自動的に機能が限定されたセットにフォールバックします。

コマンドと特殊キー

次の特殊コマンドは、すべての REPL インスタンスでサポートされています。

  • .break:複数行の式を入力している途中で、.break コマンドを入力するか(または Ctrl + C を押す)して、その式のさらなる入力または処理を中止します。
  • .clear:REPL context を空のオブジェクトにリセットし、入力中の複数行式をクリアします。
  • .exit:I/O ストリームを閉じ、REPL を終了します。
  • .help:この特殊コマンドのリストを表示します。
  • .save:現在の REPL セッションをファイルに保存します:> .save ./file/to/save.js
  • .load:現在の REPL セッションにファイルを読み込みます。> .load ./file/to/load.js
  • .editor:エディターモードに入ります(Ctrl + D で終了、Ctrl + C でキャンセル)。
bash
> .editor
// エディターモードに入ります(^Dで終了、^Cでキャンセル)
function welcome(name) {
  return `Hello ${name}!`;
}

welcome('Node.js User');

// ^D
'Hello Node.js User!'
>

REPL での次のキー組み合わせには、次の特殊効果があります。

  • Ctrl + C:1 回押すと、.break コマンドと同じ効果があります。空行で 2 回押すと、.exit コマンドと同じ効果があります。
  • Ctrl + D:.exit コマンドと同じ効果があります。
  • Tab:空行で押すと、グローバル変数とローカル変数(スコープ)が表示されます。他の入力を入力中に押すと、関連する自動補完オプションが表示されます。

逆 i 検索に関連するキーバインドについては、reverse-i-searchを参照してください。その他のキーバインドについては、TTY キーバインドを参照してください。

デフォルトの評価

デフォルトでは、repl.REPLServerのすべてのインスタンスは、JavaScript 式を評価し、Node.js 組み込みモジュールへのアクセスを提供する評価関数を使用します。このデフォルトの動作は、repl.REPLServerインスタンスの作成時に代替の評価関数を渡すことでオーバーライドできます。

JavaScript 式

デフォルトの評価関数は、JavaScript 式の直接的な評価をサポートします。

bash
> 1 + 1
2
> const m = 2
undefined
> m + 1
3

ブロックまたは関数内でスコープが指定されていない限り、constlet、またはvarキーワードを使用して暗黙的に宣言された変数は、グローバルスコープで宣言されます。

グローバルスコープとローカルスコープ

デフォルトの評価関数は、グローバルスコープに存在するすべての変数へのアクセスを提供します。各REPLServerに関連付けられたcontextオブジェクトに代入することで、変数を REPL に明示的に公開できます。

js
import repl from 'node:repl'
const msg = 'message'

repl.start('> ').context.m = msg
js
const repl = require('node:repl')
const msg = 'message'

repl.start('> ').context.m = msg

contextオブジェクトのプロパティは、REPL 内でローカルとして表示されます。

bash
$ node repl_test.js
> m
'message'

コンテキストプロパティは、デフォルトでは読み取り専用ではありません。読み取り専用のグローバル変数を指定するには、Object.defineProperty()を使用してコンテキストプロパティを定義する必要があります。

js
import repl from 'node:repl'
const msg = 'message'

const r = repl.start('> ')
Object.defineProperty(r.context, 'm', {
  configurable: false,
  enumerable: true,
  value: msg,
})
js
const repl = require('node:repl')
const msg = 'message'

const r = repl.start('> ')
Object.defineProperty(r.context, 'm', {
  configurable: false,
  enumerable: true,
  value: msg,
})

Node.js コアモジュールへのアクセス

デフォルトの評価関数は、使用時に Node.js コアモジュールを REPL 環境に自動的にロードします。例えば、グローバル変数またはスコープ変数として宣言されていない限り、入力fsはオンデマンドでglobal.fs = require('node:fs')として評価されます。

bash
> fs.createReadStream('./some/file');

グローバル未キャッチ例外

[履歴]

バージョン変更
v12.3.0'uncaughtException' イベントは、REPL がスタンドアロン プログラムとして使用されている場合にトリガーされるようになりました。

REPL は、その REPL セッションのすべての未キャッチ例外をキャッチするために domain モジュールを使用します。

REPL での domain モジュールのこの使用法には、次の副作用があります。

_(アンダースコア)変数の代入

[履歴]

バージョン変更
v9.8.0_error サポートを追加

デフォルトの評価子は、デフォルトで、最後に評価された式の結果を特別な変数 _ (アンダースコア)に代入します。_ に明示的に値を設定すると、この動作は無効になります。

bash
> [ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
Expression assignment to _ now disabled.
4
> 1 + 1
2
> _
4

同様に、_error は、存在する場合は最後に発生したエラーを参照します。_error に明示的に値を設定すると、この動作は無効になります。

bash
> throw new Error('foo');
Uncaught Error: foo
> _error.message
'foo'

await キーワード

await キーワードのサポートは、最上位レベルで有効になっています。

bash
> await Promise.resolve(123)
123
> await Promise.reject(new Error('REPL await'))
Uncaught Error: REPL await
    at REPL2:1:54
> const timeout = util.promisify(setTimeout);
undefined
> const old = Date.now(); await timeout(1000); console.log(Date.now() - old);
1002
undefined

REPL で await キーワードを使用することの既知の制限事項の 1 つは、constlet キーワードの字句スコープが無効になることです。

例:

bash
> const m = await Promise.resolve(123)
undefined
> m
123
> const m = await Promise.resolve(234)
undefined
> m
234

--no-experimental-repl-await は、REPL で最上位レベルの await を無効にします。

追加バージョン: v13.6.0, v12.17.0

REPL は、ZSHに似た双方向逆引き検索をサポートしています。 Ctrl + Rで後方検索、Ctrl + Sで前方検索が開始されます。

重複した履歴エントリはスキップされます。

逆検索に対応しないキーを押すと、エントリが確定されます。Ctrl + CまたはCtrl + Rを押すとキャンセルできます。

方向を変更すると、現在の位置から期待される方向の次のエントリがすぐに検索されます。

カスタム評価関数

新しいrepl.REPLServerが作成されると、カスタム評価関数を指定できます。これにより、完全にカスタマイズされた REPL アプリケーションを実装できます。

以下は、与えられた数を 2 乗する REPL の例です。

js
import repl from 'node:repl'

function byThePowerOfTwo(number) {
  return number * number
}

function myEval(cmd, context, filename, callback) {
  callback(null, byThePowerOfTwo(cmd))
}

repl.start({ prompt: 'Enter a number: ', eval: myEval })
js
const repl = require('node:repl')

function byThePowerOfTwo(number) {
  return number * number
}

function myEval(cmd, context, filename, callback) {
  callback(null, byThePowerOfTwo(cmd))
}

repl.start({ prompt: 'Enter a number: ', eval: myEval })

回復可能なエラー

REPL プロンプトでCtrl + Dを押すと、現在の入力行がeval関数に送信されます。複数行の入力をサポートするために、eval関数はrepl.Recoverableのインスタンスを指定されたコールバック関数に返すことができます。

js
function myEval(cmd, context, filename, callback) {
  let result
  try {
    result = vm.runInThisContext(cmd)
  } catch (e) {
    if (isRecoverableError(e)) {
      return callback(new repl.Recoverable(e))
    }
  }
  callback(null, result)
}

function isRecoverableError(error) {
  if (error.name === 'SyntaxError') {
    return /^(Unexpected end of input|Unexpected token)/.test(error.message)
  }
  return false
}

REPL 出力のカスタマイズ

デフォルトでは、repl.REPLServerインスタンスは、出力を提供されたWritableストリーム(デフォルトではprocess.stdout)に書き込む前に、util.inspect()メソッドを使用して出力をフォーマットします。showProxy検査オプションはデフォルトで true に設定され、colorsオプションは REPL のuseColorsオプションに応じて true に設定されます。

useColorsブールオプションは、構築時に指定して、デフォルトのライターに ANSI スタイルコードを使用してutil.inspect()メソッドからの出力を色付けするように指示できます。

REPL がスタンドアロンプログラムとして実行される場合、util.inspect()defaultOptionsを反映するinspect.replDefaultsプロパティを使用して、REPL 内から REPL の検査デフォルトを変更することもできます。

bash
> util.inspect.replDefaults.compact = false;
false
> [1]
[
  1
]
>

repl.REPLServerインスタンスの出力を完全にカスタマイズするには、構築時にwriterオプションに新しい関数を渡します。たとえば、次の例では、入力テキストをすべて大文字に変換します。

js
import repl from 'node:repl'

const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter })

function myEval(cmd, context, filename, callback) {
  callback(null, cmd)
}

function myWriter(output) {
  return output.toUpperCase()
}
js
const repl = require('node:repl')

const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter })

function myEval(cmd, context, filename, callback) {
  callback(null, cmd)
}

function myWriter(output) {
  return output.toUpperCase()
}

クラス: REPLServer

追加されたバージョン: v0.1.91

repl.REPLServerのインスタンスは、repl.start()メソッドを使用するか、JavaScript のnewキーワードを使用して直接作成されます。

js
import repl from 'node:repl'

const options = { useColors: true }

const firstInstance = repl.start(options)
const secondInstance = new repl.REPLServer(options)
js
const repl = require('node:repl')

const options = { useColors: true }

const firstInstance = repl.start(options)
const secondInstance = new repl.REPLServer(options)

イベント: 'exit'

追加日: v0.7.7

'exit'イベントは、.exitコマンドを入力として受信した場合、ユーザーが SIGINT をシグナルするために+を 2 回押した場合、または入力ストリームで'end'をシグナルするために+を押した場合に、REPL が終了するときに発生します。リスナーコールバックは引数なしで呼び出されます。

js
replServer.on('exit', () => {
  console.log('Received "exit" event from repl!')
  process.exit()
})

イベント: 'reset'

追加日: v0.11.0

'reset'イベントは、REPL のコンテキストがリセットされるときに発生します。これは、REPL がデフォルトの評価器を使用しておらず、repl.REPLServerインスタンスがuseGlobalオプションをtrueに設定して作成されていない限り、.clearコマンドが入力として受信されるたびに発生します。リスナーコールバックは、contextオブジェクトへの参照を引数として呼び出されます。

これは、主に REPL コンテキストを事前に定義された状態に再初期化するために使用できます。

js
import repl from 'node:repl'

function initializeContext(context) {
  context.m = 'test'
}

const r = repl.start({ prompt: '> ' })
initializeContext(r.context)

r.on('reset', initializeContext)
js
const repl = require('node:repl')

function initializeContext(context) {
  context.m = 'test'
}

const r = repl.start({ prompt: '> ' })
initializeContext(r.context)

r.on('reset', initializeContext)

このコードを実行すると、グローバルな'm'変数は変更できますが、.clearコマンドを使用して初期値にリセットできます。

bash
$ ./node example.js
> m
'test'
> m = 1
1
> m
1
> .clear
Clearing context...
> m
'test'
>

replServer.defineCommand(keyword, cmd)

追加日: v0.3.0

  • keyword <string> コマンドキーワード(先頭に.文字はなし)。
  • cmd <Object> | <Function> コマンドが処理されたときに呼び出す関数。

replServer.defineCommand()メソッドは、REPL インスタンスに新しい.で始まるコマンドを追加するために使用されます。このようなコマンドは、.の後にkeywordを入力することで呼び出されます。cmdは、次のプロパティを持つFunctionまたはObjectです。

  • help <string> .helpが入力されたときに表示されるヘルプテキスト(オプション)。
  • action <Function> 実行する関数。オプションで、単一の文字列引数を受け入れます。

次の例は、REPL インスタンスに追加された 2 つの新しいコマンドを示しています。

js
import repl from 'node:repl'

const replServer = repl.start({ prompt: '> ' })
replServer.defineCommand('sayhello', {
  help: 'Say hello',
  action(name) {
    this.clearBufferedCommand()
    console.log(`Hello, ${name}!`)
    this.displayPrompt()
  },
})
replServer.defineCommand('saybye', function saybye() {
  console.log('Goodbye!')
  this.close()
})
js
const repl = require('node:repl')

const replServer = repl.start({ prompt: '> ' })
replServer.defineCommand('sayhello', {
  help: 'Say hello',
  action(name) {
    this.clearBufferedCommand()
    console.log(`Hello, ${name}!`)
    this.displayPrompt()
  },
})
replServer.defineCommand('saybye', function saybye() {
  console.log('Goodbye!')
  this.close()
})

新しいコマンドは、REPL インスタンス内から使用できます。

bash
> .sayhello Node.js User
Hello, Node.js User!
> .saybye
Goodbye!

replServer.displayPrompt([preserveCursor])

追加日時: v0.1.91

replServer.displayPrompt()メソッドは、REPL インスタンスを使用者からの入力待ち状態にし、設定されたpromptoutputに改行して出力し、新しい入力を受け付けるようにinputを再開します。

複数行の入力が行われている場合、「prompt」ではなく省略記号が表示されます。

preserveCursortrueの場合、カーソルの位置は0にリセットされません。

replServer.displayPromptメソッドは、主にreplServer.defineCommand()メソッドを使用して登録されたコマンドのアクション関数内から呼び出すことを目的としています。

replServer.clearBufferedCommand()

追加日時: v9.0.0

replServer.clearBufferedCommand()メソッドは、バッファリングされているがまだ実行されていないコマンドをクリアします。このメソッドは、主にreplServer.defineCommand()メソッドを使用して登録されたコマンドのアクション関数内から呼び出すことを目的としています。

replServer.setupHistory(historyPath, callback)

追加日時: v11.10.0

REPL インスタンスの履歴ログファイルを開始します。Node.js バイナリを実行し、コマンドライン REPL を使用する場合、履歴ファイルはデフォルトで初期化されます。ただし、プログラムで REPL を作成する場合はそうではありません。プログラムで REPL インスタンスを操作する場合は、このメソッドを使用して履歴ログファイルを開始してください。

repl.builtinModules

追加日時: v14.5.0

すべての Node.js モジュールの名前のリスト、例:「'http'」。

repl.start([options])

[履歴]

バージョン変更点
v13.4.0, v12.17.0preview オプションが利用可能になりました。
v12.0.0terminal オプションはすべての場合においてデフォルトの説明に従うようになり、useColors は利用可能な場合 hasColors() を確認するようになりました。
v10.0.0REPL_MAGIC_MODE replMode が削除されました。
v6.3.0breakEvalOnSigint オプションがサポートされるようになりました。
v5.8.0options パラメータはオプションになりました。
v0.1.91追加:v0.1.91
  • options <Object> | <string>

    • prompt <string> 表示する入力プロンプト。デフォルト: '\> '(末尾にスペース付き)。

    • input <stream.Readable> REPL 入力を読み取る Readable ストリーム。デフォルト: process.stdin

    • output <stream.Writable> REPL 出力を書き込む Writable ストリーム。デフォルト: process.stdout

    • terminal <boolean> true の場合、output を TTY ターミナルとして扱うことを指定します。デフォルト: インスタンス化時に output ストリームの isTTY プロパティの値をチェックします。

    • eval <Function> 入力された各行を評価する際に使用する関数。デフォルト: JavaScript の eval() 関数の非同期ラッパー。eval 関数は、入力が不完全であることを示す repl.Recoverable を使用してエラーを発生させ、追加の行を要求できます。

    • useColors <boolean> true の場合、デフォルトの writer 関数が REPL 出力に ANSI カラースタイルを含めることを指定します。カスタムの writer 関数が提供されている場合、これは効果がありません。デフォルト: REPL インスタンスの terminal の値が true の場合、output ストリームの色サポートをチェックします。

    • useGlobal <boolean> true の場合、デフォルトの評価関数が REPL インスタンスのために新しい個別のコンテキストを作成するのではなく、JavaScript の global をコンテキストとして使用するように指定します。Node CLI REPL はこの値を true に設定します。デフォルト: false

    • ignoreUndefined <boolean> true の場合、デフォルトの writer は、コマンドの戻り値が undefined に評価される場合は、その戻り値を出力しません。デフォルト: false

    • writer <Function> output に書き込む前に、各コマンドの出力をフォーマットするために呼び出す関数。デフォルト: util.inspect()

    • completer <Function> カスタムの Tab オートコンプリートに使用されるオプションの関数。例については、readline.InterfaceCompleter を参照してください。

    • replMode <symbol> デフォルトの評価子がすべての JavaScript コマンドを厳格モードで実行するか、デフォルト(非厳格)モードで実行するかを指定するフラグ。許容される値は次のとおりです。

    • repl.REPL_MODE_SLOPPY は、非厳格モードで式を評価します。

    • repl.REPL_MODE_STRICT は、厳格モードで式を評価します。これは、すべての repl ステートメントの前に 'use strict' を付けることと同じです。

    • breakEvalOnSigint <boolean> SIGINT (例:+キーが押された時)を受信したときに、現在の実行中のコードの実行を停止します。これはカスタムの eval 関数と併用することはできません。デフォルト: false

    • preview <boolean> repl がオートコンプリートと出力プレビューを表示するかどうかを定義します。デフォルト: デフォルトの eval 関数では true、カスタムの eval 関数を使用する場合は falseterminal が偽の場合、プレビューはなく、preview の値は効果がありません。

  • 戻り値: <repl.REPLServer>

repl.start() メソッドは、repl.REPLServer インスタンスを作成して起動します。

options が文字列の場合、入力プロンプトを指定します。

js
import repl from 'node:repl'

// Unixスタイルのプロンプト
repl.start('$ ')
js
const repl = require('node:repl')

// Unixスタイルのプロンプト
repl.start('$ ')

Node.js REPL

Node.js 自体はnode:replモジュールを使用して、JavaScript を実行するための独自のインタラクティブインターフェースを提供します。これは、引数を渡さずに Node.js バイナリを実行するか(または-i引数を渡すことによって)使用できます。

bash
$ node
> const a = [1, 2, 3];
undefined
> a
[ 1, 2, 3 ]
> a.forEach((v) => {
...   console.log(v);
...   });
1
2
3

環境変数オプション

以下の環境変数を使用して、Node.js REPL の様々な動作をカスタマイズできます。

  • NODE_REPL_HISTORY: 有効なパスが指定されている場合、永続的な REPL 履歴は、ユーザーのホームディレクトリにある.node_repl_historyではなく、指定されたファイルに保存されます。この値を''(空文字列)に設定すると、永続的な REPL 履歴が無効になります。空白は値からトリミングされます。Windows プラットフォームでは、空の値を持つ環境変数は無効であるため、永続的な REPL 履歴を無効にするには、この変数を 1 つ以上のスペースに設定します。
  • NODE_REPL_HISTORY_SIZE: 履歴が利用可能な場合、保存される履歴の行数を制御します。正の数でなければなりません。デフォルト: 1000
  • NODE_REPL_MODE: 'sloppy'または'strict'のいずれかになります。デフォルト: 'sloppy'。これは、非厳格モードのコードの実行を許可します。

永続的な履歴

デフォルトでは、Node.js REPL は、ユーザーのホームディレクトリにある.node_repl_historyファイルに入力を保存することで、node REPL セッション間の履歴を保持します。これは、環境変数NODE_REPL_HISTORY=''を設定することで無効にできます。

高度なラインエディタを使用した Node.js REPL

高度なラインエディタを使用するには、環境変数NODE_NO_READLINE=1を使用して Node.js を起動します。これにより、メイン REPL とデバッガー REPL が標準的なターミナル設定で起動され、rlwrapを使用できるようになります。

たとえば、以下を.bashrcファイルに追加できます。

bash
alias node="env NODE_NO_READLINE=1 rlwrap node"

単一の実行インスタンスに対する複数の REPL インスタンスの起動

単一のグローバルオブジェクトを共有しますが、個別の I/O インターフェースを持つ、単一の実行中の Node.js インスタンスに対して、複数の REPL インスタンスを作成して実行することができます。

たとえば、次の例では、stdin、Unix ソケット、および TCP ソケットで個別の REPL を提供します。

js
import net from 'node:net'
import repl from 'node:repl'
import process from 'node:process'

let connections = 0

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout,
})

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

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via TCP socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen(5001)
js
const net = require('node:net')
const repl = require('node:repl')
let connections = 0

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout,
})

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

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

コマンドラインからこのアプリケーションを実行すると、stdin で REPL が起動します。他の REPL クライアントは、Unix ソケットまたは TCP ソケットを介して接続できます。たとえば、telnetは TCP ソケットへの接続に役立ち、socatは Unix ソケットと TCP ソケットの両方に接続するために使用できます。

stdin ではなく Unix ソケットベースのサーバーから REPL を起動することにより、再起動することなく、長期間実行されている Node.js プロセスに接続することができます。

net.Serverおよびnet.Socketインスタンスを介して「フル機能」(terminal) REPL を実行する例については、https://gist.github.com/TooTallNate/2209310を参照してください。

curl(1)を介して REPL インスタンスを実行する例については、https://gist.github.com/TooTallNate/2053342を参照してください。

この例は、Node.js REPL が異なる I/O ストリームを使用してどのように開始できるかを示す教育目的のためだけに意図されています。本番環境またはセキュリティが懸念される状況では、追加の保護対策なしに使用するべきではありません。実世界のアプリケーションで REPL を実装する必要がある場合は、安全な入力メカニズムの使用やオープンネットワークインターフェースの回避など、これらのリスクを軽減する代替アプローチを検討してください。