REPL и запуск скриптов

REPL (Read-Eval-Print Loop) — интерактивная консоль Node.js для быстрого выполнения JavaScript без создания файлов; запуск скриптов через node script.js позволяет выполнять файлы напрямую из командной строки.

Зачем нужно

REPL незаменим для быстрого эксперимента с API, проверки синтаксиса, тестирования регулярных выражений или вычислений. Запуск скриптов через node — основа для CLI-утилит, задач миграций, seed-скриптов базы данных и cron-задач.

Где используется

  • Отладка и эксперименты без создания файлов (REPL)
  • Seed-скрипты для наполнения базы данных
  • Однократные миграции данных
  • CLI-инструменты и автоматизация задач

Основной контент

REPL — интерактивная консоль

# Запустить REPL
node

> 2 + 2
4
> const arr = [1, 2, 3]
undefined
> arr.map(x => x * 2)
[ 2, 4, 6 ]
> .help       # список команд REPL
> .exit        # выйти (или Ctrl+D)
> .clear()       # очистить контекст
> .load() file.js   # загрузить файл в REPL
> .save session.js # сохранить сессию в файл
# Многострочный режим (начать с { или [)
> function greet(name) {
... return `Hello, ${name}!`;
... }
undefined
> greet('Node')
'Hello, Node!'

# Последний результат доступен через _
> 5 + 3
8
> _ * 2
16

Запуск скриптов

# Запустить файл
node script.js

# С аргументами
node script.js --env=production --port=3000

# Читать из stdin
echo "console.log('hello')" | node

# Выполнить строку (-e eval)
node -e "console.log(process.version)"

# Выполнить и открыть REPL (-i interactive)
node -e "const x = 42" -i

# Показать информацию о Node
node -p "process.versions"  # -p = print result

process.argv — аргументы командной строки

// script.js
// node script.js hello world --verbose

console.log(process.argv);
// [
//   '/usr/bin/node',   // argv[0] — путь к node
//   '/path/script.js', // argv[1] — путь к скрипту
//   'hello',           // argv[2]
//   'world',           // argv[3]
//   '--verbose'        // argv[4]
// ]

const args = process.argv.slice(2); // ['hello', 'world', '--verbose']

// Парсинг флагов
const verbose = args.includes('--verbose');
const port = args.find(a => a.startsWith('--port='))?.split('=')[1] || '3000';

stdin / stdout в скриптах

// Чтение из stdin построчно
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });

rl.on('line', (line) => {
  console.log(`> ${line.toUpperCase()}`);
});

rl.on('close', () => {
  console.log('Done');
  process.exit(0);
});

npm scripts — запуск через package.json

{
  "scripts": {
    "start": "node src/app.js",
    "dev": "nodemon src/app.js",
    "seed": "node scripts/seed.js",
    "migrate": "node scripts/migrate.js",
    "cli": "node src/cli.js"
  }
}
npm run seed
npm run migrate
npm start

Nodemon — автоперезапуск при изменениях

npm install --save-dev nodemon

# Перезапускать при изменении .js и .env файлов
nodemon --ext js,json,env src/app.js

Частые ошибки

  • Запустить app.js с listen в тестах — при импорте сервер запускается; выносить listen в server.js
  • Глобальные переменные в REPLvar x = 5 в REPL добавляет x в global; в модулях этого не происходит
  • Не обработать process.on('exit') — код в обработчике exit выполняется синхронно; асинхронные операции не выполнятся

Связанные темы

Ресурсы


🎓 Источник: Консоль и командная строка в JavaScript и Node.js

  • 📅 2018-10-25 · YouTube · [Marp](../../../Documents/TimurShemsedinov/2018-10-25 — Консоль и командная строка в JavaScript и Node.js (5aSZyKi5BmE).md)
  • Тезисы:
    • console — большой namespace: log, dir, table, time, group, trace, assert
    • console.log сериализует объект в JSON-подобную форму, скрытые поля не выводятся
    • console.dir(obj, {showHidden: true}) показывает символы и non-enumerable
    • console.time('x') + console.timeEnd('x') — замер интервалов
    • console.table([{a:1},{a:2}]) — табличный вывод объектов
    • console.trace печатает stack trace без остановки
    • readline.createInterface({input: process.stdin}) для пошагового чтения ввода
    • rl.question нарушает error-first — callback принимает только answer
    • Своя командная строка через event line + rl.prompt
    • process.argv — массив [node, scriptPath, ...args], ключи --port=3000 парсятся вручную
    • process.exit(code) — код возврата важен для CI (0 = успех, ≠0 = ошибка)
    • Escape-последовательности для позиции курсора: \x1b[H (home), \x1b[2J (clear)