主题
常用交互式命令行用户界面的集合。
¥A collection of common interactive command line user interfaces.
在你自己的终端上尝试一下!
¥Give it a try in your own terminal!
sh
npx @inquirer/demo@latest安装
¥Installation
sh
npm install @inquirer/promptsInquirer 最近从头开始进行了重写,以减小包大小并提高性能。该包的先前版本仍在维护(尽管没有积极开发),并提供了数百个可能未迁移到最新 API 的社区贡献提示。如果这是你要找的,则使用 [上一个包在这里](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/inquirer)。
¥[!NOTE] Inquirer recently underwent a rewrite from the ground up to reduce the package size and improve performance. The previous version of the package is still maintained (though not actively developed), and offered hundreds of community contributed prompts that might not have been migrated to the latest API. If this is what you're looking for, the previous package is over here.
用法
¥Usage
js
import { input } from '@inquirer/prompts';
const answer = await input({ message: 'Enter your name' });提示
¥Prompts
输入
js
import { input } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
选择
js
import { select } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
复选框
js
import { checkbox } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
确认
js
import { confirm } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
搜索
js
import { search } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
密码
js
import { password } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
展开
js
import { expand } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
编辑器
在临时文件上启动用户首选编辑器的实例。一旦用户退出编辑器,临时文件的内容将被读取为答案。使用的编辑器通过读取 $VISUAL 或 $EDITOR 环境变量来确定。如果两者都不存在,则使用操作系统默认值(Windows 上的记事本,Mac 或 Linux 上的 vim。)
¥Launches an instance of the users preferred editor on a temporary file. Once the user exits their editor, the content of the temporary file is read as the answer. The editor used is determined by reading the $VISUAL or $EDITOR environment variables. If neither of those are present, the OS default is used (notepad on Windows, vim on Mac or Linux.)
js
import { editor } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
数字
与 input 提示非常相似,但具有内置的数字验证配置选项。
¥Very similar to the input prompt, but with built-in number validation configuration option.
js
import { number } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
原始列表
js
import { rawlist } from '@inquirer/prompts';查看文档 用于使用示例和选项文档。
¥See documentation for usage example and options documentation.
创建你自己的提示
¥Create your own prompts
¥The API documentation is over here, and our testing utilities here.
高级用法
¥Advanced usage
所有查询器提示都是一个带有 2 个参数的函数。第一个参数是提示配置(每个提示都是唯一的)。第二个是提供上下文或运行时配置。
¥All inquirer prompts are a function taking 2 arguments. The first argument is the prompt configuration (unique to each prompt). The second is providing contextual or runtime configuration.
上下文选项为:
¥The context options are:
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| input | NodeJS.ReadableStream | no | stdin 流(默认为 process.stdin) |
| output | NodeJS.WritableStream | no | stdout 流(默认为 process.stdout) |
| clearPromptOnDone | boolean | no | 如果为真,我们将在提示得到回答后清除屏幕 |
| signal | AbortSignal | no | 用于异步取消提示的 AbortSignal |
[!警告] 当提供输入流或管道
process.stdin时,很可能需要在调用查询函数之前调用process.stdin.setRawMode(true)。Node.js 通常会自动执行此操作,但当我们隐藏标准输入时,Node 可能会丢失跟踪,并且不知道必须这样做。如果提示符不是交互式的(箭头不起作用等),很可能是由于这个原因。¥[!WARNING] When providing an input stream or piping
process.stdin, it's very likely you need to callprocess.stdin.setRawMode(true)before calling inquirer functions. Node.js usually does it automatically, but when we shadow the stdin, Node can loss track and not know it has to. If the prompt isn't interactive (arrows don't work, etc), it's likely due to this.
示例:
¥Example:
js
import { confirm } from '@inquirer/prompts';
const allowEmail = await confirm(
{ message: 'Do you allow us to send you email?' },
{
output: new Stream.Writable({
write(chunk, _encoding, next) {
// Do something
next();
},
}),
clearPromptOnDone: true,
},
);取消提示
¥Canceling prompt
这可以通过 AbortController 或 AbortSignal 完成。
¥This can be done with either an AbortController or AbortSignal.
js
// Example 1: using built-in AbortSignal utilities
import { confirm } from '@inquirer/prompts';
const answer = await confirm({ ... }, { signal: AbortSignal.timeout(5000) });js
// Example 2: implementing custom cancellation with an AbortController
import { confirm } from '@inquirer/prompts';
const controller = new AbortController();
setTimeout(() => {
controller.abort(); // This will reject the promise
}, 5000);
const answer = await confirm({ ... }, { signal: controller.signal });秘诀
¥Recipes
优雅地处理 ctrl+c
¥Handling ctrl+c gracefully
当用户按 ctrl+c 退出提示时,Inquirer 会拒绝提示 promise。这是预期的行为,以便允许你的程序拆除/清理其环境。使用 async/await 时,被拒绝的 promise 会抛出错误。如果未处理,这些错误会在用户终端中打印其堆栈跟踪。
¥When a user press ctrl+c to exit a prompt, Inquirer rejects the prompt promise. This is the expected behavior in order to allow your program to teardown/cleanup its environment. When using async/await, rejected promises throw their error. When unhandled, those errors print their stack trace in your user's terminal.
ExitPromptError: User force closed the prompt with 0 null
at file://example/packages/core/dist/esm/lib/create-prompt.js:55:20
at Emitter.emit (file://example/node_modules/signal-exit/dist/mjs/index.js:67:19)
at #processEmit (file://example/node_modules/signal-exit/dist/mjs/index.js:236:27)
at #process.emit (file://example/node_modules/signal-exit/dist/mjs/index.js:187:37)
at process.callbackTrampoline (node:internal/async_hooks:130:17)这不是一个很好的用户体验,这就是为什么我们强烈建议你优雅地处理这些错误。
¥This isn't a great UX, which is why we highly recommend you to handle those errors gracefully.
第一个选项是将你的脚本封装在 try/catch 中;像 我们在演示程序中执行。或者在你的 CLI 框架机制中处理错误;例如 Clipanion catch 方法。
¥First option is to wrap your scripts in try/catch; like we do in our demo program. Or handle the error in your CLI framework mechanism; for example Clipanion catch method.
最后,你可以使用事件监听器全局处理错误并将其静音。
¥Lastly, you could handle the error globally with an event listener and silence it.
ts
process.on('uncaughtException', (error) => {
if (error instanceof Error && error.name === 'ExitPromptError') {
console.log('👋 until next time!');
} else {
// Rethrow unknown errors
throw error;
}
});在对象中获取答案
¥Get answers in an object
当问很多问题时,你可能不想在每个答案中都保留一个变量。在这种情况下,你可以将答案放在对象。
¥When asking many questions, you might not want to keep one variable per answer everywhere. In which case, you can put the answer inside an object.
js
import { input, confirm } from '@inquirer/prompts';
const answers = {
firstName: await input({ message: "What's your first name?" }),
allowEmail: await confirm({ message: 'Do you allow us to send you email?' }),
};
console.log(answers.firstName);有条件地提问
¥Ask a question conditionally
也许有些问题取决于其他问题的答案。
¥Maybe some questions depend on some other question's answer.
js
import { input, confirm } from '@inquirer/prompts';
const allowEmail = await confirm({ message: 'Do you allow us to send you email?' });
let email;
if (allowEmail) {
email = await input({ message: 'What is your email address' });
}超时后获取默认值
¥Get default value after timeout
js
import { input } from '@inquirer/prompts';
const answer = await input(
{ message: 'Enter a value (timing out in 5 seconds)' },
{ signal: AbortSignal.timeout(5000) },
).catch((error) => {
if (error.name === 'AbortPromptError') {
return 'Default value';
}
throw error;
});用作预提交/git 钩子或脚本
¥Using as pre-commit/git hooks, or scripts
默认情况下,从 husky/lint-staged 等工具运行的脚本可能无法在交互式 shell 中运行。在非交互式 shell 中,Inquirer 无法运行,用户无法向进程发送按键事件。
¥By default scripts ran from tools like husky/lint-staged might not run inside an interactive shell. In non-interactive shell, Inquirer cannot run, and users cannot send keypress events to the process.
为了使其工作,你必须确保启动 tty(或 "interactive" 输入流)。
¥For it to work, you must make sure you start a tty (or "interactive" input stream.)
如果这些脚本在你的 package.json 中设置,你可以像这样定义流:
¥If those scripts are set within your package.json, you can define the stream like so:
json
"precommit": "my-script < /dev/tty"或者如果在 shell 脚本文件中,你可以这样做:(在 Windows 上,这可能是你唯一的选择)
¥Or if in a shell script file, you'll do it like so: (on Windows that's likely your only option)
sh
#!/bin/sh
exec < /dev/tty
node my-script.js与 nodemon 一起使用
¥Using with nodemon
当将 inquirer 提示与 nodemon 一起使用时,你需要传递 --no-stdin 标志才能使一切按预期工作。
¥When using inquirer prompts with nodemon, you need to pass the --no-stdin flag for everything to work as expected.
sh
npx nodemon ./packages/demo/demos/password.mjs --no-stdin请注意,对于大多数人来说,你将能够使用 Node 内置的新监视模式。此模式可与 inquirer 一起开箱即用。
¥Note that for most of you, you'll be able to use the new watch-mode built-in Node. This mode works out of the box with inquirer.
sh
## One of depending on your need
node --watch script.js
node --watch-path=packages/ packages/demo/等待配置
¥Wait for config
也许某些问题配置需要等待一个值。
¥Maybe some question configuration require to await a value.
js
import { confirm } from '@inquirer/prompts';
const answer = await confirm({ message: await getMessage() });在 Bash 脚本中与 npx 结合使用
¥Usage with npx within bash scripts
你可以通过 npx 直接在 shell 中使用 Inquirer 提示符,这对于快速脚本或 package.json 命令非常有用。
¥You can use Inquirer prompts directly in the shell via npx, which is useful for quick scripts or package.json commands.
@inquirer-cli 是一个社区库,它将每个提示都公开为独立的 CLI。
¥A community library, @inquirer-cli, exposes each prompt as a standalone CLI.
例如,提示输入:
¥For example, to prompt for input:
bash
name=$(npx -y @inquirer-cli/input -r "What is your name?")
echo "Hello, $name!"或者创建交互式版本的 bump:
¥Or to create an interactive version bump:
bash
$ npm version $(npx -y @inquirer-cli/select -c patch -c minor -c major 'Select Version')了解更多信息:@inquirer-cli。
¥Find out more: @inquirer-cli.
社区提示
¥Community prompts
如果你创建了一个很酷的提示,请将 向我们发送 PR 将其添加 添加到下面的列表中!
¥If you created a cool prompt, send us a PR adding it to the list below!
交互式列表提示
使用箭头键 + Enter 或按与选项关联的键选择一个选项。
¥Interactive List Prompt
Select a choice either with arrow keys + Enter or by pressing a key associated with a choice.
? Choose an option:
> Run command (D)
Quit (Q)操作选择提示
从列表中选择一个项目,然后按下一个键选择要执行的操作。
¥Action Select Prompt
Choose an item from a list and choose an action to take by pressing a key.
? Choose a file Open <O> Edit <E> Delete <X>
❯ image.png
audio.mp3
code.py表格多选提示
从表格显示中选择多个答案。
¥Table Multiple Prompt
Select multiple answer from a table display.
sh
Choose between choices? (Press <space> to select, <Up and Down> to move rows,
<Left and Right> to move columns)
┌──────────┬───────┬───────┐
│ 1-2 of 2 │ Yes? │ No? |
├──────────┼───────┼───────┤
│ Choice 1 │ [ ◯ ] │ ◯ |
├──────────┼───────┼───────┤
│ Choice 2 │ ◯ │ ◯ |
└──────────┴───────┴───────┘切换提示
使用切换确认。使用箭头键 + Enter 选择一个选项。
¥Toggle Prompt
Confirm with a toggle. Select a choice with arrow keys + Enter.
? Do you want to continue? no / yes可排序复选框提示
与内置复选框提示相同,但也允许使用 ctrl+up/down 重新排序选项。
¥Sortable Checkbox Prompt
The same as built-in checkbox prompt, but also allowing to reorder choices using ctrl+up/down.
? Which PRs and in what order would you like to merge? (Press <space> to select, <a> to toggle all, <i> to invert selection, <ctrl+up> to move item up, <ctrl+down> to move item down, and <enter> to proceed)
❯ ◯ PR 1
◯ PR 2
◯ PR 3支持多项选择和过滤/搜索的查询器选择。
¥An inquirer select that supports multiple selections and filtering/searching.
? Choose your OS, IDE, PL, etc. (Press <tab> to select/deselect, <backspace> to remove selected
option, <enter> to select option)
>> vue
>[ ] vue
[ ] vuejs
[ ] fuelphp
[ ] venv
[ ] vercel
(Use arrow keys to reveal more options)文件选择器提示
文件选择器,你可以在目录之间自由导航,选择要允许的文件类型,并且它是完全可定制的。
¥File Selector Prompt
A file selector, you can navigate freely between directories, choose what type of files you want to allow and it is fully customizable.
sh
? Select a file:
/main/path/
├── folder1/
├── folder2/
├── folder3/
├── file1.txt
├── file2.pdf
└── file3.jpg (not allowed)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Use ↑↓ to navigate through the list
Press <esc> to navigate to the parent directory
Press <enter> to select a file or navigate to a directory带有状态横幅的选择提示
与内置 select 提示符相同,但它还会在提示符上方显示一个横幅,可以使用 setState 函数进行更新。例如,它可以显示长时间运行的命令的结果,而无需用户等待查看提示。
¥Select Prompt with Stateful Banner
The same as built-in select prompt, but it also displays a banner above the prompt which can be updated with a setState function. For example, it can display the results of a long-running command without making the user wait to see the prompt.
初始展示:
¥Initial display:
Directory size: loading...
? Choose an option
❯ Rename
Copy
Delete稍后:
¥A moment later:
Directory size: 123M
? Choose an option
❯ Rename
Copy
Delete有序复选框提示
可排序的复选框提示,可保持选择顺序。非常适合确定任务优先级或对选项进行排序。
¥Ordered Checkbox Prompt
A sortable checkbox prompt that maintains the order of selection. Perfect for prioritizing tasks or ranking options.
? Configure your development workflow:
[1] Set up CI/CD pipeline
❯ [3] Code quality tools
[ ] Documentation
[2] Performance monitoring
──────────────
- Legacy system (disabled)
(Linting, formatting, and analysis)复选框+提示符
一个现代化的多选复选框提示符,具有搜索和过滤功能、高亮、自动补齐和改进的用户体验。支持 ESM 和 CommonJS,并与 @inquirer/core v10+ 兼容。
¥Checkbox Plus Plus Prompt
A modern multiselect checkbox prompt with search and filter capabilities, highlighting, autocomplete, and improved UX. Supports both ESM and CommonJS and is compatible with @inquirer/core v10+.
? Select colors [searching: "re"]
❯ ◉ The red color
◯ The green color
◉ The purple color
◯ The orange color
↑↓ navigate • space de/select • type search • 2 selected • ⏎ submit许可证
¥License
版权所有 (c) 2023 Simon Boudrias (推特:@vaxilart)
根据 MIT 许可证授权。
¥Copyright (c) 2023 Simon Boudrias (twitter: @vaxilart)
Licensed under the MIT license.
