inquirer.js_如何使用Inquirer.js

inquirer.js

In this article I want to talk about a CLI tool that I really enjoy using, and hopefully someone learns something along the way.

在本文中,我想谈一谈我非常喜欢使用的CLI工具,并希望有人在学习过程中学到一些东西。

让我们从头开始:问询者是什么? (Let’s start at the beginning: What is Inquirer?)

Inquirer is a promise-based npm package used in Node projects to create CLI (Command Line Interface) tools for query-based tasks. It’s great for asking the user questions, validating user inputs, and doing stuff with the responses given.

Inquirer是基于诺言的npm软件包,用于Node项目中,以创建用于基于查询的任务的CLI(命令行界面)工具。 询问用户问题,验证用户输入并根据给定的响应进行操作非常好。

I have used Inquirer, alongside a mysql database, to create a CLI tool called the ‘employee manager’. It asks the user what they would like to do, and gives them a list of options. They can add new staff, assign roles, departments, and offices, set salaries, and so much more — all without having to create a front-end.

我已经使用Inquirer和mysql数据库一起创建了一个称为“员工管理器”的CLI工具。 它询问用户他们想做什么,并为他们提供选项列表。 他们可以添加新员工,分配角色,部门和办公室,设置工资等等,而所有这些都无需创建前端。

什么是节点? (What’s Node?)

Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine. For more information on what Node is and how to set it up, click here. You’ll need Node before you can use Inquirer.

Node.js是基于Chrome的V8 JavaScript引擎构建JavaScript运行时。 有关什么是节点以及如何进行设置的更多信息, 请单击此处 。 您需要先使用Node,然后才能使用Inquirer。

那么如何使用Inquirer? (So how do I use Inquirer?)

Glad you asked! For the sake of this article, we’re going to build up a simple Inquirer-based project, starting at the very beginning and working all the way to so more in-depth stuff. Their documentation (link at the bottom) has all the info you’ll need to get set up, but let’s cover it here too.

很高兴你问! 为了本文的目的,我们将建立一个简单的基于Inquirer的项目,从头开始,一直进行到更深入的研究。 他们的文档(底部的链接)提供了设置所需的所有信息,但我们也将在此处进行介绍。

If you haven’t done so already, initialize npm in your project by typing the following into your terminal at the root directory of your project:

如果尚未执行此操作,请在项目的根目录下的终端中键入以下内容,以初始化项目中的npm:

npm init -y

Now you’re ready to install Inquirer. Type the following into your terminal:

现在,您可以安装Inquirer了。 在您的终端中输入以下内容:

npm install inquirer

The next step involves bringing the Inquirer library into the file you’re working on. You can do that by adding the following line to the start of your code:

下一步涉及将Inquirer库带到您正在处理的文件中。 您可以通过在代码开头添加以下行来实现:

const inquirer = require("inquirer")

So now that we’ve brought inquirer into our project, let’s build our first inquiry and run it. Every inquiry starts with the same code:

因此,既然我们已经将询价人引入了我们的项目,那么让我们构建第一个询价并运行它。 每个查询都以相同的代码开头:

inquirer.prompt()

So we access the inquirer library and use the prompt method to display our question to the user. But it’s more complicated than that — inquirer takes an array of objects for its questions. So we open an array inside the parentheses, and then an object inside of that array, to give us something like this:

因此,我们访问查询者库并使用提示方法向用户显示问题。 但这比这更复杂-查询者需要一系列对象来解决问题。 因此,我们在括号内打开一个数组,然后在该数组内打开一个对象,以得到如下所示的内容:

inquirer.prompt([{}])

Each question object should consist of at least three keys:

每个问题对象应至少包含三个键:

  • name - how you refer to the question (and the answer given) later on

    名称-稍后您如何提及问题(以及给出的答案)
  • type - what type of question is this? (input, multiple choice, numerical etc)

    类型-这是什么类型的问题? (输入,多项选择,数字等)
  • message - the question you’re asking the user

    消息-您要问用户的问题

Using this new knowledge, we can create a basic question that looks something like this:

利用这些新知识,我们可以创建一个基本问题,如下所示:

