@clack/prompts 命令行终端中构建交互式用户界面

@clack/prompts

概述

@clack/prompts 是一个轻量、美观且开发者友好的Node.js库,用于在命令行终端中构建交互式用户界面。它提供了一系列样式现代的提示组件,支持异步操作,并包含完整的类型定义(TypeScript),能够显著提升命令行工具的用户体验。

安装

使用npm或yarn进行安装:

bash 复制代码
# 使用 npm
npm install @clack/prompts

# 使用 yarn
yarn add @clack/prompts

# 使用 pnpm
pnpm add @clack/prompts

基础使用模式

每个使用@clack/prompts的CLI工具通常遵循以下模式:

javascript 复制代码
// 1. 引入必要的函数
import { intro, outro, confirm, isCancel } from '@clack/prompts';

// 2. 显示欢迎信息
intro('欢迎使用我的CLI工具');

// 3. 执行交互逻辑
const shouldContinue = await confirm({
  message: '是否继续执行?'
});

// 4. 处理用户取消操作
if (isCancel(shouldContinue)) {
  cancel('操作已取消');
  process.exit(0);
}

// 5. 显示结束信息
outro('任务已完成!');

核心组件详解

1. 文本输入 (text)

用于获取用户单行文本输入。

参数说明:

  • message: 显示给用户的提示信息
  • placeholder: 输入框内的占位符文本
  • defaultValue: 默认值
  • validate: 验证函数,返回字符串表示验证失败
javascript 复制代码
import { text } from '@clack/prompts';

const name = await text({
  message: '请输入项目名称',
  placeholder: 'my-awesome-project',
  defaultValue: 'default-project',
  validate: (value) => {
  	// 如果有默认值,直接判断vlaue.length == 0 return undefined
    if (value.length < 3) return '名称至少需要3个字符';
    if (!/^[a-z\-]+$/.test(value)) return '只能包含小写字母和连字符';
  }
});
2. 确认选择 (confirm)

获取布尔值的是/否回答。

javascript 复制代码
import { confirm } from '@clack/prompts';

const isReady = await confirm({
  message: '是否确认删除?',
  initialValue: true // 默认选中"是"
});
3. 单选列表 (select)

让用户从选项列表中选择一个值。

选项配置:

  • value: 选项的实际值
  • label: 显示给用户的文本
  • hint: 额外的提示信息(可选)
javascript 复制代码
import { select } from '@clack/prompts';

const framework = await select({
  message: '请选择前端框架',
  options: [
    { value: 'react', label: 'React', hint: 'Facebook开发' },
    { value: 'vue', label: 'Vue.js', hint: '渐进式框架' },
    { value: 'angular', label: 'Angular', hint: 'Google开发' },
    { value: 'svelte', label: 'Svelte' }
  ],
  initialValue: 'vue' // 默认选中Vue
});
4. 多选列表 (multiselect)

允许用户选择多个选项。

javascript 复制代码
import { multiselect } from '@clack/prompts';

const features = await multiselect({
  message: '选择要添加的功能',
  options: [
    { value: 'typescript', label: 'TypeScript', hint: '类型安全' },
    { value: 'eslint', label: 'ESLint', hint: '代码检查' },
    { value: 'prettier', label: 'Prettier', hint: '代码格式化' },
    { value: 'tests', label: '测试框架' }
  ],
  required: false, // 是否至少选择一项
  initialValues: ['typescript', 'eslint'] // 默认选中的值
});
5. 密码输入 (password)

输入内容会被隐藏,适用于敏感信息。

javascript 复制代码
import { password } from '@clack/prompts';

const secretKey = await password({
  message: '请输入API密钥',
  mask: '•' // 自定义掩码字符
});
6. 进度指示器

显示长时间操作的进度。

javascript 复制代码
import { progress } from '@clack/prompts';

// 创建进度条实例
const p = progress(0, 100, '处理中...');

// 更新进度
p.update(30, '正在下载文件...');
p.update(60, '正在处理数据...');
p.update(100, '完成!');

// 或使用静态方法
progress(30, 100, '第一阶段完成');

高级功能

1. 处理取消操作

所有提示函数都可能被用户通过Ctrl+C取消,必须妥善处理:

javascript 复制代码
import { text, isCancel, cancel } from '@clack/prompts';

try {
  const answer = await text({
    message: '请输入内容'
  });
  
  if (isCancel(answer)) {
    cancel('用户取消了操作');
    process.exit(0);
  }
  
  console.log(`用户输入: ${answer}`);
} catch (error) {
  cancel('发生错误: ' + error.message);
}
2. 自定义样式和主题

通过配置对象自定义外观:

