Мы каждый день используем интерфейсы командной строки, такие как git, ls, grep и т. д. Интерфейсы командной строки или CLI обычно являются самым быстрым способом решения проблемы, даже сегодня, несмотря на все графические интерфейсы.

Интерфейсы командной строки были созданы в 60-х годах, когда компьютеры (мэйнфреймы) взаимодействовали с пользователем посредством текстовых интерфейсов, и сегодня они продолжают оставаться очень важными, помимо развития GUI (графических пользовательских интерфейсов), главным образом потому, что CLI быстр, надежен и может быть сложены вместе для создания сценария.

Используя самый популярный и любимый язык, JavaScript, мы создадим интерфейс командной строки с нулевым пакетом и интерфейс командной строки с пакетом Commander.js, что позволит нам создавать более сложные, полезные и удобные интерфейсы командной строки. .

Скучно:

mkdir nodejs-cli ; cd nodejs-cli ; npm i -y ;

Часть 1

В этой первой части я покажу вам, как использовать только NodeJS для получения аргументов CLI и создания простого калькулятора. Хорошо, я знаю другой калькулятор, но подождите, давайте сосредоточимся на CLI, а не на калькуляторе этого.

Если вас интересует только Commander.js, перейдите к части 2.

touch procargvs.js

# nvim
nvim procargvs.js

# or vscode
code procargvs.js

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

Для нас важным аргументом будет третий элемент вперед.

Как получить аргументы?

// procargvs.js

const args =  process.argv
const myArgs = args.slice(2)

console.log(myArgs)

затем,

node procargvs.js hi --hello -bye

Ваш результат должен быть:

[ 'hi', '--hello', '-bye' ]

Теперь окончательный интерфейс командной строки будет работать следующим образом: мы вызовем node procargvs.js -sum <number> <number> <number...>.

Чтобы добраться до этой точки, нам нужно:

  • Получите аргументы, начинающиеся с -.
  • Проверьте тип: sum, sub, div, mul и fac.
  • Верните правильное значение для операции.

Первый момент: получите аргументы, начинающиеся с -.

// procargvs.js

const args =  process.argv
const myArgs = args.slice(2)
// Gets the options eg. word that starts with '-'
const options = myArgs.filter((a) => a.startsWith(`-`));
const values = myArgs.filter((a) => !a.startsWith('-'));

Опции — это такие, как -help, а значения — остальные аргументы, например, <number>.

Второй момент: проверьте тип: sum, sub, div, mul и fac.

// procargvs.js

let result = ''
options.map((o)=> {
  switch (o) {
    case '-sum':
      result += calculate('+', (p, v)=> Number(p)+Number(v))
      break;

    case '-mul':
      result += calculate('*', (p, v)=> Number(p)*Number(v))
      break;

    case '-div':
      result += calculate('/', (p, v)=> Number(p)/Number(v))
      break;

    case '-sub':
      result += calculate('-', (p, v)=> Number(p)-Number(v))
      break;

    case '-fac':
      result += calculateFactorial()
      break;

    default:
      break;
  }
})

calculate() и calculateFactorial() — это функции, используемые для вычисления результата, они будут представлены позже. Смотрите, как идти дальше.

Объяснение: мы сопоставляем параметры и проверяем с помощью переключателя тип операции, вы также можете использовать оператор if.

Результат:

> node procargvs.js -sum 10 10

|  10 + 10 = 20 

Часть 2

В этой заключительной части мы будем использовать пакет Commander.js для обработки всех аргументов. И используйте свойство bin на package.json, чтобы создать работоспособный CLI на вашем компьютере. Интерфейс командной строки с командиром будет немного другой, мы будем называть его node commander.js calculate -sum <number> <number> <number...>.

mkdir bin/ ; cd bin ; touch commander.js ; npm install commander ;

# then

nvim commander.js

# or 

code commander.js

Давайте импортируем и инициализируем командира:

// commander.js

import { Command } from 'commander'
const program = new Command()

program.name('node-js-cli-with-commander').description('CLI to run calculations.').version('0.0.1')

Чтобы указать аргументы, мы можем использовать program.command.option:

// commander.js

program
  .command('calculate')
  .description('Run a given calculation')
  .argument('<number...>', 'numbers to calculate')
  .option('--sum', 'sum', '')
  .option('--mul', 'multiply', '')
  .option('--div', 'divide', '')
  .option('--sub', 'subtract', '')
  .option('--fac', 'factorial', '')
  .action((numbers, options) => {
    if (options.sum) {
      console.log(calculate('+', (p, v) => Number(p) + Number(v), numbers))
    }
    if (options.mul) {
      console.log(calculate('*', (p, v) => Number(p) * Number(v), numbers))
    }
    if (options.div) {
      console.log(calculate('/', (p, v) => Number(p) / Number(v), numbers))
    }
    if (options.sub) {
      console.log(calculate('-', (p, v) => Number(p) - Number(v), numbers))
    }
    if (options.fac) {
      console.log(calculateFactorial(numbers))
    }
  })

program.parse()

Как видите, пакет Commander позволяет нам легко улучшить наш CLI с описанием программы и для каждой команды. Он также предварительно включает команду -h или --help.

calculate() и calculateFactorial() — это функции, используемые для вычисления результата, они будут представлены позже. Смотрите, как идти дальше.

> node bin/commander.js --help

Usage: node-js-cli-with-commander [options] [command]

CLI to run calculations.

Options:
  -V, --version                    output the version number
  -h, --help                       display help for command

Commands:
  calculate [options] <number...>  Run a given calculation
  help [command]                   display help for command

> node bin/commander.js --version

0.0.1