inquirer
.prompt([
{
name: "user_name",
type: "input",
message: "What is your name?",
},
]);

It’s important to note that the default option for ‘type’ is ‘input’ and therefore isn’t actually necessary in this scenario, but I like to include it for the sake of clarity.

重要的是要注意,“类型”的默认选项是“输入”,因此在这种情况下实际上并不是必需的,但是为了清楚起见,我希望将其包括在内。

But we’re not done yet, we’ve asked the question but we’re not doing anything with the answer. The answer is given back to us as an object where the key is the ‘name’ property of the question, and the answer is its value. You can access the answer using .then() with a callback function inside. Let’s say we want to print the answer to this question to the console, we could use the following code:

但是我们还没有完成,我们已经提出了问题,但是我们对答案没有做任何事情。 答案作为对象返回给我们,其中键是问题的“名称”属性,而答案是其值。 您可以使用.then()和内部的回调函数来访问答案。 假设我们要将此问题的答案打印到控制台,我们可以使用以下代码:

inquirer
.prompt([
{
name: "user_name",
type: "input",
message: "What is your name?",
},
])
.then((answer) => {
console.log("Hello " + answer.user_name);
});

Congratulations, you just wrote your first inquiry using Inquirer.js. To run this question, type the following into your console:

恭喜,您刚刚使用Inquirer.js编写了第一个查询。 要运行此问题,请在控制台中键入以下内容:

node <filename>

For the purpose of this article, I wrote my own file to demonstrate.

出于本文的目的,我编写了自己的文件进行演示。

让我们更进一步 (Let’s take it a step further)

So we’ve asked a question, how do we ask multiple questions? It’s as easy as adding another question object to the array. In the following example, I have added on to the code we wrote earlier, with a few small modifications, to ask the user for their first and last names:

所以我们问了一个问题,我们怎么问多个问题? 就像将另一个问题对象添加到数组一样容易。 在下面的示例中,我添加了我们先前编写的代码,并进行了一些小的修改,以询问用户的名字和姓氏:

inquirer
.prompt([
{
name: "first_name",
type: "input",
message: "What is your first name?",
},
{
name: "last_name",
type: "input",
message: "What is your last name?",
},
])
.then((answer) => {
console.log("Hello", answer.first_name, answer.last_name);
});

问题类型 (Types of questions)

So we’ve learned to add input-based questions. What if we want the user to select from a range of possible options? All we need to do is change the ‘type’ field of the question. Inquirer offers many types for your questions, the most common ones I use are:

因此,我们学会了添加基于输入的问题。 如果我们希望用户从一系列可能的选项中进行选择怎么办? 我们需要做的就是更改问题的“类型”字段。 询问者为您的问题提供多种类型,我最常用的类型是:

  • Input

    输入项
  • Number

  • Confirm

    确认
  • List

    清单
  • Checkbox

    选框
  • Password

    密码

We’ve already seen some input type questions, so let’s see what we can do with the other types.

我们已经看到了一些输入类型的问题,所以让我们看看我们可以使用其他类型的问题。

类型:数字 (type: number)

The following is an example of a question that uses a number and prints the result to the console.

以下是使用数字并将结果打印到控制台的问题示例。

inquirer
.prompt([
{
name: "pet_count",
type: "number",
message: "How many pets do you own?",
},
])
.then((answer) => {
console.log("You own", answer.pet_count, "pets");
});

It comes with some built-in validation that returns ‘NaN’ if you try to enter something that isn’t a number (e.g. “eight”). We can use this to our advantage and build in a conditional that asks the question again if you didn’t give a number by making the question into a function like so:

它带有一些内置的验证,如果您尝试输入非数字的内容(例如“八”),则返回“ NaN”。 我们可以利用它来发挥我们的优势,并通过将问题变成类似这样的函数,来构建一个条件,该条件再次询问问题,如果您没有给出数字:

