Node.js v11.14.0 文档


repl(交互式解释器)#

中英对照提交修改

稳定性: 2 - 稳定

repl 模块提供了一种“读取-求值-输出”循环(REPL)的实现,它可作为一个独立的程序或嵌入到其他应用中。 可以通过以下方式使用它:

const repl = require('repl');

设计与特性#

中英对照提交修改

repl 模块导出了 repl.REPLServer 类。 当 repl.REPLServer 实例运行时,它接收用户输入的每一行,根据用户定义的解释函数解释这些输入,然后输出结果。 输入可以是 stdin,输出可以是 stdout,或者也可以连接到其他任何 Node.js

repl.REPLServer 实例支持输入的自动补全、精简 Emacs 风格的行编辑、多行输入、ANSI 风格的输出、当前 REPL 会话状态的保存与恢复、错误校正、以及可定制的解释函数。

命令与特殊键#

查看v10.x中文文档

The following special commands are supported by all REPL instances:

  • .break - When in the process of inputting a multi-line expression, entering the .break command (or pressing the <ctrl>-C key combination) will abort further input or processing of that expression.
  • .clear - Resets the REPL context to an empty object and clears any multi-line expression currently being input.
  • .exit - Close the I/O stream, causing the REPL to exit.
  • .help - Show this list of special commands.
  • .save - Save the current REPL session to a file: > .save ./file/to/save.js
  • .load - Load a file into the current REPL session. > .load ./file/to/load.js
  • .editor - Enter editor mode (<ctrl>-D to finish, <ctrl>-C to cancel).
> .editor
// Entering editor mode (^D to finish, ^C to cancel)
function welcome(name) {
  return `Hello ${name}!`;
}

welcome('Node.js User');

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

The following key combinations in the REPL have these special effects:

  • <ctrl>-C - When pressed once, has the same effect as the .break command. When pressed twice on a blank line, has the same effect as the .exit command.
  • <ctrl>-D - Has the same effect as the .exit command.
  • <tab> - When pressed on a blank line, displays global and local (scope) variables. When pressed while entering other input, displays relevant autocompletion options.

默认的解释器#

中英对照提交修改

默认情况下,所有 repl.REPLServer 实例使用了一个解释函数,它可以解释 JavaScript 表达式、提供对 Node.js 内置模块的访问。 当 repl.REPLServer 实例被创建时可以传入一个替换的解释函数,覆盖其默认的功能。

JavaScript 表达式#

查看v10.x中文文档

The default evaluator supports direct evaluation of JavaScript expressions:

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

Unless otherwise scoped within blocks or functions, variables declared either implicitly or using the const, let, or var keywords are declared at the global scope.

全局作用域与局部作用域#

查看v10.x中文文档

The default evaluator provides access to any variables that exist in the global scope. It is possible to expose a variable to the REPL explicitly by assigning it to the context object associated with each REPLServer:

const repl = require('repl');
const msg = 'message';

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

Properties in the context object appear as local within the REPL:

$ node repl_test.js
> m
'message'

Context properties are not read-only by default. To specify read-only globals, context properties must be defined using Object.defineProperty():

const repl = require('repl');
const msg = 'message';

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

访问 Node.js 核心模块#

查看v10.x中文文档

The default evaluator will automatically load Node.js core modules into the REPL environment when used. For instance, unless otherwise declared as a global or scoped variable, the input fs will be evaluated on-demand as global.fs = require('fs').

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

全局的未捕获异常#

中英对照提交修改

REPL使用 domain 模块来捕获会话期间的所有未捕获异常。

在REPL中使用 domain 模块有如下副作用:

_(下划线)变量的赋值#

查看v10.x中文文档

The default evaluator will, by default, assign the result of the most recently evaluated expression to the special variable _ (underscore). Explicitly setting _ to a value will disable this behavior.

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

Similarly, _error will refer to the last seen error, if there was any. Explicitly setting _error to a value will disable this behavior.

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

await 关键词#

查看v10.x中文文档

With the --experimental-repl-await command line option specified, experimental support for the await keyword is enabled.

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

自定义的解释函数#

中英对照提交修改

当创建一个新的 repl.REPLServer 时,可以提供一个自定义的解释函数。 这可以用于实现完全定制化的 REPL 应用。

例子,一个执行文本翻译的 REPL:

const repl = require('repl');
const { Translator } = require('translator');

const myTranslator = new Translator('en', 'fr');

function myEval(cmd, context, filename, callback) {
  callback(null, myTranslator.translate(cmd));
}

