Обработка аргументов в сценариях Node.js

Аргументы командной строки позволяют предоставить дополнительный ввод для запускаемых команд. Кроме того, они добавляют сценариям Node.js гибкости и позволяют выполнять их пользовательскую настройку.

В этом руководстве вы узнаете о векторах аргументов, обнаружении флагов, обработке нескольких аргументов и значений и функциях пакета commander.

Требования

Чтобы выполнить это руководство, вам понадобится локальная установка Node.js. Инструкции по установке зависят от дистрибутива, выберите свой: Mac OSUbuntuCentOSDebian.

Это руководство было проверено на версиях Node v16.10.0, npm v7.12.2 и commander v7.2.0.

Векторы аргументов

Node.js поддерживает список переданных аргументов, такой список называется вектором аргументов.

Другими словами, вектор аргументов – это массив, доступный в process.argv в вашем скрипте Node.js. Этот массив содержит все, что передается скрипту, включая исполняемый файл Node.js, а также путь и имя файла скрипта.

Если бы мы выполнили следующую команду:

node example.js -a -b -c

Мы увидели бы, что наш вектор аргументов содержит пять элементов:

[
  '/usr/bin/node',
  '/path/to/example.js',
  '-a',
  '-b',
  '-c'
]

Если сценарий запускается без каких-либо аргументов, в его массиве будет два элемента: исполняемый файл node и файл сценария, который выполняется.

Обычно вектор аргументов сочетается со счетчиком аргументов (argc), который сообщает, сколько аргументов было передано. В Node.js эта конкретная переменная отсутствует, но мы всегда можем получить длину массива векторов аргументов через length. Например:

if (process.argv.length === 2) {
  console.error('Expected at least one argument!');
  process.exit(1);
}

Этот код проверяет длину argv (значение length). Значение 2 означает, что в массиве присутствуют только исполняемый файл node и файл сценария. Если аргументов нет, код выведет сообщение: Expected at least one argument! и завершит работу.

Флаги аргументов

Давайте рассмотрим пример, отображающий сообщение по умолчанию, если флагов нет. Однако, если присутствует конкретный флаг, код будет отображать другое сообщение.

if (process.argv[2] && process.argv[2] === '-f') {
  console.log('Flag is present.');
} else {
  console.log('Flag is not present.');
}

Этот скрипт проверяет, есть ли в нашем векторе аргументов третий элемент. Индекс равен 2, потому что индексация массивов в JavaScript начинается с нуля. Если третий элемент присутствует и равен -f, код выведет другой результат.

Например, вот так мы запускаем скрипт без аргументов:

node example.js

И вот так выглядит сгенерированный вывод:

Flag is not present.

А если мы запустим скрипт с аргументами:

node example.js -f

Результат будет таким:

Flag is present.

Нам не нужно ограничиваться условными выражениями, можно также использовать фактическое значение, переданное в скрипт:

const custom = (process.argv[2] || 'Default');
console.log('Custom: ', custom);

Вместо условного выражения, основанного на аргументе, этот сценарий принимает передаваемое значение (по умолчанию это “Default”, если аргумент отсутствует) и вставляет его в выходные данные сценария.

Использование нескольких аргументов со значениями

Итак, мы написали сценарий, который принимает аргумент, и сценарий, который принимает сырое значение. А как насчет сценариев, в которых можно было бы использовать значение вместе с аргументом?

Немного усложним задачу и примем несколько аргументов:

// проверяет наличие флага -f
const flag = (
  process.argv.indexOf('-f') > -1 ? 'Flag is present.' : 'Flag is not present.'
);

// проверяет, есть ли в команде флаг --custom и имеет ли он какое-то значение
const customIndex = process.argv.indexOf('--custom');
let customValue;

if (customIndex > -1) {
  // извлекает значение после --custom
  customValue = process.argv[customIndex + 1];
}

const custom = (customValue || 'Default');

console.log('Flag:', `${flag}`);
console.log('Custom:', `${custom}`);

Если вместо того, чтобы полагаться на определенные значения индекса, использовать indexOf, мы сможем искать аргументы в любом месте вектора, независимо от порядка!

Запустим скрипт без аргументов:

node example.js

И мы получим такой вывод:

Flag: Flag is not present.
Custom: Default

Если запустить скрипт с аргументами:

node example.js -f --custom Override

вывод будет таким:

Flag: Flag is present.
Custom: Override

Теперь сценарий командной строки может принимать несколько аргументов и значений.

Библиотека commander

Вышеупомянутые примеры работают, когда мы используем конкретные аргументы. Однако пользователи могут использовать аргументы со знаками равенства и без них (-nJaneDoe или –name=JohnDoe), строки в кавычках для передачи значений с пробелами (-n “Jane Doe”) и даже сокращения и псевдонимы аргументов. Все варианты сложно предсказать

В таком случае нам поможет библиотека commander – это популярная библиотека Node.js, вдохновленная одноименной библиотекой Ruby.

Сначала в каталоге вашего проекта инициализируйте новый проект:

npm init

Затем установите библиотеку:

npm install commander@7.2.0

Давайте возьмем наш предыдущий пример и перепишем его для использования commander:

const commander = require('commander');

commander
  .version('1.0.0', '-v, --version')
  .usage('[OPTIONS]...')
  .option('-f, --flag', 'Detects if the flag is present.')
  .option('-c, --custom <value>', 'Overwriting value.', 'Default')
  .parse(process.argv);

const options = commander.opts();

const flag = (options.flag ? 'Flag is present.' : 'Flag is not present.');

console.log('Flag:', `${flag}`);
console.log('Custom:', `${options.custom}`);

commander выполняет всю тяжелую работу: обрабатывает process.argv, добавляет аргументы и любые связанные значения как свойства объекта commander.

Мы можем изменить версию скрипта и сообщить номер версии с помощью -v или –version. Кроме того, вы можете получить удобную справку, которая объясняет работу сценария. Для этого нужно передать аргумент –help. Если же вы случайно передадите аргумент, который не определен или не имеет переданного значения, скрипт выдаст ошибку.

Заключение

В этой статье вы узнали, что такое векторы аргументов, как определять флаги аргументов и обрабатывать несколько аргументов и значений. Также мы кратко рассмотрели использование библиотеки commander.

Читайте также: Создание интерактивных запросов командной строки

Tags:

Добавить комментарий