Pull to refresh

REPL — настройка для сохранения истории и загрузка модулей по умолчанию

Reading time2 min
Views6.6K
Заметка рассчитана на новичков и пользователей среднего уровня, по этому всех гуру сразу прошу не тратить свое драгоценное время и пропустить данный пост.

В этой небольшой заметке я описываю как настроить REPL(read-eval-print loop) или «консоль» Node JS и при этом не потерять приятную плюшку — сохранение истории. Последние версии Node автоматически сохраняют историю между сеансами в REPL в файле ~/.node_repl_history Но есть одна загвоздка, если вы хотите настроить REPL «под себя», тогда история сеансов автоматически сохраняться прекращает.

Раньше для сохранения истории использовался отдельный пакет rlwrap(ReadLine Wrap).
Который позволяет например разукрашивать promt консоли, но при использовании rlwrap перестает работать автозавершение(autocomple) команд по клавише Tab. По этому его использовать не буду.

Кроме того в контекст REPL сразу загрузим часто используемые модули, такие как axios и lodash.

Иногда для модулей lodash или underscore используют символ подчёркивание _
В REPL этого делать не следует, так как этот символ имеет специальное значение — результат предыдущей операции.

По умолчанию если ввести

let a=1;

или любой другой код в результате которого ничего не возвращается или правильнее сказать возвращатся undefined, в консоли выведется это самое undefined, что как по мне раздражает.
За это поведение отвечает параметр
ignoreUndefined: true

Другой параметр: replMode: Repl.REPL_MODE_STRICT,.Это эквивалент 'use strict';. То есть теперь, например, не получится присвоить переменной значение без ее объявления.

Иначе говоря

b=2;

выдаст ошибку и нужно писать

let b=2;

Все параметры REPL описаны на сайте Node

Остальной код интуитивной понятен.


'use strict';
const Repl  = require('repl'),
      fs    = require('fs'),
      os    = require('os'),
      path  = require('path'),
      lo    = require('lodash'),
      axios = require('axios'),
      sa    = require('superagent');

const historyFile = path.resolve(os.homedir(), ".node_repl_history");

const repl = Repl.start({
  prompt: 'node> ',
  useColors: true,
  replMode: Repl.REPL_MODE_STRICT,
  ignoreUndefined: true
});

try {
  if (fs.existsSync(historyFile)) {
    fs.readFileSync(historyFile, 'utf-8')
      .split('\n')
      .reverse()
      .filter(line => line.trim())
      .map(line => repl.history.push(line));
  }
}
catch (err) {
  console.error(err);
}

repl.context.axios = axios;
repl.context.fs    = fs;
repl.context.lo    = lo;
repl.context.os    = os;
repl.context.path  = path;
repl.context.sa    = sa;

repl.on('line', newLine =>{
  const line = newLine.trim();
  if (line) { fs.appendFileSync(historyFile, line + '\n'); }
});


OUTDATED
В предыдущем варианте сохранение происходило только при выходе из REPL.

repl.on('exit', ()=>{
  fs.appendFileSync(historyFile, repl.lines.join('\n'));
});



Сохраняем этот код например в tools/repl.js

Для запуска node tools/repl.js

Можно прописать alias в .bashrc, но мне больше нравиться скрипт в package.json

  "scripts": {
    "repl": "node tools/repl "
  }

И запускать yarn repl
Tags:
Hubs:
+9
Comments3

Articles