const getPetCount = () => {
inquirer
.prompt([
{
name: "pet_count",
type: "number",
message: "How many pets do you own?",
},
])
.then((answer) => {
if (!answer.pet_count) {
console.log("That wasn't a number!");
getPetCount();
} else {
console.log("You own", answer.pet_count, "pets");
});
};getPetCount();

What we did was turn the question into a re-usable function, and call the question again if the answer comes back as false. Note that, since the question function is not immediately invoked, we need to actually call the function below where we declared it.

我们所做的是将问题转换为可重用的函数,如果答案返回为假,则再次调用该问题。 请注意,由于问题函数不会立即被调用,因此我们实际上需要在声明它的位置下面调用该函数。

类型:确认 (type: confirm)

Confirm gives the user a simple yes or no option and returns a boolean value as the answer. The following code is an example of how to use the confirm type:

确认为用户提供了简单的是或否选项,并返回布尔值作为答案。 以下代码是如何使用确认类型的示例:

inquirer
.prompt([
{
name: "wants_pizza",
type: "confirm",
message: "Do you want a free pizza?",
},
])
.then((answer) => {
console.log(answer.wants_pizza);
});

The user is presented with the question:

向用户提出以下问题:

Do you want a free pizza? (Y/n)

您要免费的披萨吗? (是/否)

A simple Y or N will give you ‘true’ or ‘false’. You could use this to build up a series of questions, all saved as functions, to make a pizza order builder. You do want a pizza? How many pizzas do you want? What address should we deliver the pizzas to? That’s a series of questions using confirm, number, and input question types. But what crust should the pizza have?

简单的Y或N将为您提供“ true”或“ false”。 您可以使用它来构建一系列问题,并将其全部保存为函数,以构建比萨饼订单构建器。 你要披萨吗? 您要多少个披萨? 我们应该将披萨运送到哪个地址? 这是使用确认,编号和输入问题类型的一系列问题。 但是比萨饼应该有什么外壳?

类型:清单 (type: list)

The list type requires you to add an additional key to your question object: a choices array. This will present the user with a list of options to pick from and save their submission as the answer to the question. This type completely prevents the user from entering their own inputs and restricts their choices to your pre-defined list. Here’s an example:

列表类型要求您向问题对象添加一个附加键:choices数组。 这将为用户提供一个选项列表,供用户选择并保存其提交内容作为问题的答案。 此类型完全阻止用户输入自己的输入,并将他们的选择限制在您的预定义列表中。 这是一个例子:

inquirer
.prompt([
{
name: "pizza_crust",
type: "list",
message: "Choose your crust:",
choices: ["Thin Crust", "Stuffed Crust", "Pan"],
},
])
.then((answer) => {
console.log(answer.pizza_crust);
});

The user will be able to pick their crust type from the list and their choice will be printed to the console. If we stick with the pizza order builder idea, let’s say you defined an ‘order’ object at the start of the document, with keys for an address, a crust, number of pizzas, etc.. you could be pushing the values from these answers to that object, then move on to the next question. So what if we want to select multiple options from a list — pizza toppings, for example?

用户将能够从列表中选择他们的外壳类型,并且他们的选择将被打印到控制台。 如果我们坚持披萨订单构建器的想法,假设您在文档的开头定义了一个“订单”对象,并提供了地址,外壳,披萨数量等的键。则可以从这些值中推送值该对象的答案,然后继续下一个问题。 那么,如果我们想从列表中选择多个选项(例如披萨馅料)怎么办?

类型:复选框 (type: checkbox)

Checkbox works similarly to a list, in that you have to provide a choices array, except the user can select multiple options. This would be a great way to select pizza toppings. Here’s an example:

Checkbox与列表类似,除了用户可以选择多个选项外,还必须提供一个options数组。 这将是选择披萨馅料的好方法。 这是一个例子:

const toppingArray = ["Cheese", "Pepperoni", "Onions", "Peppers", "Jalapeños", "Chicken"]inquirer
.prompt([
{
name: "pizza_toppings",
type: "checkbox",
message: "Choose your toppings:",
choices: toppingArray,
},
])
.then((answer) => {
console.log(answer.pizza_toppings);
});

The user will be given the question “Choose your toppings:” and then be presented with a list of options, which, in this example, I defined previously in a variable. The user can use space to select/deselect options, and press enter to submit their answer. Once answered, the answers are saved as strings in an array. An answer to this question might look like this:

将为用户提供“选择浇头:”问题,然后为用户提供选项列表,在此示例中,我之前在变量中定义了这些选项。 用户可以使用空格选择/取消选择选项,然后按Enter提交答案。 回答后,答案将以字符串形式保存在数组中。 这个问题的答案可能看起来像这样:

["Cheese", "Onions", "Peppers", "Chicken"]

Interesting idea, you can save these answers to a variable and use them again later in another ‘list’ or ‘checkbox’ style question.

有趣的想法是,您可以将这些答案保存到变量中,并稍后在另一个“列表”或“复选框”样式的问题中再次使用它们。

类型:密码 (type: password)

This example doesn’t really fit in to the pizza order builder example, but it’s an important one to cover. The password type will hide the user input completely. No asterisks or blanked out characters, you will see absolutely nothing as you type. This is incredibly useful, though, as anyone looking over your shoulder can’t even see how long your password is! Here’s an example:

这个示例并不真正适合比萨订单构建器示例,但是它是一个很重要的示例。 密码类型将完全隐藏用户输入。 没有星号或空白字符,键入时绝对看不到任何内容。 但是,这非常有用,因为任何人都看不到您的密码了! 这是一个例子:

inquirer
.prompt([
{
name: "user_password",
type: "password",
message: "Enter Password:",
},
])
.then((answer) => {
console.log(answer.user_password);
});

Obviously, you don’t want to print the sensitive information you just typed directly into the console, but doing this initially is a great way to test that it worked. A better solution in a finished product may be to save the password to a variable or immediately submit it along with a username to log someone into a service.

显然,您不想直接将刚刚输入的敏感信息打印到控制台中,但是最初进行此操作是测试其是否有效的好方法。 成品中更好的解决方案可能是将密码保存到变量中,或者立即将其与用户名一起提交以使某人登录服务。

想建立一个披萨订单生成器吗? (Want to build a pizza order builder?)

That’s awesome. I’ve created a super simple example and uploaded it to GitHub, feel free to clone the repo and see how everything works!

棒极了。 我创建了一个超级简单的示例,并将其上传到GitHub ,随时克隆存储库并查看一切工作原理!

那么查询者还能做什么呢? (So what else can inquirer do?)

One of my favorite features in Inquirer, from before I learned I could separate all my questions into functions, is ‘when’. In a more complex scenario than the pizza order builder, you might want to add a follow-up question that only gets asked if the user selected a certain answer from a previous question. Here’s an example of how to use ‘when’:

在我了解将所有问题分解为功能之前,Inquirer中最喜欢的功能之一就是“何时”。 在比比萨饼订单构建器更复杂的场景中,您可能想要添加一个后续问题,该问题仅在用户是否从上一个问题中选择了某个答案时才被询问。 这是如何使用“时间”的示例:

inquirer
.prompt([
{
name: "wants_pizza",
type: "confirm",
message: "Do you want a free pizza?",
},
{
name: "confirm_answer",
type: "confirm",
message: "Are you sure?",
when: (answers) => answers.wants_pizza === false,
},
])
.then((answers) => {
if (answers.wants_pizza) {
console.log("The user wants free pizza");
} else if (answers.confirm_answer) {
// the user definitely doesn't want pizza
} else {
// the user changed their mind
// run the function to ask this question again
}
});

So we can see that the ‘when’ property is actually using a callback function with a basic conditional. If the answer was false, then ask if the user is sure. In the .then() block, we use a conditional to see:

因此,我们可以看到'when'属性实际上是在使用带有基本条件的回调函数。 如果答案是否定的,请询问用户是否确定。 在.then()块中,我们使用条件查看:

  • If the first question was answered as ‘true’, do something.

    如果第一个问题被回答为“是”,请执行一些操作。
  • If the first answer was not true, if the second answer was true, the user definitely doesn’t want pizza, run some kind of exit function here

    如果第一个答案正确,如果第二个答案正确,那么用户肯定不想要披萨,请在此处运行某种退出功能

  • else the user said they didn’t want pizza, then changed their mind, so they should be redirected to the initial question

    否则用户说他们不想吃披萨,然后改变了主意,因此应将其重定向到最初的问题

It’s important to note that if the user says they do want a free pizza, they don’t get asked if they are sure — this is the power of ‘when’. By using ‘when’, we can ask a question only when a given criteria is met, and skip it otherwise.

重要的是要注意,如果用户说他们确实想要免费的披萨,那么他们不会被问到是否确定,这就是“何时”的力量。 通过使用“何时”,我们可以仅在满足给定条件时提出问题,否则跳过该问题。

那么我应该将查询分为功能,还是使用“何时”? (So should I split my inquiries up into functions, or use ‘when’?)

In my opinion, both have their use cases. Splitting things up into functions is great for making reusable questions, but the answers to those questions are confined to the scope of their .then() blocks unless you save them to a variable outside of that scope. In the case of the pizza order builder, this was fine since each question contributed a value to an object.

我认为,两者都有用例。 将事物分解为函数对于提出可重用的问题非常有用,但是这些问题的答案仅限于它们的.then()块的范围,除非您将它们保存到该范围之外的变量中。 对于比萨饼订单生成器,这很好,因为每个问题都为对象贡献了价值。

The pizza order builder could just as easily have been two functions — one to display the start menu, and one that contains every follow-up question after that, since we always ask every question in that list.

比萨订单构建器可以很容易地具有两个功能-一个显示开始菜单,一个包含之后的每个后续问题,因为我们总是询问该列表中的每个问题。

One argument for using the ‘when’ feature is that it can save on the number of lines of code written and make your files a little shorter; you don’t need to write a whole inquirer.prompt() block, and then have a conditional to either send you to that question, or to the next question. Another benefit is that by asking questions in this way, you don’t lose the answer to the question that took you to that point by changing scope.

使用“何时”功能的一个论据是,它可以节省编写的代码行数,并使文件更短一些。 您不需要编写整个inquirer.prompt()块,然后有条件将您发送到该问题或下一个问题。 另一个好处是,通过以这种方式提出问题,您不会因改变范围而失去对这一问题的答案。

默认值 (Default Values)

Inquirer allows you to add default values to your inquiries, to speed up navigation and make suggestions to the user. Here’s an example of how it might be used:

Inquirer允许您向查询中添加默认值,以加快导航速度并向用户提出建议。 这是如何使用它的示例:

const mediaArray = ["Facebook", "Wikipedia", "Medium"];inquirer
.prompt([
{
name: "fav_media",
type: "list",
message: "What is your favorite source for info?",
choices: mediaArray,
default: "Medium",
},
])
.then((answer) => {
console.log(answer.fav_media);
});

Now, when the user is asked for their favorite source of info, the selected option will be the third option — “Medium”.

现在,当询问用户最喜欢的信息源时,所选选项将是第三个选项-“中”。

example of what functionality the default option gives us
How the inquiry begins when you use a ‘default’ option
使用“默认”选项时查询如何开始

This can be very useful if you’re trying to implement CRUD functionality into your project, specifically the Update part. You can pull the existing value into a variable or function argument, and use that as the default value.

如果您要在项目中实现CRUD功能(特别是Update部分),这将非常有用。 您可以将现有值放入变量或函数参数中,并将其用作默认值。

更多信息 (More Information)

  • If you want to learn more in-depth features in Inquirer.js, you can view the official docs on npm here.

    如果您想了解在Inquirer.js更深入的功能,你可以在故宫查看官方文档在这里

信用到期 (Credit where it’s due)

  • Thank you to Squirrel for their article on how to add code blocks to Medium articles. This thing looked a mess before I found that article.

    感谢Squirrel撰写的有关如何在中型文章中添加代码块的文章。 在我找到那篇文章之前,这东西看起来一团糟

  • Thank you to Thomas W. Smith for teaching me all of this (and so much more) in the first place, and for proof-reading this article.

    感谢托马斯·史密斯 ( Thomas W. Smith)首先教给我所有这些(以及更多),并感谢您阅读本文。

翻译自: https://medium.com/javascript-in-plain-english/how-to-inquirer-js-c10a4e05ef1f

inquirer.js

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值