javascript 复制代码
import { setTheme } from '@clack/prompts';

// 应用自定义主题
setTheme({
  color: {
    primary: '#FF6B35',
    success: '#00C851',
    error: '#FF4444'
  }
});
3. 分组提示

将多个相关提示组合在一起:

javascript 复制代码
import { group } from '@clack/prompts';

const results = await group({
  name: () => text({ message: '姓名' }),
  email: () => text({ message: '邮箱' }),
  subscribe: () => confirm({ message: '订阅新闻' })
}, {
  onCancel: () => {
    cancel('操作取消');
    process.exit(0);
  }
});

console.log(results); // { name: '...', email: '...', subscribe: true/false }

完整示例

以下是一个完整的CLI工具示例,演示了多个组件的组合使用:

javascript 复制代码
#!/usr/bin/env node

import { intro, outro, select, text, confirm, multiselect, isCancel, cancel } from '@clack/prompts';

async function main() {
  // 欢迎界面
  intro('🚀 项目初始化工具');
  
  // 收集项目信息
  const projectType = await select({
    message: '选择项目类型',
    options: [
      { value: 'web', label: 'Web应用' },
      { value: 'cli', label: '命令行工具' },
      { value: 'lib', label: '库/包' }
    ]
  });
  
  if (isCancel(projectType)) {
    cancel('操作已取消');
    return process.exit(0);
  }
  
  const projectName = await text({
    message: '项目名称',
    placeholder: '请输入有效的包名'
  });
  
  if (isCancel(projectName)) {
    cancel('操作已取消');
    return process.exit(0);
  }
  
  const features = await multiselect({
    message: '选择功能',
    options: [
      { value: 'typescript', label: 'TypeScript' },
      { value: 'testing', label: '测试框架 (Jest)' },
      { value: 'linting', label: '代码检查 (ESLint)' },
      { value: 'formatting', label: '代码格式化 (Prettier)' }
    ]
  });
  
  if (isCancel(features)) {
    cancel('操作已取消');
    return process.exit(0);
  }
  
  const confirmSetup = await confirm({
    message: '确认创建项目?'
  });
  
  if (isCancel(confirmSetup) || !confirmSetup) {
    cancel('项目创建取消');
    return process.exit(0);
  }
  
  // 模拟创建过程
  console.log('\n📁 创建项目结构...');
  console.log(`📦 项目名称: ${projectName}`);
  console.log(`🔧 类型: ${projectType}`);
  console.log(`✨ 功能: ${features.join(', ')}`);
  
  // 结束界面
  outro('✅ 项目创建成功!');
}

main().catch(console.error);

注意事项

  1. 异步处理 :所有提示函数都是异步的,必须使用await.then()
  2. 取消处理 :务必使用isCancel()检查每个提示的返回值。
  3. 版本兼容性:v1.x版本可能包含破坏性变更,生产环境建议锁定版本号。
  4. 错误处理:使用try-catch包装可能出错的提示操作。

最佳实践

  • 为必填字段提供清晰的验证信息
  • 使用placeholderhint提供额外指导
  • 按逻辑顺序组织提示问题
  • 及时处理用户取消操作
  • 在长时间操作前提供确认提示

这个库特别适合构建项目脚手架、配置向导、系统管理工具等需要复杂用户交互的CLI应用程序。

相关推荐
失忆爆表症5 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
Mongnewer12 小时前
试写UI界面设计器
ui·界面设计器
TT哇16 小时前
【实习】数字营销系统 银行经理端(interact_bank)前端 Vue 移动端页面的 UI 重构与优化
java·前端·vue.js·ui
木斯佳16 小时前
周末杂谈:UI-UX Pro Max Skill:为AI编程助手注入专业设计智能的终极利器
ui·ai编程·ux
手揽回忆怎么睡16 小时前
opencode和TRAE使用Superpowers 和ui-ux-pro-max skillls
ide·ui·ai·ux
草莓熊Lotso18 小时前
Qt 主窗口核心组件实战:菜单栏、工具栏、状态栏、浮动窗口全攻略
运维·开发语言·人工智能·python·qt·ui
御承扬1 天前
鸿蒙NDK UI之文本自定义样式
ui·华为·harmonyos·鸿蒙ndk ui
一起养小猫1 天前
Flutter for OpenHarmony 实战_魔方应用UI设计与交互优化
flutter·ui·交互·harmonyos
会一点设计2 天前
6个优质春节海报模板网站推荐!轻松设计马年祝福海报
ui·ux
hudawei9962 天前
TweenAnimationBuilder和AnimatedBuilder两种动画的比较
flutter·ui·动画·tweenanimation·animatedbuilder