Spec-Zone.ru › Node.js 16 LTS

ПОЛИ

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

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

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

const repl = require('repl');

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

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

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

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

Все экземпляры ПОЛИ поддерживают следующие специальные команды:

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

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

  • 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

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

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

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

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

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

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

$ 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 в среду ПОЛИ при использовании. Например, если не объявлено иначе как глобальная или локальная переменная, ввод fs будет оцениваться по требованию как global.fs = require('fs').

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

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

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

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

  • Необработанные исключения генерируют только событие 'uncaughtException' в самостоятельном ПОЛИ. Добавление обработчика для этого события в ПОЛИ внутри другой программы 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();
  • Попытка использования process.setUncaughtExceptionCaptureCallback() вызывает ошибку ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE.

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

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

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

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

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

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

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

> 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

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

Например:

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

--no-experimental-repl-await отключит поддержку ожидания на верхнем уровне в ПОЛИ.

Поиск по истории в обратном порядке

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

ПОЛИ поддерживает двунаправленный поиск по истории, аналогичный ZSH. Он вызывается нажатием Ctrl+R для поиска назад и Ctrl+S для поиска вперед.

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

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

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

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

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

Ниже приведен гипотетический пример ПОЛИ, выполняющего перевод текста с одного языка на другой:

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 });
Восстанавливаемые ошибки

В приглашении ПОЛИ нажатие 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.REPLServer форматируют вывод, используя метод util.inspect(), прежде чем записать вывод в предоставленный поток Writable (по умолчанию process.stdout). Опция инспекции showProxy установлена в значение true по умолчанию, а опция colors установлена в значение true в зависимости от опции useColors ПОЛИ.

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

Если ПОЛИ запускается как самостоятельная программа, можно изменить настройки инспекции ПОЛИ изнутри ПОЛИ, используя свойство inspect.replDefaults, которое отражает свойство defaultOptions из util.inspect().

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

Для полной настройки вывода экземпляра 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
  • options <Объект> | <строка> См. repl.start()
  • Расширяет: <readline.Interface>

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

const repl = require('repl');

const options = { useColors: true };

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

Событие: '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 является либо Function, либо Object, имеющим следующие свойства:

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

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

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

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

replServer.displayPrompt([preserveCursor])

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

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

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

Когда 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.REPLServer>

Инициализирует файл журнала истории для экземпляра 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 <строка> Подсказка для ввода. По умолчанию: '> ' (с заключительным пробелом).
    • 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. REPL командной строки Node устанавливает это значение в 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('repl');

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

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

Сам 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. Пробелы в значении будут удалены. В Windows переменные среды с пустым значением недействительны, поэтому установите это значение в один или несколько пробелов, чтобы отключить сохранение истории команд REPL.
  • NODE_REPL_HISTORY_SIZE: Управляет количеством сохраняемых строк истории, если история доступна. Должно быть положительным числом. По умолчанию: 1000.
  • NODE_REPL_MODE: Может быть либо 'sloppy', либо 'strict'. По умолчанию: 'sloppy', что позволит запускать код без строгого режима.

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

По умолчанию интерактивная оболочка Node.js сохранит историю между сессиями REPL, сохраняя вводимые команды в файле .node_repl_history в домашнем каталоге пользователя. Это можно отключить, установив переменную среды 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) на стандартном вводе. Другие клиенты 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-v16.x/docs/api/repl.html

Spec-Zone.ru

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