Научит вас, как использовать nodejs для написания cli (командная строка)

Node.js внешний интерфейс Командная строка NPM

При ежедневной разработке внешнего интерфейса вы будете сталкиваться с различными cli, такими как webpack, который помогает упаковывать с помощью одной команды, vue-cli, который помогает создавать шаблоны проектов vue с помощью одной команды, и create-react-app для создание реактивных проектов и т. д. Подождите. Эти инструменты значительно облегчают нашу повседневную работу, позволяют компьютеру выполнять рутинную работу самостоятельно, а мы можем сэкономить массу времени на обучение, общение, развитие,посетить пар.

Но иногда для некоторых особых нужд мы не можем найти подходящий инструмент cli для этого. Например, ваш проект очень большой, вы добавляете в проект новый маршрут, проходите创建目录 -> 创建.vue文件 -> 更新vue-router的路由列表В этом процессе, даже если вы знакомы с использованием горячих клавиш для создания файлов каталогов, он быстрее, чем ваша однострочная команда, особенно когда каталог маршрутизации глубоко вложен, а шаблон инициализации файла .vue сложен.

Итак, почему бы не написать cli для собственного проекта? Просто делать нудную работу?

0x1 hello world

Клиентская среда nodejs, по сути, запускает скрипты узлов.В принципе, каждый клиент будет:

// index.js
console.log('hello world')

Затем вызывается командная строка

> node index.js

## 输出:
> hello world

Для большей реалистичности добавим имя скрипта в поле scripts в package.json:

{
    "scripts":{
        "hello":"node index.js"
    }
}

Затем вызов командной строки:

> npm run hello

输出

Однако, увидев такое, вы точно скажете, что чужие webpack и vue-cli "именные"! какиеvue-cli init app,webpack -pДа как красиво, посмотрите на эту командную строку,node index.js,Такжеnpm run hello, Кто бы не хотел, это не некрасиво, боюсь, это не статья от воды? Плохой отзыв! !

Не волнуйтесь, давайте поговорим о том, как назвать этот сценарий узла.

0x2 имя

На данный момент сначала назовите этот cli какhello-cli, то есть мы можем ввести в командной строкеhello-cli, затем печатает предложениеhello world,нетnodeниnpm,то есть:

hello-cli
Здесь нам нужно сделать несколько шагов:

  1. Среда выполнения объявлена ​​в верхней части файла index.js:
    // index.js
    #!/usr/bin/env node
    console.log('hello world')
    
    Добавить к#!/usr/bin/env nodeили#!/usr/bin/node, который сообщает системе, что следующий скрипт выполняется с использованием nodejs. Конечно, эта система не включает окна, потому что под окнами находится историческая реликвия JScript, из-за которой ваш скрипт не сможет работать.
    #!/usr/bin/env nodeЭто означает позволить системе самостоятельно найти исполняемую программу узла.
    #!/usr/bin/nodeЭто означает явно указать системе, что исполняемая программа узла находится на пути/usr/bin/node.
  2. Добавьте поле bin в package.json.
    Может выполняться в текущем каталоге index.jsnpm initСоздайте package.json, а затем добавьте в package.json поле bin:
    {
         "name": "hello-test",
         "version": "1.0.0",
         "bin":{
             "hello-cli":"index.js"  
         }
    }
    
    Напишите имя командной строки в поле bin, котороеhello-cli, который сообщает npm, что скрипт js внутри может быть выполнен через командную строку дляhello-cliкомандный вызов. Само собой имя командной строки ваше, пишите что хотите, например:
    bin
    +1s
  3. В текущем каталоге package.json откройте инструмент командной строки и выполнитеnpm link, оставив ярлык для текущего кода в глобальном каталоге npm.
    npm обнаруживает, что в package.json есть поле bin, и одновременно генерирует исполняемый файл в глобальном каталоге пакета npm:
    Когда мы выполняем непосредственно в системной командной строкеhello-cli, на самом деле выполнить скрипт здесь.
    Потому что при установке узла npm настраивает этот каталог как среду системных переменных.Когда вы выполняете команду, система сначала будет искать системные команды и системные переменные, а затем переходить в среду переменных, чтобы найти имя команды, а затем найти это directory. , найдите исполняемый файл, соответствующий имени команды, и выполните его напрямую. Так выполняется либо vue-cli, либо webpack-cli.

