Что такое интерфейс командной строки
воспитывать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метод определенияcommanderoptions, конечно, эти определенные параметры также будут использоваться в качестве справочной документации команды.
-
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метод используется для преобразования относительных путей в абсолютные пути. Он может принимать несколько параметров, указывая путь, который нужно ввести по очереди, пока последний параметр не будет преобразован в абсолютный путь. Если абсолютный путь не может быть получен в соответствии с параметрами, в качестве ссылки используется текущий путь. За исключением корневого каталога, возвращаемое значение этого метода не имеет завершающей косой черты.