💬 打造丝滑交互体验:用 prompts 优化你的 CLI 工具(gix 实战)
在前几篇文章中,我们一步步构建了 gix CLI 工具,完成了常用命令如 squash 和 merge 的实现。
这一篇,我们来聊聊"体验"。
一个真正好用的 CLI 工具,不只是功能能跑通,更重要的是:它用起来是不是丝滑、清晰、让人舒服。
所以今天的主题是:如何用 prompts 打造更人性化的交互体验。
✅ 为什么选 prompts?
我们常用的 CLI 交互库有几个:
库名 | 特点 |
---|---|
inquirer | 功能强大,但体积大、启动慢 |
enquirer | 快速 + 样式好看,但文档偏少 |
✅ prompts | 轻量 + 类型支持好 + async 友好 |
对于我们这种日常工具型 CLI,prompts 是性能和体验的最佳平衡点。****
✨ 实现几个交互小优化
🧩 1. 根据已有参数决定是否弹出输入框
比如 merge 命令中,我们允许用户用 -f/-t/-m 传参,但如果没传,就自动用 prompts 提示。
php
if (!opts.message) {
const { msg } = await prompts({
type: 'text',
name: 'msg',
message: '请输入新的 commit message:'
})
opts.message = msg
}
✅ 效果:
- 传了就自动执行
- 没传就弹出提示框,智能兜底
🧩 2. 添加默认值和校验逻辑
css
{
type: 'text',
name: 'from',
message: '请输入起始 commit(hash 或 HEAD~n)',
initial: 'HEAD~2',
validate: (val) => val.trim() !== '' || '不能留空'
}
🧩 3. 多步问题组合(使用 prompts 数组)
php
const response = await prompts([
{
type: 'text',
name: 'from',
message: '起始 commit(默认 HEAD~2)',
initial: 'HEAD~2',
},
{
type: 'text',
name: 'to',
message: '结束 commit(默认 HEAD)',
initial: 'HEAD'
}
])
🧩 4. 选择列表:让用户「选」而不是「输」
比如你可以用 git log 的结果渲染一个下拉框,让用户选择要 squash 的 commit 数量:
css
{
type: 'select',
name: 'count',
message: '要合并几次提交?',
choices: [
{ title: '2 次(推荐)', value: 2 },
{ title: '3 次', value: 3 },
{ title: '5 次', value: 5 },
{ title: '全部', value: -1 }
]
}
🪄 高级体验优化技巧
🎨 使用 chalk 提升输出样式
javascript
import chalk from 'chalk'
console.log(chalk.green('🎉 squash 完成!'))
console.log(chalk.yellow('⚠️ 即将执行强推操作'))
console.log(chalk.redBright('❌ 出错了'))
搭配 emoji,终端输出会更有亲和力。
💻 exec 命令输出更流畅
支持静默执行:
csharp
await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
stdio: opts.silent ? 'pipe' : 'inherit'
})
✅ 确认提示(confirm)
bash
{
type: 'confirm',
name: 'confirmPush',
message: '是否要立即推送?',
initial: true
}
让关键操作(如 push --force)更安全。
📦 推荐封装思路:统一 Prompt 层
你可以新建一个 src/ui/prompt.ts 文件,将所有交互都封装成函数:
php
export async function askCommitMessage() {
const { msg } = await prompts({
type: 'text',
name: 'msg',
message: '请输入新的 commit message'
})
return msg
}
export async function askConfirmForcePush() {
const { yes } = await prompts({
type: 'confirm',
name: 'yes',
message: '是否使用 --force 推送?',
initial: false
})
return yes
}
后续命令调用时非常清晰:
csharp
const msg = await askCommitMessage()
const yes = await askConfirmForcePush()
📈 未来可扩展功能
结合 prompts,我们还能做很多:
场景 | 交互方式 |
---|---|
自动生成 changelog | 选择范围 + 类型 + 确认 |
选择分支 rebase | select 分支列表 |
修改历史 message | 多步 wizard |
🔚 小结
这篇文章我们学了:
-
如何让 CLI 工具更"人性化"
-
prompts 的最佳实践与组合技巧
-
提升用户体验的细节打磨
一个工具如果能"看着舒服、用着舒服",用户才更愿意用它。别让你辛辛苦苦写的 CLI 工具因为体验差被放弃。
🧩 项目地址
欢迎来提需求、提 PR 或 star 支持 ✨
🔮 下一篇预告
下一篇我们聊聊如何让你的 CLI 工具"发布"出圈:
-
如何发布到 npm
-
如何写 bin 配置
-
如何自动注入版本号
-
如何用 CI/CD 实现一键发布
别忘了点赞 + 收藏 + 评论支持我继续写下去~