Spec-Zone.ru › Node.js 8 LTS

REPL

Стабильность: 2 - Стабильно

Модуль repl предоставляет реализацию Read-Eval-Print-Loop (REPL), доступную как самостоятельную программу или для включения в другие приложения. К нему можно обратиться, используя:

const repl = require('repl');

Архитектура и возможности

Модуль repl экспортирует класс repl.REPLServer. Во время работы экземпляры repl.REPLServer будут принимать отдельные строки пользовательского ввода, оценивать их согласно пользовательской функции оценки и затем выводить результат. Ввод и вывод могут происходить из stdin и stdout, соответственно, или могут быть подключены к любому потоку Node.js stream.

Экземпляры repl.REPLServer поддерживают автоматическое завершение ввода, простую редактирование строк в стиле Emacs, многострочный ввод, вывод в стиле ANSI, сохранение и восстановление текущего состояния REPL, восстановление после ошибок и настраиваемые функции оценки.

Команды и специальные клавиши

Следующие специальные команды поддерживаются всеми экземплярами REPL:

  • .break - При вводе многострочного выражения, ввод команды .break (или нажатие комбинации клавиш <ctrl>-C) прервет дальнейший ввод или обработку этого выражения.
  • .clear - Сбрасывает контекст REPL context до пустого объекта и очищает любое многострочное выражение, которое вводится в данный момент.
  • .exit - Закрывает поток ввода/вывода, что приводит к завершению работы REPL.
  • .help - Отображает этот список специальных команд.
  • .save - Сохраняет текущее состояние сессии REPL в файл: > .save ./file/to/save.js
  • .load - Загружает файл в текущую сессию REPL. > .load ./file/to/load.js
  • .editor - Переход в режим редактирования (<ctrl>-D для завершения, <ctrl>-C для отмены)
> .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!'
>

Следующие комбинации клавиш в REPL имеют следующие эффекты:

  • <ctrl>-C - При нажатии один раз, имеет тот же эффект, что и команда .break. При двойном нажатии на пустой строке, имеет тот же эффект, что и команда .exit.
  • <ctrl>-D - Имеет тот же эффект, что и команда .exit.
  • <tab> - При нажатии на пустой строке отображает глобальные и локальные (в области видимости) переменные. При нажатии во время ввода другого ввода отображает соответствующие варианты автозаполнения.

По умолчанию оценка

По умолчанию все экземпляры repl.REPLServer используют функцию оценки, которая оценивает выражения JavaScript и предоставляет доступ к встроенным модулям Node.js. Это поведение по умолчанию может быть переопределено путем передачи альтернативной функции оценки при создании экземпляра repl.REPLServer.

Выражения JavaScript

По умолчанию интерпретатор поддерживает непосредственную оценку выражений JavaScript:

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

Если не указано иное в пределах блоков или функций, переменные, объявленные неявно или с использованием ключевых слов const, let, или var, объявляются на глобальном уровне.

Глобальная и локальная область видимости

По умолчанию интерпретатор предоставляет доступ к любым переменным, которые существуют в глобальной области видимости. Можно явно предоставить переменную для REPL, назначив её объекту context, связанному с каждым REPLServer. Например:

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

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

Свойства объекта context появляются как локальные в REPL:

$ node repl_test.js
> m
'message'

Свойства контекста по умолчанию не являются неизменяемыми. Чтобы указать неизменяемые глобальные свойства, свойства контекста должны быть определены с помощью 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

По умолчанию интерпретатор автоматически загрузит основные модули Node.js в среду REPL при использовании. Например, выражение fs будет оцениваться по требованию как global.fs = require('fs')

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

Назначение переменной _ (ничего)

По умолчанию интерпретатор назначает результат последнего оцененного выражения специальной переменной _ (ничего). Явное задание _ значению отключит это поведение.

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

Пользовательские функции оценки

При создании нового 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

По умолчанию экземпляры repl.REPLServer форматируют вывод, используя метод util.inspect(), прежде чем записывать вывод в предоставленный поток записи (process.stdout по умолчанию). Параметр useColors типа boolean, при указании в момент создания, указывает дефолтному записывателю использовать коды ANSI для окраски вывода метода util.inspect().

Можно полностью настроить вывод экземпляра repl.REPLServer путем передачи новой функции с помощью опции writer при создании. Например, следующий пример просто преобразует любой вводимый текст в верхний регистр:

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

Добавлен в: v0.1.91

Класс repl.REPLServer наследуется от класса readline.Interface. Экземпляры repl.REPLServer создаются с помощью метода repl.start() и не должны создаваться напрямую с помощью ключевого слова JavaScript new.

