Научите вас, как реализовать инструмент cli

Node.js

предисловие

Когда дело доходит до строительных лесов, вы обязательно подумаете о vue-cli. Некоторые люди отступят, когда увидят интересные функции и взаимодействия vue-cli. Если бы я сказал вам, что нам нужна только база nodejs для написания функций, таких как vue-cli, вы были бы немного взволнованы? Далее следуйте моим шагам, чтобы раскрыть строительные леса.

Готов к работе

Прежде всего, нашему компьютеру нужна среда разработки nodejs, нажмите здесь, чтобы загрузить и установить (пожалуйста, не указывайте существующую среду):nodejs; командный вводnode -v, и появится номер версии, показанный на рисунке ниже, установка прошла успешно.

Шаги развития

Инициализировать проект

npm initИнициализировать проект; после успешной инициализации будет сгенерирован проект в соответствии с введенной конфигурациейpackage.jsonдокумент:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Добавить команду скаффолдинга и файл ввода команды (тест)

Команда строительных лесов:существуетpackage.jsonДобавьте конфигурацию bin, чтобы указать расположение исполняемого файла, соответствующего определяемой вами команде.Код выглядит следующим образом:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "bin": {
    "test": "bin/test.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

файл ввода команды:согласно сpackage.jsonВ конфигурации bin мы добавляем папку bin в корневой каталог проекта и создаем новую папку в этой папке.test.js, код показан ниже:

#!/usr/bin/env node
console.log('test')

Первая строка должна быть добавлена, здесь указано, чтобы использовать узел для разбора этого скрипта. Найти по умолчанию/usr/binкаталог, если вы не можете его найти, перейдите к переменной системной среды, чтобы найти его.

В это время мыcmdвойтиtestкоманду, вы найдете ошибку:Почему я не могу найти тестовую команду? Давайте сначала разберемся, почему после того, как мы установили vue-cli, ввод vue не сообщает об ошибке? Откройте нас вопросамиnpmГлобально установленный каталог файлов:Обратите внимание на красное место на картинке выше, мы обнаружим, что в нем тоже наши знакомые старые друзья:cnpm,vue. Здесь мы сначала оставим неизвестность и вернемся к проекту строительных лесов только сейчас.

ссылка на глобальную: выполните следующую команду в корневом каталоге проекта.npm link, после успешного выполнения проверим каталог нашего глобального npm.В это время мы обнаружим, что есть еще несколько элементов.Осторожно, вы обязательно обнаружите, что дополнительный файл назван в честь того, что мы находимся вpackage.jsonнастроен вbinключ:

В этот раз мы снова открываемсяcmdвойтиtestПытаться:

Сравнив влияние вышеуказанного сбоя, вы обнаружите, что на этот раз система распозналаtestкоманда и вывод консолиtest. Вышеупомянутые вопросы должны быть решены здесь: Выполните ссылку npm и оставьте ярлык для текущего кода в глобальном каталоге npm.npm обнаруживает, что в package.json есть поле bin, и оно также находится в глобальном каталоге пакета npm. Генерируется исполняемый файл:

  1. npm link, связанный с глобальным
  2. binСоздание командных файлов с помощью ссылки npm
  3. "test": "bin/test.js",cmdвоплощать в жизньtest, согласно конфигурации будет выполнятьсяbin/test.jsэтот файл

добавить команду

Мы должны иметь функции, которыми обладают строительные леса других людей, такие как:-V(--version) -H(--help)Ждать.

commander

Во-первых, мы сначала устанавливаем требуемую библиотеку командира, а затем устанавливаем требуемую библиотеку командира для нашегоtestКоманда добавляет самый основной номер версии для просмотра команды:

#!/usr/bin/env node
const program = require('commander')
program
	.version(`version is ${require('../package.json').version}`)
	.parse(process.argv)

Здесь следует отметить, что последний.parse(process.argv)Код не может быть утерян, если нет, то введенные нами параметры не могут быть проанализированы, эффект следующий:

Кроме того, вы можете добавить.description .usage .option .action .commandПодождите, давайте сосредоточимся на.command和.actionметод: где команда позволяет нам зарегистрировать команду (аналогичноvue create), код показан ниже:

program
    .version(`Version is ${require('../package.json').version}`)
    .description('A simple CLI for building initialize project include Wechat applet, Vue, Egg (nodejs)')
    .usage('<command> [options]')
    .command('create')
    .option("-l --list", "project list", listOption)
    .action((name, cmd) => {
    	console.log(111)
        require('../lib/create')
    })
    .parse(process.argv)

терминальный входtest createПроверьте эффект:Зарегистрированная нами команда создания печатается методом действия111, где мы можемactionВыполняйте другие файлы js в модульной разработке нашегоcreateвведите следующий кодtext createбудет выполнятьlib/create.js:

.action((name, cmd) => {
        require('../lib/create')
    })

Разбор параметров:

const program = require('commander')
const inquirer = require('inquirer')
program.usage('<project-name>').parse(process.argv)
console.log(program.args)

консольный вводtest create saa dfasas:

Дополнительные ссылки на использование:commander

chalk

Роль пакета chalk заключается в изменении стиля строк в консоли: например, стиль шрифта, цвет шрифта, цвет фона и т. д.

Дополнительные ссылки на использование:chalk

log-symbols

Предоставляет цветные символы для различных уровней журнала (аналогично √ для успешной загрузки)

Дополнительные ссылки на использование:log-symbols

ora

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

командное взаимодействие запросчика

Эта библиотека является инструментом, с которым мы можем взаимодействовать с пользователем; мы определяем две проблемы: имя проекта и номер версии,create.jsНапишите следующий код в:

const inquirer = require('inquirer')
getInquirer().then((res) => {
	console.log(res)
})
function getInquirer() {
	return inquirer.prompt([
		{
			name: 'projectName',
			message: 'project name',
			default: 'project',
		},
		{
			name: 'projectVersion',
			message: '项目版本号',
			default: '1.0.0',
		},
	])
}

терминальное исполнениеtest create, приведенный выше код выводит параметры, полученные после выполнения, как показано на следующем рисунке:

download-git-repo

Этот модуль используется для загрузки проекта шаблона на git, аналогично инициализации vue-cli, он также загружает код на git и возвращает его локально для завершения построения среды разработки. Следующий код инкапсулирует загруженный код, который используется для клонирования кода целевого адреса на локальный в соответствии с входящим адресом git:

const ora = require('ora');
const chalk = require("chalk");
const logSymbols = require('log-symbols');
const download = require('download-git-repo');
const {
    spawnSync
} = require("child_process");

module.exports = function (target, downLoadURL) {
    let {
        error
    } = spawnSync("git", ["--version"]);
    if (error) {
        let downurl = downLoadURL.replace("direct:", "");
        console.log(logSymbols.warning, chalk.yellow("未添加Git环境变量引起,添加Git与git管理库的环境变量即可;"))
        console.log(logSymbols.info, chalk.green('或直接到模板地址下载:', downurl));
        return Promise.reject(error);
    }

    return new Promise((resolve, reject) => {
        const spinner = ora(`正在下载模板`)
        spinner.start();
        console.log(downLoadURL)
        download(downLoadURL, target, {
            clone: true
        }, (err) => {
            if (err) {
                let errStr = err.toString()
                spinner.fail();
                reject(err);

                if (errStr.includes("status 128")) {
                    console.log('\n', logSymbols.warning, chalk.yellow("Git默认开启了SSL验证,执行下面命令关闭后再重试即可;"))
                    console.log(logSymbols.info, chalk.green("git config --global http.sslVerify false"))
                }
            } else {
                spinner.succeed();
                resolve(target);
            }
        })
    })
}

Проверьте имя каталога файла, введенное при загрузке шаблона:

function checkProjectName(projectName) {
    let next = null;
    if (list.length) {
        if (
            list.filter((name) => {
                const fileName = path.resolve(process.cwd(), path.join(".", name));
                const isDir = fs.statSync(fileName).isDirectory();
                return name.indexOf(projectName) !== -1 && isDir;
            }).length !== 0
        ) {
            console.error(logSymbols.error, chalk.red(`项目${projectName}已经存在`));
            return Promise.resolve(false);
        }
        next = Promise.resolve(projectName);
    } else if (rootName === projectName) {
        next = inquirer
            .prompt([{
                name: "buildInCurrent",
                message: "当前目录为空,且目录名称和项目名称相同,是否直接在当前目录下创建新项目?",
                type: "confirm",
                default: true,
            }, ])
            .then((answer) => {
                return Promise.resolve(answer.buildInCurrent ? "." : projectName);
            });
    } else {
        next = Promise.resolve(projectName);
    }

    return next;
}

child_process

Это пакет, поставляемый с nodejs. Он используется для запуска дочерних потоков. Он очень мощный. Подробности см.здесь; использовать здесьspawnSyncспособ проверить, существует ли локальныйgitокружающая обстановка:

const { spawnSync } = require("child_process");
let { error } = spawnSync("git", ["--version"]);

На данный момент вы освоили необходимые навыки для разработки строительных лесов, давайте действовать! (Если эта статья вас вдохновила, ставьте лайк, создавать картинки со словами не просто 😄)