Avatar ·

Как передать аргументы командной строки в программу Node.js и получить их?

Привет! Я новичок в Node.js и пишу простую утилиту для работы с файлами. Хочу, чтобы пользователь мог передать имя файла и режим обработки (например, "read" или "write") прямо при запуске скрипта из терминала. Пробовал использовать глобальный объект `process`, но не совсем понимаю, как правильно извлечь эти аргументы. Вот мой код: ```javascript // app.js const name = process.argv; console.log(name); ``` Когда я запускаю `node app.js myfile.txt read`, в консоль выводится массив: `['node', 'app.js', 'myfile.txt', 'read']`. Я ожидал увидеть только `myfile.txt` и `read`. Как правильно получить именно пользовательские аргументы, а не путь к Node и имя скрипта? Также интересует, как обрабатывать опции вроде `--file` или `-f`, чтобы сделать интерфейс более дружелюбным. Подскажите, пожалуйста, лучший способ работы с аргументами командной строки в Node.js. Заранее спасибо! <<>>

Основной способ: использование массива process.argv

Вы уже на правильном пути! Глобальный объект process содержит массив argv, который включает все аргументы командной строки. Первые два элемента — это путь к исполняемому файлу Node.js и путь к вашему скрипту. Пользовательские аргументы начинаются с индекса 2.

// app.js
const args = process.argv.slice(2);
console.log(args); // ['myfile.txt', 'read']

const fileName = args[0];
const mode = args[1];
console.log(`Файл: ${fileName}, Режим: ${mode}`);

При запуске node app.js myfile.txt read вы получите ожидаемый результат. Метод slice(2) отбрасывает первые два элемента и возвращает новый массив с вашими аргументами.

Обработка именованных аргументов (флагов)

Для поддержки опций вроде --file или -f можно написать простой парсер самостоятельно или использовать готовые библиотеки. Вот пример ручного парсинга:

function parseArgs(args) {
    const options = {};
    const positional = [];

    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        if (arg.startsWith('--')) {
            // Длинный флаг: --file value
            const key = arg.slice(2);
            options[key] = args[i + 1] || true;
            i++; // пропускаем значение
        } else if (arg.startsWith('-')) {
            // Короткий флаг: -f value
            const key = arg.slice(1);
            options[key] = args[i + 1] || true;
            i++;
        } else {
            // Позиционный аргумент
            positional.push(arg);
        }
    }
    return { options, positional };
}

const { options, positional } = parseArgs(process.argv.slice(2));
console.log(options); // { file: 'myfile.txt', f: 'myfile.txt' }
console.log(positional); // ['read']

Использование готовых библиотек

Для серьёзных проектов рекомендую использовать проверенные решения:

  • yargs — мощная библиотека с автоматической генерацией справки, валидацией и поддержкой подкоманд.
  • commander — популярный инструмент для создания интерфейсов командной строки.
  • minimist — лёгкая библиотека для базового парсинга.

Пример с yargs:

const yargs = require('yargs');

const argv = yargs
    .option('file', {
        alias: 'f',
        description: 'Путь к файлу',
        type: 'string',
        demandOption: true
    })
    .option('mode', {
        alias: 'm',
        description: 'Режим обработки (read/write)',
        type: 'string',
        choices: ['read', 'write']
    })
    .help()
    .argv;

console.log(`Файл: ${argv.file}, Режим: ${argv.mode}`);

Установка: npm install yargs. Запуск: node app.js --file myfile.txt --mode read.

Советы

  • Всегда проверяйте наличие обязательных аргументов и выводите понятные сообщения об ошибках.
  • Используйте process.exit(1) при критических ошибках.
  • Для простых скриптов достаточно process.argv.slice(2), для сложных — берите библиотеку.
<<>>

Альтернативный подход: использование process.argv с деструктуризацией

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

// app.js
const [, , fileName, mode] = process.argv;

if (!fileName || !mode) {
    console.error('Использование: node app.js <fileName> <mode>');
    process.exit(1);
}

console.log(`Обработка файла "${fileName}" в режиме "${mode}"`);

Здесь мы пропускаем первые два элемента (путь к Node и скрипту) с помощью запятых и сразу получаем нужные значения. Этот подход хорошо подходит для скриптов с фиксированным набором позиционных аргументов.

Работа с переменными окружения

Ещё один способ передачи параметров — переменные окружения. Они удобны, когда данные чувствительны (пароли, ключи) или когда нужно задать значения по умолчанию:

const fileName = process.env.FILE_NAME || 'default.txt';
const mode = process.env.MODE || 'read';

console.log(`Файл: ${fileName}, Режим: ${mode}`);

Запуск: FILE_NAME=myfile.txt MODE=write node app.js. Этот метод особенно полезен в Docker-контейнерах или CI/CD системах.

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