repl.start({ prompt: '> ', eval: myEval });

可恢复的错误#

中英对照提交修改

当用户正在 REPL 中输入时,按下 <enter> 键会把当前行的输入发送到 eval 函数。 为了支持多行输入, eval 函数可以返回一个 repl.Recoverable 实例给提供的回调函数:

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 输出#

查看v10.x中文文档

By default, repl.REPLServer instances format output using the util.inspect() method before writing the output to the provided Writable stream (process.stdout by default). The showProxy inspection option is set to true by default and the colors option is set to true depending on the REPL's useColors option.

The useColors boolean option can be specified at construction to instruct the default writer to use ANSI style codes to colorize the output from the util.inspect() method.

If the REPL is run as standalone program, it is also possible to change the REPL's inspection defaults from inside the REPL by using the inspect.replDefaults property which mirrors the defaultOptions from util.inspect().

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

To fully customize the output of a repl.REPLServer instance pass in a new function for the writer option on construction. The following example, for instance, simply converts any input text to upper case:

const repl = require('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 类#

中英对照提交修改

repl.REPLServer 类继承自 readline.Interface 类。 repl.REPLServer 的实例由 repl.start() 方法创建,不能直接使用 JavaScript 的 new 关键字创建。

'exit' 事件#

中英对照提交修改

当接收到 .exit 命令、或按下两次 <ctrl>-C 发出 SIGINT 信号、或按下 <ctrl>-D 发出 'end' 信号而使 REPL 被退出时,触发 'exit' 事件。 监听器的回调函数被调用时不带任何参数。

replServer.on('exit', () => {
  console.log('从 REPL 接收到 "exit" 事件!');
  process.exit();
});

'reset' 事件#

查看v10.x中文文档

The 'reset' event is emitted when the REPL's context is reset. This occurs whenever the .clear command is received as input unless the REPL is using the default evaluator and the repl.REPLServer instance was created with the useGlobal option set to true. The listener callback will be called with a reference to the context object as the only argument.

This can be used primarily to re-initialize REPL context to some pre-defined state:

const repl = require('repl');

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

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

r.on('reset', initializeContext);

When this code is executed, the global 'm' variable can be modified but then reset to its initial value using the .clear command:

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

replServer.defineCommand(keyword, cmd)#

中英对照提交修改

  • keyword <string> 命令关键字(开头不带 . 字符)。
  • cmd <Object> | <Function> 当命令被执行时调用的函数。

replServer.defineCommand() 方法用于添加新的前缀为 . 的命令到 REPL 实例。 这些命令通过输入一个 .keyword 来调用。 cmd 可以是一个函数或一个具有以下属性的对象:

  • help <string> 当键入 .help 时显示的帮助说明(可选)。
  • action <Function> 要执行的函数,可接受一个字符串参数。

例子,添加两个新命令到 REPL 实例:

const repl = require('repl');

const replServer = repl.start({ prompt: '> ' });
replServer.defineCommand('sayhello', {
  help: '打招呼',
  action(name) {
    this.clearBufferedCommand();
    console.log(`你好, ${name}!`);
    this.displayPrompt();
  }
});
replServer.defineCommand('saybye', function saybye() {
  console.log('再见!');
  this.close();
});

在 REPL 实例中使用新的命令:

> .sayhello Node.js中文网
你好,Node.js中文网!
> .saybye
再见!

replServer.displayPrompt([preserveCursor])#

中英对照提交修改

replServer.displayPrompt() 方法会让 REPL 实例做好用户输入的准备,打印配置的 promptoutput 中新的一行,然后返回 input 等待新的输入。

当正在键入多行输入时,会打印省略号而不是提示符。

preserveCursortrue 时,游标位置不会被复位到 0

replServer.displayPrompt 方法主要被使用 replServer.defineCommand() 方法注册的命令的 action 函数调用。

replServer.clearBufferedCommand()#

中英对照提交修改

replServer.clearBufferedCommand() 方法清除已缓冲但尚未执行的任何命令。 此方法主要用于在使用 replServer.defineCommand() 方法注册的命令的 action 函数内调用。

replServer.parseREPLKeyword(keyword[, rest])#

暂无中英对照

  • keyword <string> the potential keyword to parse and execute
  • rest <any> any parameters to the keyword command
  • Returns: <boolean>

稳定性: 0 - 废弃.

An internal method used to parse and execute REPLServer keywords. Returns true if keyword is a valid keyword, otherwise false.

replServer.setupHistory(historyPath, callback)#

暂无中英对照

Initializes a history log file for the REPL instance. When executing the Node.js binary and using the command line REPL, a history file is initialized by default. However, this is not the case when creating a REPL programmatically. Use this method to initialize a history log file when working with REPL instances programmatically.

repl.start([options])#

中英对照提交修改

  • options <Object> | <string>

    • prompt <string> 要显示的输入提示符。默认为 '> '(末尾有一个空格)。
    • input <stream.Readable> REPL 输入要被读取的可读流。默认为 process.stdin
    • output <stream.Writable> REPL 输出要被写入的可写流。默认为 process.stdout
    • terminal <boolean> 如果为 true,则指定 output 应被当作一个 TTY 终端,并且可以使用 ANSI/VT100 转义码写入。 默认值为初始化时 output 流的 isTTY 属性的值。
    • eval <Function> 当解释每行输入时使用的函数。默认为 JavaScript eval() 函数的异步封装。 eval 函数出错时会返回 repl.Recoverable,表明输入不完整并提示用户完成输入。
    • useColors <boolean> 如果为 true,则指定默认的 writer 函数可以在 REPL 输出中包含 ANSI 颜色风格。 如果提供了自定义的 writer 函数,则该参数无效。 默认为 REPL 实例的 terminal 属性的值。
    • useGlobal <boolean> 如果为 true,则指定默认的解释函数使用 JavaScript global 作为上下文,而不是为 REPL 实例创建一个新的独立的上下文。    在node命令行(node CLI)交互解释器中,这个值为 true. 默认为 false
    • ignoreUndefined <boolean> 如果为 true,则指定默认的输出器不会输出命令返回的 undefined 值。 默认为 false
    • writer <Function> 在写入到 output 之前,该函数被调用用来格式化每个命令的输出。 默认为 util.inspect()
    • completer <Function> 可选的函数,用来自定义 Tab 键的自动补全。 详见 readline.InterfaceCompleter
    • replMode <symbol> 一个标志位,指定默认的解释器使用严格模式或默认(sloppy)模式来执行 JavaScript 命令。 可选的值有

      • repl.REPL_MODE_SLOPPY - 使用默认模式解释表达式。
      • repl.REPL_MODE_STRICT - 使用严格模式解释表达式。该模式等同于在每个 repl 声明前加上 'use strict'
    • breakEvalOnSigint - 当接收到 SIGINT 时停止解释当前代码,比如按下 Ctrl+C。 不能与自定义的 eval 函数同时使用。 默认为 false
  • 返回: <repl.REPLServer>

repl.start() 方法创建并启动一个 repl.REPLServer 实例。

如果 options 是一个字符串,则它指定了输入提示符:

const repl = require('repl');

// 一个 Unix 风格的提示符
repl.start('$ ');

Node.js 的 REPL#

查看v10.x中文文档

Node.js itself uses the repl module to provide its own interactive interface for executing JavaScript. This can be used by executing the Node.js binary without passing any arguments (or by passing the -i argument):

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

环境变量选项#

查看v10.x中文文档

Various behaviors of the Node.js REPL can be customized using the following environment variables:

  • NODE_REPL_HISTORY - When a valid path is given, persistent REPL history will be saved to the specified file rather than .node_repl_history in the user's home directory. Setting this value to '' (an empty string) will disable persistent REPL history. Whitespace will be trimmed from the value. On Windows platforms environment variables with empty values are invalid so set this variable to one or more spaces to disable persistent REPL history.
  • NODE_REPL_HISTORY_SIZE - Controls how many lines of history will be persisted if history is available. Must be a positive number. Default: 1000.
  • NODE_REPL_MODE - May be either 'sloppy' or 'strict'. Default: 'sloppy', which will allow non-strict mode code to be run.

历史记录#

中英对照提交修改

默认情况下,Node.js REPL 模块会把 node REPL 会话之间的历史记录保存到用户目录中的 .node_repl_history 文件。 修改环境变量 NODE_REPL_HISTORY='' 可以禁用该功能。

在高级的行编辑器中使用 Node.js REPL#

中英对照提交修改

对于高级的行编辑器,可以使用环境变量 NODE_NO_READLINE=1 来启动 Node.js。 这会以标准的终端配置来启动主 REPL 和调试 REPL,可以使用 rlwrap

例如,可以在 .bashrc 文件中添加:

alias node="env NODE_NO_READLINE=1 rlwrap node"

在一个 Node.js 实例中启动