如何创建Node.js CLI箭头键选择菜单?参考eslint init等示例
嘿,路子完全对!Node.js+CLI工具链就是做这种交互式箭头键选择菜单的标准答案,你提到的Commander.js这类框架负责处理命令解析,而核心的箭头键选择交互,得靠专门的交互库来实现——毕竟原生Node.js的readline模块写起来太繁琐了。我给你捋个清晰的实现流程:
核心依赖推荐
业内最常用的两个交互库,直接选就行:
- Inquirer.js:ESLint、Yeoman这类知名CLI的御用交互库,功能全、稳定性拉满,文档也很完善
- Enquirer:更轻量、API更简洁,适合追求精简的小项目
下面以「Commander.js + Inquirer.js」的组合为例(最贴近你提到的eslint init/create-react-app场景),一步步实现:
实现步骤
1. 初始化项目并安装依赖
先创建CLI项目骨架,安装所需包:
mkdir my-custom-cli && cd my-custom-cli npm init -y # 注意:Inquirer v9+是ESM格式,若用CommonJS则安装v8.x版本 npm install commander inquirer@8.x
2. 编写核心CLI代码
创建index.js作为入口文件,结合Commander的命令解析和Inquirer的交互菜单:
const { program } = require('commander'); const inquirer = require('inquirer'); // 配置CLI基础信息 program .name('my-cli') .description('自定义交互式CLI工具') .version('1.0.0'); // 实现类似eslint init的init命令 program .command('init') .description('初始化新项目') .action(async () => { console.log('欢迎初始化新项目!请选择以下选项:\n'); // 箭头键选择菜单核心:inquirer的list类型 const userChoices = await inquirer.prompt([ { type: 'list', // 这个类型就是上下箭头选择的列表 name: 'projectType', message: '选择项目类型:', choices: [ // 可以直接传字符串,也可以传带描述的对象 { name: 'React 单页应用', value: 'react', description: '基于Create React App构建' }, { name: 'Vue 单页应用', value: 'vue', description: '基于Vue CLI构建' }, { name: 'Node.js API服务', value: 'node-api', description: '基于Express/Koa构建' }, '静态HTML网站' ], default: 'react' // 默认选中的选项 }, { type: 'confirm', // 附加确认交互(可选) name: 'installDeps', message: '是否立即安装依赖?', default: true } ]); // 处理用户选择的结果 console.log(`\n✅ 你选择了:${userChoices.projectType}`); if (userChoices.installDeps) { console.log('🔧 正在安装依赖...'); // 这里可以通过child_process模块执行npm install等命令 } }); // 解析命令行参数 program.parse(process.argv);
3. 测试CLI功能
先在package.json中配置全局调用的入口:
{ "bin": { "my-cli": "./index.js" } }
然后全局链接测试:
npm link # 运行init命令,就能看到箭头键选择菜单了 my-cli init
其他可选方案
如果不需要Commander的命令解析功能(比如只是一个简单的单菜单CLI),可以直接用Inquirer或Enquirer独立实现:
// 用Enquirer实现极简箭头键选择菜单 const { Select } = require('enquirer'); const prompt = new Select({ name: 'framework', message: '选择开发框架:', choices: ['React', 'Vue', 'Svelte'] }); prompt.run() .then(answer => console.log(`你选择了:${answer}`)) .catch(err => console.error('交互出错:', err));
进阶技巧
- 可以给选项添加快捷键(比如在choices中加
{ name: 'React', value: 'react', short: 'R' }) - 支持多级嵌套菜单:在第一个prompt的回调中,根据用户选择再发起第二个prompt
- 自定义菜单样式:通过Inquirer的
theme配置修改字体颜色、选中状态等
内容的提问来源于stack exchange,提问作者Chance Smith
相关产品推荐
相关产品推荐

