Гид по технологиям

Создание CLI на Node.js с Commander.js

6 min read Разработка Обновлено 08 Jan 2026
Создание CLI на Node.js с Commander.js
Создание CLI на Node.js с Commander.js

Важно: показанный пример использует RapidAPI/Urban Dictionary для демонстрации запросов. Никогда не храните ключи API в открытом виде в репозитории — используйте переменные окружения.

Логотип Node.js на размытом фоне с окном редактора и терминалом

О чём этот материал

В статье объясняется, что такое CLI-приложения, почему они важны для разработчиков, как использовать Commander.js для создания стандартного интерфейса командной строки, как подключать Axios для HTTP-запросов и как подготовить пакет для установки и публикации в npm. В конце — чеклисты, подсказки и краткая матрица сравнения альтернатив.

Понимание CLI приложений

CLI (Command Line Interface) — текстовый интерфейс для взаимодействия с программой через терминал. Вы вводите команды; программа выполняет действия и возвращает текстовый результат.

Типичный CLI-командный ввод состоит из трёх частей:

  • имя программы (например, ls);
  • опции/флаги (например, -l);
  • аргументы (например, путь /home).

Пример:

ls -l /home

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

Что такое Commander.js

Commander.js — это npm-пакет для создания CLI на Node.js. Он упрощает работу с подкомандами, опциями, аргументами и генерацией текста помощи. Компания-разработчик уже реализовала много стандартных сценариев, поэтому вы фокусируетесь на логике команды.

С помощью дополнительных библиотек (например, Chalk для раскраски вывода) можно сделать интерфейс более удобным.

Пример: утилита urbanary-cli

Мы создадим CLI urbanary-cli, который ищет значения слов и аббревиатур в Urban Dictionary. Основные шаги:

  1. Инициализация проекта.
  2. Установка зависимостей (Commander, Axios).
  3. Создание точки входа в bin/index.js.
  4. Реализация команды find с опциями example и count.
  5. Тестирование локально и установка глобально.
  6. Публикация в npm.

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

mkdir urbanary-cli  
cd urbanary-cli  
npm init -y  

Для работы с Urban Dictionary в примере используется Axios и RapidAPI для проверки endpoint и учётных данных.

Страница Urban Dictionary API на RapidAPI с видимыми полями учётных данных

Установка зависимостей и начальная структура

Установите Commander и Axios:

npm install commander axios  

Создайте папку bin и файл index.js:

mkdir bin  
cd bin  
touch index.js  

Папка bin содержит исполняемый файл, который будет запускаться при вводе команды из терминала. Файл index.js станет точкой входа.

Минимальная регистрация команды

Импортируйте объект program из Commander:

const { program } = require('commander');  

Зарегистрируйте подкоманду find:

// index.js  
program  
    .command('find ')  
    .description('find meaning of a word or abbreviation or slang')  

Уголковые скобки означают обязательный аргумент. Для необязательного аргумента используйте квадратные скобки []. Описание пригодится для генерации раздела помощи.

Добавьте парсинг аргументов для отображения помощи:

program.parse()

При запуске с –help или -h Commander сгенерирует стандартный текст помощи.

Вывод команды помощи в терминале с перечислением команд и опций

Опции команды и окончательная структура

Опции добавляются методом option. Пример: опция для показа примеров и опция для количества определений:

program.option('-e, --example', "Display examples")  

program.option(  
    '-c, --count [amount]',  
    'amount of definitions to display (max is 10)'  
)  

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

Добавим действие (action), где реализуем логику команды:

program  
    .command('find ')  
    .description('find meaning of a word or abbreviation or slang')  
    .option('-e, --example', "Display examples")  
    .option(  
        '-c, --count [amount]',  
        'amount of definitions to display (max is 10)'  
    )  
    .action(async (word, options) => {});  

Пример запуска:

urbanary-cli find lol -e -c 3  

Или с длинными опциями:

urbanary-cli find lol --example --count 3  

Реализация запросов к API с Axios

Импортируйте Axios в index.js:

const axios = require('axios');  

В теле action создайте объект с опциями запроса:

let requestOptions = {  
    method: 'GET',  
    URL: "https://mashape-community-urban-dictionary.p.rapidapi.com/define",  
    params: { term: word },  
    headers: {  
        'X-RapidAPI-Key': YOUR_RAPID_API_KEY,  
        'X-RapidAPI-Host': 'mashape-community-urban-dictionary.p.rapidapi.com'  
    }  
}  

Затем выполните запрос и обработайте ответ:

try {  
    let resp = await axios.request(requestOptions);  
    console.log(`Definitions for ${word} fetched`);  
    wordData = resp.data.list;  
} catch (err) {  
    console.error(err.message)  
}  

В ответе нас интересует свойство list, где находятся определения и примеры.

Далее — логика отображения в зависимости от опций:

if (options.example && options.count) {  
    let cnt = 1;  
    let definitions = wordData.slice(0, options.count);  
  
    definitions.forEach((elem) => {  
        console.log(`Definition ${cnt++}: ${elem.definition}`);  
        console.log(`Example:\n${elem.example}\n`);  
    });  
} else if (options.count && !options.example) {  
    let cnt = 1;  
    let definitions = wordData.slice(0, options.count);  
  
    definitions.forEach((elem) => {  
        console.log(`Definition ${cnt++}: ${elem.definition}`);  
    });  
} else if (options.example) {  
    console.log(`Definition: ${wordData[0].definition}`);  
    console.log(`Example:\n${wordData[0].example}`);  
} else {  
    console.log(`Definition: ${wordData[0].definition}`);  
}  

Код последовательно проверяет комбинации опций и формирует вывод. Это базовый и понятный подход для большинства CLI-инструментов.