Объяснение:

  • .arguments будет определять значения после параметра, в данном случае числа для расчета.
  • .options определит каждый возможный вариант команды. option(flags: string, description?: string, defaultValue?: string | boolean | string[])

Давайте попробуем использовать программу сейчас, чтобы увидеть, как она работает:

> node bin/commander.js -V
0.0.1

> node bin/commander.js calculate 
error: missing required argument 'number'

> node bin/commander.js calculate -h
Usage: node-js-cli-with-commander calculate [options] <number...>

Run a given calculation

Arguments:
  number      numbers to calculate

Options:
  --sum       sum
  --mul       multiply
  --div       divide
  --sub       subtract
  --fac       factorial
  -h, --help  display help for command

> node bin/commander.js calculate -sum 10 10
10 + 10 = 20

Теперь, когда CLI работает, давайте завершим все и сделаем его доступным для PATH.

Для этого мы собираемся использовать команду npm link, чтобы связать локальную папку с глобальной папкой пакета. Благодаря этому мы сможем протестировать и запустить клиентский интерфейс без сборки и развертывания.

Нам нужно определить свойство bin в файле package.json. После этого мы можем начать процесс связывания.

...
"bin": {
  "mwc": "./bin/commander.js calculate",
  "mwp": "./bin/procargvs.js calculate"
},
...

Первая команда для запуска:

chmod u+x bin/*

Предполагается, что все исполняемые файлы находятся в папке bin.

После этого вы можете запустить:

npm link

Проверьте команду mwc(Math With Commander):

> mwc

Usage: commander-js-calculator [options] [command]

CLI to run calculations.

Options:
  -V, --version                    output the version number
  -h, --help                       display help for command

Commands:
  calculate [options] <number...>  Run a given calculation
  help [command]                   display help for command

а затем проверьте команду mwp(Math With Procargvs):

> mwp -fac 5                                                             ✔  
------------------------------
!5 = 120
------------------------------

Как видите, на этом этапе вы можете создать простой и эффективный интерфейс командной строки с помощью NodeJ.

Я надеюсь, что я сделал вас более продуктивными и способными совершенствоваться и продвигаться по карьерной лестнице.

Большое вам спасибо, и я с нетерпением жду встречи с вами в ближайшее время. 😉

А если вам нравится контент о Git, Linux, советы по продуктивности, Typescript и Python, подписывайтесь на меня Марко Антонио Бет.

Посетите мой личный сайт: itsbetma.com

Идти дальше

Узнать больше:

  • Командир
  • Ссылка на НПМ

itsbetma/nodejs-cli-with-commander (github.com)

Файл Procargvs

// procargvs.js

const args = process.argv
const myArgs = args.slice(2)
// Gets the options eg. word that starts with '-'
const options = myArgs.filter((a) => a.startsWith(`-`))
const values = myArgs.filter((a) => !a.startsWith('-'))

let result = ''

const renderValues = (operator, total) => {
  return `\n|  ${values.join(` ${operator} `)} = ${total}`
}

const calculate = (operator, func) => {
  if (values && values.length > 0) {
    const t = values.reduce(func)
    return renderValues(operator, t)
  }
  return ''
}

const calculateFactorial = () => {
  if (values && values.length > 0) {
    let base = Number(values[0])
    let t = base
    for (let i = base - 1; i < base && i >= 1; i--) {
      t *= i
    }
    return `\n!${base} = ${t}`
  }
  return ''
}

options.map((o) => {
  switch (o) {
    case '-sum':
      result += calculate('+', (p, v) => Number(p) + Number(v))
      break

    case '-mul':
      result += calculate('*', (p, v) => Number(p) * Number(v))
      break

    case '-div':
      result += calculate('/', (p, v) => Number(p) / Number(v))
      break

    case '-sub':
      result += calculate('-', (p, v) => Number(p) - Number(v))
      break

    case '-fac':
      result += calculateFactorial()
      break

    default:
      break
  }
})

console.log('------------------------------', result, '\n------------------------------')

Командирский файл

// commander.js

import { Command } from 'commander'
const program = new Command()

const renderValues = (operator, total, values) => {
  return `\n${values.join(` ${operator} `)} = ${total}`
}

const calculate = (operator, func, values) => {
  if (values && values.length > 0) {
    const t = values.reduce(func)
    return renderValues(operator, t, values)
  }
  return ''
}

const calculateFactorial = (values) => {
  if (values && values.length > 0) {
    let base = Number(values[0])
    let t = base
    for (let i = base - 1; i < base && i >= 1; i--) {
      t *= i
    }
    return `\n!${base} = ${t}`
  }
  return ''
}

program.name('node-js-cli-with-commander').description('CLI to run calculations.').version('0.0.1')

program
  .command('calculate')
  .description('Run a given calculation')
  .argument('<number...>', 'numbers to calculate')
  .option('--sum', 'sum', '')
  .option('--mul', 'multiply', '')
  .option('--div', 'divide', '')
  .option('--sub', 'subtract', '')
  .option('--fac', 'factorial', '')
  .action((numbers, options) => {
    if (options.sum) {
      console.log(calculate('+', (p, v) => Number(p) + Number(v), numbers))
    }
    if (options.mul) {
      console.log(calculate('*', (p, v) => Number(p) * Number(v), numbers))
    }
    if (options.div) {
      console.log(calculate('/', (p, v) => Number(p) / Number(v), numbers))
    }
    if (options.sub) {
      console.log(calculate('-', (p, v) => Number(p) - Number(v), numbers))
    }
    if (options.fac) {
      console.log(calculateFactorial(numbers))
    }
  })

program.parse()