脚手架系列-inquirer.js

1,464 阅读7分钟

inquirer.js

一组常用的交互式命令行用户界面。以vue/cli为例,下面的截图就是inquirer的功能

6AsmdO.png

使用方法

本次使用版本为:8.0.0

github地址:github.com/SBoudrias/I…

基础示例

// 来自官方文档
var inquirer = require('inquirer');
inquirer
  .prompt([
    /* Pass your questions in here */
  ])
  .then(answers => {
    // Use user feedback for... whatever!!
  })
  .catch(error => {
    if(error.isTtyError) {
      // Prompt couldn't be rendered in the current environment
    } else {
      // Something else went wrong
    }
  });

prompt()方法

inquirer.prompt(questions, answers) -> promise,使用方式大概就是这个样子,这个方法执行后会返回一个promise对象

函数参数

  • questions

这是一个数组类型,这个配置了你在执行prompt过后会展示的一系列可选项给用户,然后让用户选择,比如上面截图展示的vue/cli显示的一系列选项。

  • answers

这是一个对象类型,包含已经回答的问题的值。

Questions参数

对象里面可以设置的有效的值

  • type: String类型

表示prompt可以选择的类型,默认是input类型,其他还包括number, confirm, list, rawlist, expand, checkbox, password, editor

  • name: String类型

这个参数表示一个映射关系,比如你同时设置了questions和answers,prompt根据你选择的question去映射answer里面设置的对应的name,找到对应的关系。如果你只设置了questions,那么在最后的then()方法的参数里面会包含name的信息。

  • message:String|Function类型

要打印的问题。如果定义为函数,第一个参数将是当前查询者会话的回答。默认值为name

  • default: String|Number|Boolean|Array|Function类型

如果没有输入任何值,则使用默认值,或者返回默认值的函数。如果定义为函数,第一个参数将是当前查询者会话的回答。如果你的type是confirm类型,default值只会返回布尔类型,哪怕你的default值设置的字符串或者数值类型

  • choices: Array|Function类型

这个主要是用来配置list、rawlist、checkbox等列表类型的情况。

  • validate: Function类型

这个对用户的输入可以做校验。

  • filter: Function类型

这个可以对answers进行筛选,返回筛选过后的值。

  • transformer: Function类型

这个可以对用户的输入进行转换操作,不影响最终的输出answer结果。

  • when: Function|Boolean类型

这个只有当用户对这个问题做了回答操作后才会执行when里面相关的操作。

  • pageSize: Number类型

这个参数针对type类型为list, rawList, expand,checkbox的输出显示每页显示多少个question。

  • prefix: String类型

在你的message前面加一个前缀。

  • suffix: String类型

在你的message后面加一个后缀。

  • askAnswered: Boolean类型

如果答案已经存在,则强制提出问题。

  • loop: Boolean类型

是否允许列表循环显示,默认为true。

Answers

这是一个对象类型,包含一个key/value键值对,这个对象表示如果已经有答案了避免用户二次选择的话,可以把已有的答案写在这个参数里面。

  • key 相当于对应question里面的name属性
  • value 对应的值取决于你的prompt问题的类型
    • confirm类型,对应布尔值true或者false
    • input类型,对应用户输入,如果有filter筛选则对应筛选过后的内容
    • number类型,对应用户输入,如果有filter筛选则对应筛选过后的内容
    • rawlist、list类型,对应用户的选择,如果选项对应的没有声明具体的值,则以选项名为结果

示例代码:

const inquirer = require('inquirer');

let questions = [
  {
    type: 'list',
    name: 'phone',
    message: 'choice your phone number',
    choices: [
      {
        name: 'xiaomi'
      },
      {
        name: 'huawei'
      },
      {
        name: 'samsung'
      }
    ]
  }
];

let answers = {
  'apple': 'ok',
  'oppo': 'ok'
};

inquirer.prompt(questions, answers).then((ans) => {
  console.log(ans);
});

执行过后,如果我们选择了huawei,那么最终ans输出的结果就是下面的样子:

{ apple: 'ok', oppo: 'ok', phone: 'huawei' }

Separator()方法

这个方法可以在choices里面增加分割线,使用方法如下

choices: [
  new inquirer.Separator(), // 不给参数的话,默认分割线为‘--------’
  {
    name: 'A',
  },
  {
    name: 'B',
  },
  {
    name: 'C',
  },
  {
    name: 'D',
  },
  new inquirer.Separator('---line---'), // 分割线为---line---
  {
    name: 'one',
    checked: true,
  },
  {
    name: 'two',
  },
  {
    name: 'three',
  },
]

详解prompt的类型

input类型

这个类型允许用户进行输入操作。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message

可选参数为:

  • default
  • filter
  • validate
  • transformer

简单示例代码如下

const inquirer = require('inquirer');

/*** input ***/
let questions = [
  {
    type: 'input',
    name: 'input your favorite book',
    message: 'your favorite book is:',
    default: 'book-one',
  }
]

inquirer.prompt(questions).then((answers) => {
  console.log(answers);
})

输出结果如下:

6e8O41.png

官方示例代码比较完整,链接如下:github.com/SBoudrias/I…

官方示例结果演示如下: 6e8v36.png

number类型

允许用户输入数字,如果不是数字,则结果对应的是NaN。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message

可选参数为:

  • default
  • filter
  • validate
  • transformer

示例代码如下:

const inquirer = require('inquirer');

let questions = [
  {
    type: 'number',
    name: 'your favorite number',
    message: 'input your favorite number: ',
    default: 100
  }
];

inquirer.prompt(questions).then((ans) => {
  console.log(ans);
});