Таким образом, ваш первый cli-скрипт был успешно установлен.Вы можете напрямую ввести имя cli в командной строке и увидеть результат.

Кроме того, если вы хотите, чтобы ваш cli-скрипт исполнялся только в проекте, вам нужно создать новую директорию в вашем проекте и повторить вышеописанную операцию, но на третьем шаге не ссылаться на глобальную, а использоватьnpm i -D file:<你的脚本cli目录路径>, и установите его в node_modules как зависимость проекта. Если установка прошла успешно, вы увидите дополнительную зависимость в package.json проекта. Значением этой зависимости является не номер версии, а путь вашего скрипта. Затем в node_modules будет каталог .bin, в котором будут храниться ваши исполняемые файлы.

Рекомендуется локальная установкаnpm i -D file:xxx, так что он оставит запись в package.json для других друзей. Естественно, ваши скрипты также лучше всего размещать в каталоге проекта.

Разумеется, скрипт cli, установленный таким образом, должен объявить команду script в поле scripts файла package.json проекта, а затем передатьnpm runспособ выполнения.

Ой? Если вы используете его таким образом, вы не вернетесь к исходному в самом начале.npm run helloЭто то же самое.

Да, но есть качественные различия. использоватьnode index.jsВызывать таким образом просто и гибко, но сильно зависит от пути к скрипту.После изменения структуры каталогов команды, прописанные в скриптах, нужно менять один раз, но после установки с помощью npm локальный cli-скрипт подтягивается в node_modules и изменения структуры каталогов мало на это влияют. Во-вторых, это не способствует совместному использованию и публикации.Если вы хотите опубликовать свой cli-скрипт, лучше иметь красивое и громкое имя, чем рассказывать пользователям, как найти путь к вашему скрипту в документации и выполнить его с помощью node.10 000 раз больше, не так ли?

Здесь также представлена ​​идея процесса разработки cli:

  • Первоначальная разработка может осуществляться черезnode index.jsчтобы увидеть эффект.
  • пройти тестnpm linkспособ проверить установку.
  • выпускать

0x3 Чтение параметра: process.argv

Теперь, когда у нас есть имя, у нас есть вывод Давайте посмотрим, в чем разница между нами и этими знаменитыми инструментами cli по форме? Кстати, люди могут поддерживать различные варианты параметров, а также могут давать разные результаты в зависимости от ввода.

Ну давайте добавим в этот кли функцию, раз уж она называетсяhello-cli, это не может толькоhello worldНу, вы должны встретиться с кем-то, чтобы сказатьhelloПросто делать:

> hello-cli older
## 输出
> hello older

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

Аргументы в командной строке, доступ к которым можно получить черезprocessЭта переменная получает,processявляется глобальным объектом, а не пакетом, и его не нужно передаватьrequireПредставлять. пройти черезprocessС помощью этого объекта мы можем получить ряд сведений, таких как текущая среда выполнения скрипта, включая ввод командной строки.Эта информация сохраняется вprocess.argvв этом свойстве. Мы можем напечатать это:

//index.js
console.log(process.argv);

распечатать результат:

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

//index.js
console.log(`hello ${process.argv[2]||'world'}`)

В сообществе npm также есть отличные пакеты для разбора параметров командной строки, такие какyargs, т. е.commander.jsтак далее

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

0x4 дочерний процесс

Теперь вы можете писать свои собственные cli-скрипты.
Если вы хотите написать проект и автоматически отправить пакет в git cli или автоматически извлечь шаблон запуска проекта из репозитория git, вам необходимо передать узелchild_processМодуль запускает подпроцесс и вызывает команду git в подпроцессе:

