Spec-Zone.ru › Node.js 6 LTS

REPL

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

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

const repl = require('repl');

Конструкции и возможности

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

Экземпляры 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
> var m = 2
undefined
> m + 1
3

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

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

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

Явное присвоение значению _ отключит это поведение.

Настраиваемые функции вычисления

При создании нового repl.REPLServer, можно указать пользовательскую функцию вычисления. Это позволяет, например, реализовать полностью настраиваемые приложения REPL.

Ниже приведен гипотетический пример REPL, который выполняет перевод текста с одного языка на другой:

const repl = require('repl');
const Translator = require('translator').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 eval(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: function(name) {
    this.lineParser.reset();
    this.bufferedCommand = '';
    console.log(`Hello, ${name}!`);
    this.displayPrompt();
  }
});
replServer.defineCommand('saybye', function() {
  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 для принятия нового ввода.

При вводе многострочного ввода, вместо приглашения печатается многоточие.

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

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

repl.start([options])

Добавлен в: v0.1.91
  • options <Объект> | <строка>
    • prompt <строка> Приглашение для ввода, отображаемое по умолчанию. По умолчанию >.
    • 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(). Функция может возвращать ошибку repl.Recoverable, чтобы указать, что ввод был неполным, и запросить дополнительные строки.
    • useColors <булево> Если true, указывает, что в функцию вывода по умолчанию должно добавляться ANSI-стилизация цвета вывода REPL. Если предоставлена пользовательская функция writer, это не влияет. По умолчанию устанавливается значение terminal экземпляра REPL.
    • useGlobal <булево> Если true, указывает, что функция оценки по умолчанию будет использовать JavaScript global как контекст вместо создания нового отдельного контекста для экземпляра REPL. По умолчанию false.
    • ignoreUndefined <булево> Если true, указывает, что функция вывода по умолчанию не будет выводить результат команды, если он равен undefined. По умолчанию false.
    • writer <Функция> Функция форматирования вывода каждой команды перед записью в output. По умолчанию util.inspect().
    • completer <Функция> Необязательная функция для пользовательской автозамены Tab. См. readline.InterfaceCompleter для примера.
    • replMode - Флаг, определяющий, выполняет ли функция оценки по умолчанию все JavaScript-команды в строгом режиме, обычном режиме или гибридном режиме ("магический" режим). Допустимые значения:
      • repl.REPL_MODE_SLOPPY - выполняет выражения в нестрогом режиме.
      • repl.REPL_MODE_STRICT - выполняет выражения в строгом режиме. Эквивалентно предложению каждой команды repl с 'use strict'.
      • repl.REPL_MODE_MAGIC - пытается выполнить выражения в обычном режиме. Если выражения не могут быть обработаны, повторная попытка в строгом режиме.
    • 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
> a = [1, 2, 3];
[ 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, что автоматически выполнит команды в строгом режиме, если они имеют соответствующий синтаксис.

Постоянная история

По умолчанию, интерпретатор команд 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. Это запустит основной и отладчик REPL в стандартных терминальных настройках, что позволит использовать их с 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 на стандартном вводе. Другие клиенты REPL могут подключиться через сокет Unix или сокет TCP. telnet, например, полезно для подключения к сокетам TCP, в то время как socat можно использовать для подключения к сокетам Unix и TCP.

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

Для примера работы «полнофункционального» (terminal) REPL через net.Server и net.Socket экземпляр, см.: https://gist.github.com/2209310

Для примера работы экземпляра REPL через 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-v6.x/docs/api/repl.html

Spec-Zone.ru

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