一、什么是CLI
cli相当于一个命令行界面,我们常用的npm install 、npm run xxx 都属于CLI命令
二、创建一个CLI
1、初始化
创建个文件夹,执行npm init 初始化项目,package.json内容如此
{
"name": "ycli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "",
"license": "ISC"
}
2、编辑package.json文件
{
"name": "ycli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
//region 新增
"bin": {
"study-test": "index.js"
},
//endregion
"author": "",
"license": "ISC"
}
可以看到我们新增了一个bin,其含义是给我们的cli一个命名,并且指明入口文件为index.js
3、创建入口文件
#! /usr/bin/env node
console.log('进来了')
可以看到我们的入口文件上有一行独特的代码 #! /usr/bin/env node,它是一个Shell脚本规则,其含义是指明这个文件的运行环境为node, /usr/bin/env是我们的本地的环境变量,这个是为了告诉我们的系统从哪里去找node,感兴趣的同学可以看一下www.ruanyifeng.com/blog/2016/1…
4、运行CLI
我们平时使用cli时一般有两种方式,一种是将CLI下载到本地,也就是npm instll global XXX ,还有一种就是npx,两种的区别就是npx不用将CLI包下载到本地,它是一种去引用npm云端CLI的方法,由npm提供,因为我们的包还没有上传到npm的云端,所以npx肯定是不适用了,但是没有上传的云端也不涉及到npm install下载这个问题,我们可以使用npm link,这个命令做的事情的结果类似于npm install global XXX,可以把我们写的库和npm全局建立一个软连接,这样我们运行我们声明的cli命令就可以找到我们的包
可以看到有了进来了的字样,证明我们的cli执行成功了。
🎉撒花,这样我们就完成了一个最简单的CLI
三、处理命令
在我们使用cli的时候往往都是伴随值命令的,例如 vue create app,现在我们已经知道了如何去执行我们的代码,现在我们要学习根据用户输入去执行不同的代码,首先,先去获取用户的输入命令是什么,目前有一个命令行解决方案(库)commander.js
这里简单的说明一下commander的使用,
const { program } = require('commander')
program
// 注册命令
.command('create <template>')
.description('create a new project')
// 注册选项
.option('-v, --vue', 'vue templete')
.option('-r, --react', 'react templete')
.option('-v2, --vue2', 'vue2 templete')
.option('-v3, --vue3', 'vue3 templete')
.action((projectName, options) => {
console.log(projectName, options)
})
program.version('1.0.0', '-v, --version').parse()
尝试一下
study-test create app -v
app { vue: true }
四、处理交互行为
有的时候我们可能需要在命令行工具中融入一些交互行为,例如选择是否使用ts等,我们可以引入包inquirer来处理这一行为,简单的上手文档juejin.cn/post/722137…
const inquirer = require('inquirer')
// 创建一个问题模块
const prompt = inquirer.createPromptModule()
// 创建问题
const questions = [{
type: 'input',
name: 'name',
message: 'what is your name?',
default: 'yuexingyu'
},
{
type: 'password',
name: 'password',
message: 'this is password'
},{
type: 'confirm',
name: 'confirm',
message: 'Do you like BbQ?',
default: true
},{
type: 'list',
name: 'list',
message: 'what is you favourite programming language?',
choices: ['JS', 'node', 'Java'],
default: 'JS'
},{
type: 'checkbox',
name: 'checkbox',
message: 'this is checkbox',
choices: [
{ name: 'HTML', checked: true },
{ name: 'CSS', checked: true },
{ name: 'JavaScript', checked: true },
{ name: 'Node.js' },
{ name: 'React' },
{ name: 'Vue' }
]
}]
// 进行提问
prompt(questions).then(answer => {
console.log('回答', answer)
})
试一下
study-test create app
what is your name? yuexingyu
? this is password [hidden]
? Do you like BbQ? Yes
? what is you favourite programming language? node
? this is checkbox Node.js, React
回答 {
name: 'yuexingyu',
password: '123456',
confirm: true,
list: 'node',
checkbox: [ 'Node.js', 'React' ]
}