Node插件之inquirer

2,499 阅读5分钟

PS: 演示demo在文章最后面,可做学习参考

Inquirer.js是做什么的?

Inquirer.js试图为NodeJs做一个可嵌入式的美观的命令行界面,它是非常容易去处理以下几种事情的:

  • 提供错误回调
  • 询问操作者问题
  • 获取并解析用户输入
  • 检测用户回答是否合法
  • 管理多层级的提示

编写一个小demo

const inquirer = require('inquirer')
inquirer.prompt([ { 
  type: 'confirm', 
  name: 'test', 
  message: 'Are you handsome?', 
  default: true 
}]).then((answers) => { console.log('结果为:') console.log(answers)})

其中prompt方法中的参数为question数组对象,每一个对象都可以配置一些属性,这个需要配合commander使用。

问题对象具体配置项:

  • type:(String)提示的类型。默认值:input-可能的值:input,number,confirm, list,rawlist,expand,checkbox,password,editor
  • name:(String)将答案存储在答案哈希中时使用的名称。如果名称包含句点,它将在答案哈希中定义路径。
  • message:(String | Function)要打印的问题。如果定义为函数,则第一个参数将是当前查询者会话答案。默认值为name(后面跟冒号)。
  • default:(String | Number | Boolean | Array | Function)如果未输入任何内容,则使用默认值,或者返回默认值的函数。如果定义为函数,则第一个参数将是当前查询者会话答案。
  • choices:(Array | Function)Choices数组或返回choices数组的函数。如果定义为函数,则第一个参数将是当前查询者会话答案。数组值可以是简单的numbers,strings或objects含有一个name(将在一览显示),一个value(在答案散列保存),和一个short(以后选择显示)属性。choices数组也可以包含一个Separator。
  • validate:(功能)接收用户输入并回答哈希。true如果该值有效,则应返回,否则返回错误消息(String)。如果false返回,则提供默认错误消息。
  • filter:(功能)接收用户输入并回答哈希。返回要在程序内部使用的过滤值。返回的值将添加到Answers哈希中。
  • transformer:(功能)接收用户输入,回答哈希和选项标志,并返回转换后的值以显示给用户。转换仅影响编辑时显示的内容。它不会修改答案哈希。
  • when:(Function,Boolean)接收当前用户的答案哈希,并应返回true或false取决于是否应询问此问题。该值也可以是一个简单的布尔值。 的pageSize:(号码)改变将使用时呈现的行数list,rawList,expand或checkbox。
  • prefix:(String)更改默认的前缀消息。
  • suffix:(字符串)更改默认的后缀消息。
  • askAnswered:(布尔型)如果答案已经存在,则强制提示该问题。
  • loop:(布尔)启用列表循环。默认值:true
每个type类型需要配置的项或多或少会有些不同,比如当type为checkbox时,需要配置choices这一项,而当type为number时就不需要。

以下是一些type类型需要配置的项的示例

  • input

取type,name, message[, default, filter, validate, transformer]属性

inquirer.prompt([ {
  type: 'input', 
  name: 'size', 
  message: 'Select size: large, medium and small', 
  default: 'medium'
}]).then((answers) => { 
  console.log('结果为:')
  console.log(answers)
})
  • number

取type,name, message[, default, filter, validate, transformer]属性

inquirer.prompt([ {
  type: 'number', 
  name: 'number', 
  message: 'How much do you need?', 
  default: 1
}]).then((answers) => { 
  console.log('结果为:')
  console.log(answers)
})
  • confirm

取type,name,message,[ default]属性。default如果使用,则应为布尔值。

inquirer.prompt([ {
  type: 'confirm', 
  name: 'confirm', 
  message: '请问你现在要开始点餐了吗?', 
  default: true
}]).then((answers) => { 
  console.log('结果为:')
  console.log(answers)
})
  • list

问题对象中必须有type,name,message,choices等属性,同时,default选项必须为默认值在choices数组中的位置索引(Boolean)

inquirer.prompt([ {
  type: 'list', 
  name: 'list', 
  message: 'What do you like to drink?', 
  choices: ['black-tea', 'green-tea', 'milk-tea'],
  default: 1
}]).then((answers) => { 
  console.log('结果为:')
  console.log(answers)
})
  • checkbox

