Spec-Zone.ru › Node.js 18 LTS

REPL

Устойчивость: 2 - Стабильно

Исходный код: lib/repl.js

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

const repl = require('node:repl'); copy

Конструкция и особенности

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

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

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

Все экземпляры 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!'
> copy

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

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

Связанные с поиском по обратной истории клавиши см. reverse-i-search. Все остальные сочетания клавиш см. в сочетаниях клавиш TTY.

Функция вычисления по умолчанию

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

JavaScript-выражения

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

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

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

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

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

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

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

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

$ node repl_test.js
> m
'message' copy

Свойства контекста по умолчанию не являются только для чтения. Чтобы указать только для чтения глобальные переменные, свойства контекста должны быть определены с использованием Object.defineProperty():

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

const r = repl.start('> ');
Object.defineProperty(r.context, 'm', {
  configurable: false,
  enumerable: true,
  value: msg,
}); copy
Доступ к основным модулям Node.js

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

> fs.createReadStream('./some/file'); copy
Глобальные необработанные исключения
История
Версия Изменения
v12.3.0

Событие 'uncaughtException' теперь срабатывает, если repl используется как автономная программа.

REPL использует модуль domain для перехвата всех необработанных исключений для этого сеанса REPL.

Это использование модуля domain в REPL имеет следующие побочные эффекты:

  • Необработанные исключения испускают только событие 'uncaughtException' в автономном REPL. Добавление обработчика этого события в REPL внутри другой программы Node.js приводит к ERR_INVALID_REPL_INPUT.

    const r = repl.start();
    
    r.write('process.on("uncaughtException", () => console.log("Foobar"));\n');
    // Output stream includes:
    //   TypeError [ERR_INVALID_REPL_INPUT]: Listeners for `uncaughtException`
    //   cannot be used in the REPL
    
    r.close(); copy
  • Попытка использовать process.setUncaughtExceptionCaptureCallback() вызывает ошибку ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE.

Присвоение переменной _ (underscore)
История
Версия Изменения
v9.8.0

Добавлена поддержка _error.

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

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

Аналогично, _error будет ссылаться на последнюю ошибку, если таковая имелась. Явное присвоение значению _error отключит это поведение.

> throw new Error('foo');
Uncaught Error: foo
> _error.message
'foo' copy
await ключевое слово

Поддержка ключевого слова await включена на верхнем уровне.

> 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 copy

Известное ограничение использования ключевого слова await в REPL заключается в том, что оно делает недействительной лексическую область видимости ключевых слов const и let.

Например:

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

--no-experimental-repl-await отключит выполнение await на верхнем уровне в REPL.

Поиск по обратной истории

Добавлено в: v13.6.0, v12.17.0

REPL поддерживает двунаправленный поиск по обратной истории, подобный ZSH. Он запускается с помощью Ctrl+R для поиска назад и Ctrl+S для поиска вперёд.

Дублированные записи истории будут пропущены.

Записи принимаются, как только нажимается любая клавиша, не связанная с обратным поиском. Отмена возможна с помощью Esc или Ctrl+C.

Изменение направления немедленно производит поиск следующей записи в ожидаемом направлении от текущей позиции.

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

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

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

const repl = require('node: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 }); copy
Восстанавливаемые ошибки

В приглашении 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;
} copy

Настройка вывода REPL

По умолчанию экземпляры repl.REPLServer форматируют вывод с использованием метода util.inspect() перед записью вывода в предоставленный поток Writable (по умолчанию process.stdout). Опция проверки showProxy установлена в значение true по умолчанию, а опция colors установлена в значение true в зависимости от опции useColors REPL.

Логическое значение useColors может быть указано при создании для инструкции по умолчанию по умолчанию использовать коды стиля ANSI для раскрашивания вывода из метода util.inspect().

Если REPL запущен как автономная программа, то также можно изменить значения по умолчанию для проверки REPL изнутри REPL, используя свойство inspect.replDefaults, которое отражает свойство defaultOptions из util.inspect().

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

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

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();
} copy

Класс: REPLServer

Добавлен в: v0.1.91
  • options <Объект> | <строка> См. repl.start()
  • Расширяет: <readline.Интерфейс>

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

