Что такое интерфейс командной строки
воспитыватьCLI
, не могу не вспомнитьvue-cli
а такжеangular-cli
, они основаны наNode
инструмент командной строки.
Зачем разрабатыватьCLI
Предположим, вы сейчас создаете новый проект с той же конфигурацией, что и предыдущий проект. без тебяCLI
, вы можете сделать это только путем копирования и вставки. Однако, когда у вас естьCLI
, вы можете выполнить эти шаги с помощью команд. Конечно, можно сказать просто создать новый проект, разрабатывать еще один совершенно не обязательно.CLI
инструмент. Что делать, если вы хотите создать n новых проектов? В это время естьCLI
и нетCLI
разница проявляется.
как разработатьCLI
Подготовить
разрабатыватьCLI
, потребуются следующие инструменты:
Начинать
Создайте новую папку, назовите ееdemo-cli
, а внутри папкиnpm init
. существуетdemo-cli
Внутри папки создайте новыйbin
папку и создайте новую в этой папкеindex.js
документ. Далее откройтеdemo-cli
в папкеpackage.json
файл и добавьте в него следующую команду.
{
"bin": {
"demo": "./bin/index.js"
}
}
Этот код означает, что при использованииdemo
Когда команда будет выполнена, она будет выполненаbin
в папкеindex.js
документ.
В это время мыindex.js
файл, напишите следующий код.
#!/usr/bin/env node
console.log('hello CLI');
существуетdemo-cli
запустить в каталогеnpm link
,demo
, на этот раз вы найдете вывод консолиhello CLI
.
Примечание:
#!/usr/bin/env node
указать операционной системе использоватьNode
запустить этот файлnpm link
Основная роль заключается в развитииnpm
Что касается модулей, мы будем отлаживать их во время разработки. В настоящее время,npm link
Это пригодилось.
шаг за шагом
- существует
index.js
Внутри файла напишите следующий код.
#!/usr/bin/env node
const program = require('commander');
program
.version('1.0.0', '-v, --version')
.command('init <dir>', 'generate a new project')
.parse(process.argv);
commander
обеспечивает использованиеnode.js
развивать возможности командной строки. мы можем пройтиcommander
изoption
метод определенияcommander
options, конечно, эти определенные параметры также будут использоваться в качестве справочной документации команды.
-
version
: Используется для определения номера версии.commander
Помогите нам добавить по умолчанию-V, --version
опции. Конечно, мы также можем сбросить его. -
command
:<>
Требуются делегаты,[]
Представитель необязателен. когда.command()
С параметром описания его нельзя использовать.action(callback)
для обработки подкоманды, иначе произойдет ошибка. это говоритcommander
, вы будете использовать отдельные исполняемые файлы в качестве подкоманд. -
parse
: разборprocess.argv
, данные после парсинга будут храниться вnew Command().args
в массиве.process.argv
Содержимое, хранящееся в нем, следующее:
program.args[0]
вывезтиdir
ценность .
Вопрос: почему когда
command
нет параметров описания, иparse
Метод, использующий цепной вызов, сообщит об ошибке? (догадка:command
имеютdesc
параметр, возвратthis
, когда нетdesc
параметр, возвращает новый объект,согласно сAPI Document
предполагаемый)
```js
// 正确
program
.version('1.0.0', '-v, --version')
.command('init <dir>', 'generate a new project')
.action(function(dir, cmd){
console.log(dir, cmd)
})
.parse(process.argv);
// 正确
program
.version('1.0.0', '-v, --version')
.command('init <dir>', 'generate a new project')
.action(function(dir, cmd){
console.log(dir, cmd)
})
program.parse(process.argv);
// 正确
program
.version('1.0.0', '-v, --version')
.command('init <dir>')
.action(function(dir, cmd){
console.log(dir, cmd)
})
program.parse(process.argv);
// 错误
program
.version('1.0.0', '-v, --version')
.command('init <dir>')
.action(function(dir, cmd){
console.log(dir, cmd)
})
.parse(process.argv);
```
- существует
bin
Создать в файлеdemo-init.js
файл, часть кода выглядит следующим образом:
#!/usr/bin/env node
const shell = require('shelljs');
const program = require('commander');
const inquirer = require('inquirer');
const download = require('download-git-repo');
const ora = require('ora');
const fs = require('fs');
const path = require('path');
const spinner = ora();
program.parse(process.argv);
let dir = program.args[0];
const questions = [{
type: 'input',
name: 'name',
message: '请输入项目名称',
default: 'demo-static',
validate: (name)=>{
if(/^[a-z]+/.test(name)){
return true;
}else{
return '项目名称必须以小写字母开头';
}
}
}]
inquirer.prompt(questions).then((answers)=>{
// 初始化模板文件
downloadTemplate(answers);
})
function downloadTemplate(params){
spinner.start('loading');
let isHasDir = fs.existsSync(path.resolve(dir));
if(isHasDir){
spinner.fail('当前目录已存在!');
return false;
}
// 开始下载模板文件
download('gitlab:git.gitlab.com/demo-static', dir, {clone: true}, function(err){
if(err){
spinner.fail(err);
};
updateTemplateFile(params);
})
}
function updateTemplateFile(params){
let { name, description } = params;
fs.readFile(`${path.resolve(dir)}/public/package.json`, (err, buffer)=>{
if(err) {
console.log(chalk.red(err));
return false;
}
shell.rm('-f', `${path.resolve(dir)}/.git`);
shell.rm('-f', `${path.resolve(dir)}/public/CHANGELOG.md`);
let packageJson = JSON.parse(buffer);
Object.assign(packageJson, params);
fs.writeFileSync(`${path.resolve(dir)}/public/package.json`, JSON.stringify(packageJson, null, 2));
fs.writeFileSync(`${path.resolve(dir)}/README.md`, `# ${name}\n> ${description}`);
spinner.succeed('创建完毕');
});
}
-
inquirer
В основном он обеспечивает функцию интерактивных команд.validate
вернутьtrue
Указывает, что входное значение допустимо для проверки. Если возвращается какая-либо строка, она будет возвращена вместо стандартного сообщения об ошибке. - пройти через
Node
серединаfs
модуль, чтобы определить, существует ли уже папка.path.resolve
метод используется для преобразования относительных путей в абсолютные пути. Он может принимать несколько параметров, указывая путь, который нужно ввести по очереди, пока последний параметр не будет преобразован в абсолютный путь. Если абсолютный путь не может быть получен в соответствии с параметрами, в качестве ссылки используется текущий путь. За исключением корневого каталога, возвращаемое значение этого метода не имеет завершающей косой черты.