Событие: 'exit'

Добавлен в: v0.7.7

Событие 'exit' генерируется при выходе из REPL, либо при вводе команды .exit, либо при двойном нажатии пользователем на клавишу <ctrl>-C для сигнализации о SIGINT, или при нажатии <ctrl>-D для сигнализации о 'end' в потоке ввода. Функция обратного вызова вызывается без аргументов.

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

Событие: 'reset'

Добавлен в: v0.11.0

Событие 'reset' генерируется при сбросе контекста REPL. Это происходит всякий раз, когда ввод команды .clear за исключением случая, когда REPL использует интерпретатор по умолчанию и экземпляр repl.REPLServer был создан с опцией useGlobal установленной в true. Функция обратного вызова вызывается со ссылкой на объект context в качестве единственного аргумента.

Это можно использовать в первую очередь для повторной инициализации контекста REPL до некоторого предопределённого состояния, как показано в следующем простом примере:

const repl = require('repl');

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

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

r.on('reset', initializeContext);

Когда этот код выполняется, глобальную переменную 'm' можно изменить, но затем сбросить до её исходного значения с помощью команды .clear:

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

replServer.defineCommand(keyword, cmd)

Добавлен в: v0.3.0
  • keyword <строка> Ключевое слово команды (без ведущего символа .).
  • cmd <Объект> | <Функция> Функция, которая вызывается при обработке команды.

Метод replServer.defineCommand() используется для добавления новых команд, начинающихся с ., в экземпляр REPL. Такие команды вызываются написанием . за которым следует keyword. cmd — это либо функция, либо объект со следующими свойствами:

  • help <строка> Текст справки, который отображается при вводе .help (необязательно).
  • action <Функция> Функция для выполнения, которая по желанию может принимать один строковый аргумент.

Следующий пример демонстрирует две новые команды, добавленные в экземпляр REPL:

const repl = require('repl');

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

Новые команды можно использовать в экземпляре REPL:

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

replServer.displayPrompt([preserveCursor])

Добавлен в: v0.1.91
  • preserveCursor <логическое значение>

Метод replServer.displayPrompt() подготавливает экземпляр REPL для ввода данных пользователем, печатая на новой строке в output конфигурированное значение prompt и возобновляя input для принятия нового ввода.

При вводе многострочного ввода вместо 'prompt' печатается многоточие.

Когда preserveCursor равно true, позиция курсора не будет сброшена к 0.

Метод replServer.displayPrompt предназначен в первую очередь для вызова из функции действия команд, зарегистрированных с помощью метода replServer.defineCommand().

repl.start([options])

История
Версия Изменения
v5.8.0

Параметр options теперь является необязательным.

v0.1.91

Добавлен в: v0.1.91

  • options <Объект> | <строка>
    • prompt <строка> Приглашение для ввода. По умолчанию: >. (с trailing пробелом).
    • input <stream.Readable> Поток Readable для считывания ввода REPL. По умолчанию: process.stdin.
    • output <stream.Writable> Поток Writable для записи вывода REPL. По умолчанию: process.stdout.
    • terminal <логическое значение> Если true, указывает, что output должно обрабатываться как терминал TTY, и к нему должны записываться коды ANSI/VT100. По умолчанию: проверка значения свойства isTTY в потоке output при инициализации.
    • eval <Функция> Функция, используемая для обработки каждой строки ввода. По умолчанию: асинхронная оболочка для JavaScript функции eval(). Функция eval может возвращать ошибку с repl.Recoverable, чтобы указать, что ввод был неполным, и запросить дополнительные строки.
    • useColors <логическое значение> Если true, указывает, что функция по умолчанию для writer должна включать стили ANSI-цветов в вывод REPL. Если предоставлена пользовательская функция writer, это не повлияет. По умолчанию: значение terminal экземпляра REPL.
    • useGlobal <логическое значение> Если true, указывает, что функция оценки по умолчанию будет использовать JavaScript global в качестве контекста, а не создавать новый отдельный контекст для экземпляра REPL. Командная строка Node CLI устанавливает это значение в true. По умолчанию: false.
    • ignoreUndefined <логическое значение> Если true, указывает, что функция вывода по умолчанию не будет выводить результат команды, если он равен undefined. По умолчанию: false.
    • writer <Функция> Функция для форматирования вывода каждой команды перед записью в output. По умолчанию: util.inspect().
    • completer <Функция> Необязательная функция для пользовательской автодополнения Tab. См. readline.InterfaceCompleter для примера.
    • replMode <символ> Флаг, определяющий, выполняет ли функция оценки по умолчанию все команды JavaScript в строгом режиме или по умолчанию (нестрогом) режиме. Допустимые значения:
      • repl.REPL_MODE_SLOPPY - оценивает выражения в нестрогом режиме.
      • repl.REPL_MODE_STRICT - оценивает выражения в строгом режиме. Это эквивалентно добавлению префикса 'use strict' к каждой строке REPL.
      • repl.REPL_MODE_MAGIC - Это значение устарело, так как улучшенное соответствие спецификации в V8 сделало магический режим ненужным. Теперь он эквивалентен repl.REPL_MODE_SLOPPY (описано выше).
    • breakEvalOnSigint - Прекращение оценки текущего кода при получении SIGINT, т.е. нажатии Ctrl+C. Нельзя использовать вместе с пользовательской функцией eval. По умолчанию: false.