const repl = require('node:repl');

const options = { useColors: true };

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

Событие: '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();
}); copy

Событие: 'reset'

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

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

Это можно использовать в основном для повторной инициализации контекста REPL в некотором предварительно определенном состоянии:

const repl = require('node:repl');

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

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

r.on('reset', initializeContext); copy

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

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

replServer.defineCommand(keyword, cmd)

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

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

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

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

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();
}); copy

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

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

replServer.displayPrompt([preserveCursor])

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

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

При вводе многострочного ввода вместо «подсказки» печатается многоточие.

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

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

replServer.clearBufferedCommand()

Добавлен в: v9.0.0

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

replServer.parseREPLKeyword(keyword[, rest])

Добавлен в: v0.8.9Устаревший начиная с: v9.0.0
Уровень стабильности: 0 - Устаревший.
  • keyword <строка> потенциальное ключевое слово для разбора и выполнения
  • rest <любой> любые параметры для команды ключевого слова
  • Возвращает: <логическое значение>

Внутренний метод, используемый для разбора и выполнения ключевых слов REPLServer. Возвращает true, если keyword — это допустимое ключевое слово, в противном случае false.

replServer.setupHistory(historyPath, callback)

Добавлен в: v11.10.0
  • historyPath <строка> путь к файлу истории
  • callback <Функция> вызывается при готовности записи истории или при возникновении ошибки
    • err <Ошибка>
    • repl <repl.REPLСервер>

Инициализирует файл журнала истории для экземпляра REPL. При запуске бинарного файла Node.js и использовании REPL командной строки, файл истории инициализируется по умолчанию. Однако это не так при программировании REPL. Используйте этот метод для инициализации файла журнала истории при программировании с экземплярами REPL.

repl.builtinModules

Добавлен в: v14.5.0
  • <массив строк>

Список имён всех модулей Node.js, например, 'http'.

repl.start([options])

История
Версия Изменения
v13.4.0, v12.17.0

Опция preview теперь доступна.

v12.0.0

Опция terminal теперь следует по умолчанию во всех случаях и useColors проверяет hasColors() при наличии.

v10.0.0

Опция REPL_MAGIC_MODE replMode была удалена.

v6.3.0

Опция breakEvalOnSigint теперь поддерживается.

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. По умолчанию: проверка значения свойства isTTY в потоке output при создании.
    • eval <Функция> Функция для вычисления каждой строки ввода. По умолчанию: асинхронная обертка для JavaScript-функции eval() . Функция eval может возвращать ошибку repl.Recoverable для указания неполного ввода и запроса дополнительных строк.
    • useColors <логическое_значение> Если true, указывает, что функция по умолчанию writer должна включать форматирование ANSI-цветов для вывода REPL. Если предоставлена пользовательская функция writer, то это не имеет эффекта. По умолчанию: проверка поддержки цвета в потоке output если значение terminal экземпляра REPL равно true.
    • useGlobal <логическое_значение> Если true, указывает, что функция вычисления по умолчанию будет использовать JavaScript global в качестве контекста вместо создания нового отдельного контекста для экземпляра REPL. Node CLI REPL устанавливает это значение в 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.
    • breakEvalOnSigint <логическое_значение> Останавливает вычисление текущего блока кода при получении SIGINT, например, при нажатии Ctrl+C. Не может использоваться вместе с пользовательской функцией eval. По умолчанию: false.
    • preview <логическое_значение> Определяет, будет ли REPL выводить подсказки автодополнения и предварительные просмотры вывода или нет. По умолчанию: true для функции вычисления по умолчанию и false в случае использования пользовательской функции вычисления. Если terminal ложно, то предварительные просмотры отсутствуют, и значение preview не имеет эффекта.
  • Возвращает: <repl.REPLServer>

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

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

const repl = require('node:repl');

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

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

Сам Node.js использует модуль node: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 copy

Настройки переменных среды

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

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

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

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

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

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

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

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

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

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

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

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); copy

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

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

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

Для примера запуска экземпляра REPL по curl(1), см.: https://gist.github.com/TooTallNate/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-v18.x/docs/api/repl.html

Spec-Zone.ru

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