输出结果如下:

6eYJnU.png

confirm类型

给出单项选择,让用户选择Y/n。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message

可选参数为:

  • default 如果使用了这个参数,那么对应的值必须是布尔值

示例代码如下:

const inquirer = require('inquirer');

let questions = [
  {
    type: 'confirm',
    name:'your select',
    message: 'Do you like red?',
    default: 'red'
  }
];

inquirer.prompt(questions).then((ans) => {
  console.log(ans);
})

输出结果如下:

6efvTJ.png

list类型

列出一系列选项让用户选择。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message
  • choices

可选参数为:

  • default default必须是数组中的选择索引或选择值
  • filter
  • loop

示例代码如下:

const inquirer = require('inquirer');

let questions = [
  {
    type: 'list',
    name: 'todo',
    message: '你现在想要做什么?',
    choices: [
      'Eat food',
      'Buy a phone',
      new inquirer.Separator('----line----'),
      {
        name: 'Play game',
        disabled: 'cant available'
      },
      'Work'
    ],
    // 默认选中buy a phone这个选项
    default: 1
  },
  {
    type: 'list',
    name: 'brand',
    message: '请选择你需要购买的手机品牌',
    choices: [
      'Huawei',
      'Samsung',
      'Apple',
      'Xiaomi'
    ],
    // 筛选一下结果,将大写转换为小写
    filter(value) {
      return value.toLowerCase();
    }
  }
];

inquirer.prompt(questions).then((ans) => {
  console.log(ans);
});

输出结果如下:

6eL4JS.png

rawlist类型

跟list类型差不多,我目前看到的区别主要是rawlist可以显示序号,并且会在选项最后预览你当前选中的选项的序号。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message
  • choices

可选参数为:

  • default default必须是数组中的选择索引
  • filter
  • loop

由于跟list区别不大,这里就不单独展示代码和结果了

expand类型

提供一个指定key值的value选项。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message
  • choices

可选参数为:

  • default default必须是数组中的选择索引。如果没有提供默认键,那么help选项将被用作默认选择

注意:choices里面的选项列表里面的key值为必填项,并且必须是单个的小写字符,比如q,w,e这种小写字母,并且h是被inquirer默认的帮助选项占用了,不能用来定义。

示例代码如下:

const inquirer = require('inquirer');

let questions = [
  {
    type: 'expand',
    name: 'smart phone brand',
    message: '选择你的智能手机品牌',
    choices: [
      {
        key: 'a',
        name: 'Apple',
        value: 'apple'
      },
      {
        key: 's',
        name: 'Samsung',
        value: 'samsung'
      },
      {
        key: 'x',
        name: 'Xiaomi',
        value: 'xiaomi'
      }
    ],
    default: 2
  }
];

inquirer.prompt(questions).then((ans) => {
  console.log(ans);
});

输出结果如下:

6exaCV.png

6exN40.png

checkbox类型

checkbox可以提供多选功能。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message
  • choices 标记为{checked: true}的选项默认将被选中

choices中的disabled属性为true的选项将是不可选择的。如果disabled是一个字符串,那么这个字符串将输出到disabled选项旁边,否则它将默认为“disabled”。disabled属性也可以是一个同步函数,接收当前的答案作为参数,并返回一个布尔值或字符串

可选参数为:

  • default default应该是选中的选项值的数组
  • filter
  • validate
  • loop

示例代理如下:

const inquirer = require('inquirer');

let questions = [
  {
    type: 'checkbox',
    name: 'your select',
    message: '选择你喜欢的品牌',
    choices: [
      new inquirer.Separator('--- 国产品牌 ---'),
      {
        name: 'Huawei'
      },
      {
        name: 'Xiaomi'
      },
      {
        name: 'VIVO'
      },
      {
        name: 'OPPO'
      },
      new inquirer.Separator('--- 国外品牌 ---'),
      {
        name: 'Apple'
      },
      {
        name: 'Nokia',
        disabled: true
      },
      {
        name: 'Samsung'
      }
    ],
    validate(value) {
      if(value.length <= 0) {
        return '至少选择一项!'
      }
      return true;
    },
    loop: false,
    default: ['VIVO']
  }
];

inquirer.prompt(questions).then((ans) => {
  console.log(ans);
});

输出结果如下:

6miuZD.png

password类型

这个可以定义用户输入为密码类型。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message
  • mask 这个表示你想让用户的输入最终展示为什么样式,比如定义为*,那么用户的输入就全部显示星号

可选参数为:

  • default
  • filter
  • validate

示例代码如下:

const inquirer = require('inquirer');

let questions = [
  {
    type: 'password',
    name: 'password-1',
    message: '请输入密码:'
  },
  {
    type: 'password',
    name: 'password-2',
    message: '请输入密码:',
    mask: '&'
  }
];

inquirer.prompt(questions).then((ans) => {
  console.log(ans);
});

输出结果如下:

6mZOTf.png

editor类型

editor类型可以调用电脑的编辑器(windows为记事本)来编辑对应的文本并输出。question可用的参数组合如下:

必选参数为:

  • type
  • name
  • message

可选参数为:

  • default
  • filter
  • validate
  • postfix

示例代码参考官方文档:

var inquirer = require('inquirer');

var questions = [
  {
    type: 'editor',
    name: 'bio',
    message: 'Please write a short bio of at least 3 lines.',
    validate: function (text) {
      if (text.split('\n').length < 3) {
        return 'Must be at least 3 lines.';
      }

      return true;
    },
  },
];

inquirer.prompt(questions).then((answers) => {
  console.log(JSON.stringify(answers, null, '  '));
});