Метод repl.start() создаёт и запускает экземпляр repl.REPLServer.

Если options является строкой, то она задаёт приглашение для ввода:

const repl = require('repl');

// a Unix style prompt
repl.start('$ ');

Интерактивная оболочка Node.js

Сам Node.js использует модуль repl для предоставления собственного интерактивного интерфейса для выполнения JavaScript. Это можно сделать, выполнив бинарник Node.js без аргументов (или с аргументом -i):

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

Параметры переменных окружения

Различные действия интерактивной оболочки Node.js можно настроить с помощью следующих переменных окружения:

  • NODE_REPL_HISTORY - Если задан допустимый путь, постоянная история REPL будет сохранена в указанном файле вместо .node_repl_history в домашней папке пользователя. Установка этого значения в '' отключит сохранение истории REPL. Пробелы будут удалены из значения.
  • NODE_REPL_HISTORY_SIZE - Управляет количеством строк истории, которые будут сохранены, если история доступна. Должно быть положительным числом. По умолчанию: 1000.
  • NODE_REPL_MODE - Может быть любым из sloppy, strict, или magic. magic устарело и считается псевдонимом sloppy. По умолчанию: sloppy, что позволит запускать код без строгого режима.

Сохранение истории

По умолчанию, интерактивная оболочка Node.js будет сохранять историю между сессиями REPL, сохраняя ввод в файл .node_repl_history в домашней папке пользователя. Это можно отключить, задав переменную окружения NODE_REPL_HISTORY="".

NODE_REPL_HISTORY_FILE

Добавлен в: v2.0.0Устарел с: v3.0.0
Уровень стабильности: 0 - Устарел: Используйте NODE_REPL_HISTORY вместо него.

Ранее в Node.js/io.js v2.x история REPL контролировалась с помощью переменной окружения NODE_REPL_HISTORY_FILE, и история сохранялась в формате JSON. Эта переменная теперь устарела, и старый файл истории REPL в формате JSON будет автоматически преобразован в упрощённый текстовый формат. Этот новый файл будет сохранён либо в домашней папке пользователя, либо в каталоге, определённом переменной NODE_REPL_HISTORY, как описано в разделе Параметры переменных окружения.

Использование интерактивной оболочки Node.js с расширенными редакторами строк

Для расширенных редакторов строк запустите Node.js с переменной окружения NODE_NO_READLINE=1. Это запустит основную и отладочную интерактивные оболочки в канонических терминальных настройках, что позволит использовать их с rlwrap.

Например, следующее можно добавить в файл .bashrc:

alias node="env NODE_NO_READLINE=1 rlwrap node"

Запуск нескольких экземпляров REPL для одного запущенного экземпляра

Возможен запуск и выполнение нескольких экземпляров REPL для одного работающего экземпляра Node.js, которые используют один и тот же объект global, но имеют отдельные интерфейсы ввода-вывода.

Например, следующий пример предоставляет отдельные REPL на stdin, сокете Unix и сокете TCP:

const net = require('net');
const repl = require('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);

Запуск этого приложения из командной строки запустит интерактивную оболочку на стандартном вводе. Другие клиенты REPL могут подключиться через сокет Unix или сокет TCP. telnet, например, полезен для подключения к сокетам TCP, а socat можно использовать для подключения к сокетам Unix и TCP.

Запустив интерактивную оболочку с сервера на основе сокета Unix вместо стандартного ввода, можно подключиться к долгоживущему процессу Node.js без его перезапуска.

Для примера запуска "полноценной" (terminal) интерактивной оболочки через net.Server и net.Socket экземпляр, см.: https://gist.github.com/2209310

Для примера запуска экземпляра интерактивной оболочки через curl(1), см.: https://gist.github.com/2053342

© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v8.x/docs/api/repl.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API