Node REPL с библиотеками
В работе мне довольно часто приходится проверять какие-то небольшие сниппеты кода на различных входных данных. Такое возникает, например, когда я занимаюсь код ревью, и возникает желание убедиться в правильной обработке краевых условий. Либо же просто, когда я использую при разработке какую-то внешнюю библиотеку, и мне нужно быть уверенным, что использованный метод будет работать ожидаемо.
Для таких проверок и приходит на помощь CLI-среда REPL (read-eval-print-loop), которая по сути является неким инлайн-интерпретатором, в нём вы можете написать строку кода и тут же увидеть результат.
Node.js REPL
Чтобы запустить REPL Node.js, достаточно просто набрать в терминале:
node
В нём легко выполнять какие-то простые вещи и сразу видеть результат:
> [1, 2, 3].join(':')
'1:2:3'
REPL и библиотеки
Давайте представим, что мы попали в следующую ситуацию: нам понадобилось посмотреть, как именно ведёт себя функция библиотеки lodash keyBy. Мы наивно пробуем:
> _.keyBy([{ id: 1, name: 'Justin' }, { id: 2, name: 'Bob' }], 'id')
TypeError: Cannot read property 'keyBy' of undefined
Естественно, никакой магии нет, мы никак не обозначили, что собираемся использовать lodash в REPL, да и более того, lodash у нас не установлена глобально, и REPL просто не может её увидеть. Что ж, ставим:
yarn global add lodash
# или
npm i -g lodash
И пробуем запустить REPL, но в этот раз сделаем это несколько хитрее:
node -i -e "const _ = require('lodash')"
И видим Error: Cannot find module 'lodash'
. Давайте пока отложим эту неприятность и посмотрим, какими ключами мы воспользовались:
-e "const _ = require('lodash')"
выполняет указанный код, в данном случае импортирует модуль lodash в константу_
.-i
форсирует интерактивный режим, нам это необходимо, так как предыдущий ключ-e
подразумевает под собой только выполнение кода, без интерактивного режима.
С ключами разобрались, но почему же не видна библиотека, мы же поставили её глобально? Тут стоит проверить, а верно ли указана переменная окружения NODE_PATH
. В моём случае она не была установлена вообще, и пришлось её добавить в конфиги шелла (в моём случае это был fish), указав в ней путь до глобальных модулей:
set -x NODE_PATH ~/.config/fnm/lib/node_modules
Эта переменная может задаваться по-разному, если у вас, например, bash или zsh, и в зависимости от того, пользуетесь ли вы nvm или fnm. Если вдруг у вас возникнут трудности на этом этапе, не стесняйтесь задавать вопросы, будем разбираться вместе!
Итак, пробуем снова:
node -i -e "const _ = require('lodash')"
И, наконец, попадаем в REPL без ошибок, с надеждой снова пробуем функцию из lodash:
> _.keyBy([{ id: 1, name: 'Justin' }, { id: 2, name: 'Bob' }], 'id')
{ '1': { id: 1, name: 'Justin' }, '2': { id: 2, name: 'Bob' } }
И, всё заработало! Мы добились того, чтобы при запуске нашей песочницы нам подключалась библиотека и мы могли свободно ей пользоваться.
Также хотелось бы отметить, что это далеко не единственный и даже не самый простой способ использовать внешние библиотеки в REPL. Например, есть trymodule, который довольно просто позволяет открывать REPL с импортированными библиотеками. Но честно говоря, в моём случае я столкнулся с небольшими субъективным недостатками, поэтому пока остаюсь на нативном REPL.
Итак, подытожим, мы с вами научились из Node.js создавать свою песочницу для различных проб и экспериментов.