//test.js
const child_process = require('child_process');

let subProcess=child_process.exec("git version",function(err,stdout){
    if(err)console.log(err);
    console.log(stdout);
    subProcess.kill()
});

Здесь могут быть выполнены не только команды git, но и системные команды и другие команды cli. Особенно системные команды, использование системных команд для работы с файловыми каталогами более эффективно, чем fs, поэтому я не знаю, куда идти.

В сообществе также есть несколько хороших пакетов, например, рекомендованных Ruan Yifeng.shelljs

0x5 украсить вывод

Если вы не хотите, чтобы ваш cli был таким «хардкорным», вы хотите, чтобы он был более удобным для пользователя, например, предоставлял дружественный ввод и подсказки, добавлял некоторые цвета к вашему выводу, чтобы различать ключевые точки, написание простого индикатор выполнения и т. д. Подождите, тогда вам нужно украсить свой вывод.

Кроме цветовой части, это очень громоздко и сложно реализовать без использования сторонних пакетов, остальные функции можно попробовать написать самому.
Цветная часть использует сторонний пакетcolors, что не будет здесь продемонстрировано.
Другие предоставляются nodejsreadlineреализуется модулем.

//index.js
const readline = require('readline');
const unloadChar='-';
const loadedChar='=';
const rl=readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question('你想对谁说声hello? ',answer=>{
    let i = 0;
    let time = setInterval(()=>{
        if(i>10){
            clearInterval(time);
            readline.cursorTo(process.stdout, 0, 0);
            readline.clearScreenDown(process.stdout);
            console.log(`hello ${answer}`);
            process.exit(0)
            return
        }
        readline.cursorTo(process.stdout,0,1);
        readline.clearScreenDown(process.stdout);
        renderProgress('saying hello',i);
        i++
    },200);
});

function renderProgress(text,step){
    const PERCENT = Math.round(step*10);
    const COUNT = 2;
    const unloadStr = new Array(COUNT*(10-step)).fill(unloadChar).join('');
    const loadedStr = new Array(COUNT*(step)).fill(loadedChar).join('');
    process.stdout.write(`${text}:【${loadedStr}${unloadStr}|${PERCENT}%】`)
}
  1. Во-первых, поreadline.createInterfaceметод созданияinterfaceДобрый, есть метод ниже этого класса.question, используйте этот метод, чтобы передать проблему в командную строку и передать функцию для прослушивания во втором параметре. Как только пользователь заканчивает печатать и нажимает Enter, срабатывает функция обратного вызова.
  2. Затем мы написали таймер внутри функции обратного вызова, делая вид, что мы что-то делаем.
  3. использоватьreadline.cursorToЭтот метод изменяет положение курсора в командной строке.
    readline.cursorTo(process.stdout, 0, 0);это перейти к столбцу 1, строке 1,
    readline.cursorTo(process.stdout, 0, 1);это перейти к столбцу 1 и строке 2.
  4. использоватьreadline.clearScreenDownЭтот метод заключается в запуске командной строки с текущей строки до конца последней строки и очистке всего между двумя строками.
  5. renderProgressЭто метод собственной инкапсуляции, посредствомprocess.stdout.writeМетод выводит в командную строку строку, которая выглядит как индикатор выполнения.
  6. Итак, в таймере, когда счетчик меньше 10, мы перемещаем курсор на первую строку, затем очищаем весь вывод и выводим строку индикатора выполнения; когда счетчик больше 10, мы выключаем таймер, очищаем вывод, Распечатать результат.
  7. Наконец, не забудьте закрыть процесс, вы можете использоватьinterfaceэтого класса.closeМетод отключает процесс readline, или вы можете вызвать его напрямуюprocess.exitпокидать.

Идея рисования такая же, как анимация рисования холста, за исключением того, что холст очищает холст, а командная строка передается черезreadline.clearScreenDownОчистить вывод.

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

Ведь в нашем фронтенде мы можем писать анимации с браузером, а можем писать анимации без браузера.

ссылка 0x6