取type,name,message,choices[, filter, validate, default, loop]属性。预期为已检查选择值的数组。 {checked: true}默认情况下将选中标记为的选项。

属性disabled为真的选择将是不可选择的。如果disabled为字符串,则该字符串将在禁用选项旁边输出,否则默认为"Disabled"。该disabled属性也可以是一个同步函数,该函数接收当前答案作为参数并返回布尔值或字符串。

inquirer.prompt([ { 
  type: 'checkbox', 
  name: 'checkbox', 
  message: 'What do you like to drink?', 
  choices: ['black-tea', 'green-tea', 'milk-tea', new inquirer.Separator(), 'juice'], //可以在数组中插入分割符
  default: ['black-tea'] //这里需要用数组,不能像list一样用下标
}]).then((answers) => { 
  console.log('结果为:')
  console.log(answers)
})
  • password

取type, name, message, mask,[, default, filter, validate]属性

inquirer.prompt([ { //当类型为confirm时,各配置项示例
  type: 'password', 
  name: 'password', 
  message: 'Please input password:', 
  mask: true
}]).then((answers) => { 
  console.log('结果为:')
  console.log(answers)
})
  • Raw list

{type: 'rawlist'} 与List类型类似,不同在于,list打印出来为无序列表,而rawlist打印为有序列表

  • Expand

{type: 'expand'} 取type,name,message,choices[,default]属性。(请注意,默认值必须是index数组中的选项。如果default未提供键,help则将用作默认选项) 请注意,该choices对象将使用一个额外的参数key来expand提示。此参数必须是单个(小写)字符。该h选项是由提示添加的,不应由用户定义。

  • Editor

{type: 'editor'} 终端打开用户默认编辑器,如vim,notepad。并将用户输入的文本传回

inquirer需要配合commander来使用,以下是一个简单的演示demo

console.log('命令行已启动')
const program = require('commander')
const inquirer  = require('inquirer')

program.version('0.0.1', '-v, --version', 'output the current version');

program
  .option('--type <type...>','What do you like to drink? We have black-tea, green-tea, flower-tea, milk-tea and juice')
  .option('-n, --number <number...>', 'How much do you need?')
  .option('-s, --size <size...>', 'Select size: large, medium and small')
  .option('-S, --sugar <sugar...>', 'Select sugar content: less, normal and more')
  .action(function (list) {

  })

inquirer.prompt([ {
  type: 'checkbox', 
  name: 'type', 
  message: 'What do you like to drink?', 
  choices: ['black-tea', 'green-tea', 'milk-tea'], 
  default: ['black-tea']
}, {
  type: 'input', 
  name: 'number', 
  message: 'How much do you need?', 
  default: '1'
}, { 
  type: 'checkbox', 
  name: 'size', 
  message: 'Select size: large, medium and small', 
  choices: ['large', 'medium','small'],
  default: ['medium']
}, { 
  type: 'checkbox', 
  name: 'sugar', 
  message: 'Select sugar content: less, normal and more', 
  choices: ['less', 'normal','more'],
  default: ['normal'] 
}]).then((answers) => { 
  const type = answers.type,
      number = answers.number.split(' '),
      size = answers.size,
      sugar = answers.sugar;

  console.log('\nYour have ordered: \n');
  if(type && type.length > 0) {
    type.forEach((value, index) => {
      console.log(`${ number[index] } ${ size[index] } cups of ${ value } with ${ sugar[index] } sugar\n`)
    })
  }
})

program.parse(process.argv)

以上demo保存为index.js,然后终端进入index.js所在文件夹,执行以下命令:

node index.js

输出结果:
命令行已启动
? What do you like to drink? black-tea, green-tea, milk-tea
? How much do you need? 1 2 3
? Select size: large, medium and small large, medium, small
? Select sugar content: less, normal and more less, medium, more

Your have ordered: 

1 large cups of black-tea with less sugar

2 medium cups of green-tea with medium sugar

3 small cups of milk-tea with more sugar