Сделать скрипт исполняемым и установить глобально

Добавьте шебанг в начало bin/index.js:

#!/usr/bin/env node

Откройте package.json, укажите main и bin:

"main": "./bin/index.js",  
"bin": {  
  "urbanary-cli": "./bin/index.js"  
},  

Ключ под bin — это команда, которую вводят в терминале. Затем выполните установку глобально:

npm install -g

После глобальной установки команду можно запускать из любой директории.

Терминал с процессом установки пакета и тестовым запуском команды find lmk

Публикация пакета выполняется командой npm publish в корне проекта, если у вас есть аккаунт npm и пакет готов к публикации.

Советы по улучшению качества CLI

  • Не храните ключи API в коде — используйте переменные окружения или секрет менеджеры.
  • Обрабатывайте ошибки сетевых запросов и выводите удобные сообщения для пользователя.
  • Добавьте тесты для критических частей (парсинг опций, обработка ошибок API).
  • Предоставьте примеры использования в README и поддержку –help.

Проверка и критерии приёмки

  • Команда urbanary-cli успешно устанавливается глобально и запускается в терминале.
  • Команда find возвращает определение для заданного слова.
  • Опции –example и –count работают согласно описанию.
  • В коде нет открытых ключей API, а ошибки обрабатываются и понятны пользователю.

Полезные сниппеты и cheat sheet

Краткие блоки кода, которые пригодятся при разработке CLI:

  • Базовая регистрация команды и опций:
const { program } = require('commander');

program
  .command('find ')
  .description('find meaning')
  .option('-e, --example', 'Display examples')
  .option('-c, --count [amount]', 'amount of definitions to display (max is 10)')
  .action(async (word, options) => {
    // реализация
  });

program.parse();
  • Использование переменных окружения для ключа API:
const API_KEY = process.env.RAPIDAPI_KEY;
headers: {
  'X-RapidAPI-Key': API_KEY,
  'X-RapidAPI-Host': 'mashape-community-urban-dictionary.p.rapidapi.com'
}
  • Пример package.json для CLI:
{
  "name": "urbanary-cli",
  "version": "1.0.0",
  "main": "./bin/index.js",
  "bin": {
    "urbanary-cli": "./bin/index.js"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "commander": "^9.0.0"
  }
}

Роли и чеклисты

Developer:

  • Создать минимальную рабочую версию команды.
  • Добавить опции и помочь (–help).
  • Настроить логирование ошибок.

Maintainer:

  • Проверять уязвимости зависимостей.
  • Обновлять зависимости и тестировать обратную совместимость.
  • Проводить код-ревью перед публикацией.

DevOps / Release engineer:

  • Настроить CI для линтинга и тестов.
  • Управлять релизами и тегами в git.
  • Публиковать в npm с безопасными секретами.

Мини‑методология разработки CLI (шаги)

  1. Набросать UX: команды, опции, примеры использования.
  2. Создать skeleton с Commander.js.
  3. Реализовать обработку аргументов и вызовы API.
  4. Добавить обработку ошибок и логирование.
  5. Написать unit-тесты на парсер опций и интеграционные тесты на «заглушённые» API.
  6. Добавить CI и проверки PR.
  7. Подготовить package.json и README.
  8. Публиковать релиз и отслеживать обратную связь.

Сравнение подходов для CLIs

ТехнологияПлюсыМинусы
Node.js + Commander.jsБыстро начать, богатая экосистема npm, простая публикация в npmМенее производителен при тяжёлых вычислениях, зависимость от среды Node.js
RustВысокая производительность, статическая компиляция, небольшие двоичные файлыДольше разработка, круче порог входа для новичков

Выбор зависит от требований: если нужна простая автоматизация и быстрый выпуск — Node.js подходит лучше. Если нужен быстрый и автономный исполняемый файл с минимальным зависимостями — Rust имеет смысл.

Когда этот подход не подходит

  • Нужны статически скомпилированные двоичные файлы без зависимости от интерпретатора — выбирайте языки с компиляцией в нативный код.
  • Требуются сверхнизкие задержки и малая память — Node.js может уступать системным языкам.

Security и приватность

  • Не храните ключи API в репозитории. Используйте process.env или секретные хранилища CI.
  • Ограничьте вывод отладочной информации в продакшне.
  • В README укажите, какие данные логируются и как пользователь может очистить локальные данные.

Тесты и критерии приёмки

Примеры тест-кейсов:

  1. Запуск urbanary-cli find слово без опций — выводится одно определение.
  2. Запуск с –count 3 — выводится ровно три определения.
  3. Запуск с –example выводит пример под определением.
  4. При ошибке сети — утилита возвращает понятное сообщение ошибки и ненулевой код выхода.

Критерии приёмки описаны ранее.

Глоссарий 1 строкой

CLI — инструмент для взаимодействия через командную строку. Commander.js — библиотека для определения команд и опций. Axios — HTTP-клиент для выполнения запросов.

Пример flowchart принятия решения (Mermaid)

flowchart TD
  A[Нужно ли CLI?] -->|Да| B{Требуется нативный exe без Node?}
  B -->|Да| C[Rust или Go]
  B -->|Нет| D[Node.js + Commander.js]
  A -->|Нет| E[Использовать GUI или API]

Заключение

Node.js и Commander.js облегчают создание пригодных CLI‑утилит: они позволяют быстро определить команды и опции, автоматически генерируют помощь и легко интегрируются с библиотеками для HTTP-запросов, такими как Axios. Следуйте рекомендациям по безопасности, тестированию и публикации, чтобы ваш инструмент был удобен, надёжен и обслуживаем.

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

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство