Enquirer 2.0 全面解析:语义化样式、内置 Prompt 与对话式 CLI 交互
开发工具【免费下载链接】enquirerStylish, intuitive and user-friendly prompts. Used by eslint, webpack, yarn, pm2, pnpm, RedwoodJS, FactorJS, salesforce, Cypress, Google Lighthouse, Generate, tencent cloudbase, lint-staged, gluegun, hygen, hardhat, AWS Amplify, GitHub Actions Toolkit, airbnb/nimbus, and more! Please follow Enquirers author: https://github.com/jonschlinkert项目地址https://gitcode.com/gh_mirrors/en/enquirer点击查看免费下载Enquirer 2.0 是该项目的一次彻底重构不仅重写了 Prompt 的编写与处理方式还重新定义了创建和维护 CLI 提示的哲学。本篇以官方发布公告为骨架结合仓库源码lib/styles.js、lib/theme.js、lib/prompt.js、lib/prompts/index.js等逐条解读 2.0 的版本变化、语义化样式系统、元素与主题机制并给出可直接运行的配置示例帮助你掌握用 Enquirer 2.0 快速构建像对话而非审问的现代化 CLI 交互界面。一、2.0 的核心理念Prompt 是对话不是审问发布公告开篇即点明 2.0 的目标定位风格化、直观、对用户友好的 CLI 提示Prompt 应当像一场对话而不是一次审讯Prompts should be more like a conversation than an inquisition。轻量且强大Enquirer 足够快、足够轻适合小项目使用同时又足够强大、足够可定制能承载最复杂的进阶场景。这两句话背后对应着 2.0 的三项工程决策详见后文只保留极少的运行时依赖、将常用 Prompt 全部内置、以语义化样式与元素机制把可定制性从配置项提升为第一等公民。二、Whats changing2.0 的三大变化公告明确列出了相对 1.x 的关键变化这些变化都能在当前仓库中找到落点。1. 常用 Prompt 从插件变为内置此前多个 Prompt 以独立 npm 包的形式发布使用者需要手动安装插件。2.0 将常用 Prompt 直接内置进 Enquirer 本体同时仍然完整支持自定义 Prompt。查看 lib/prompts/index.js当前仓库内置了 19 个 Prompt源码中每个定义同时注册了大小写两种导出形式内置 Prompt用途AutoComplete输入时自动补全并返回选中值BasicAuth用户名 密码认证Confirm返回true/falseEditable可增删、编辑条目的列表Form单屏填写并提交多个字段表单式对话见第五节Input接受用户输入并返回字符串Invisible隐藏输入内容返回字符串List按分隔符拆分输入返回列表MultiSelect从列表中多选Numeral接受数字输入Password掩码显示输入内容Scale基于李克特量表Likert Scale快速评分Select从列表中单选Snippet在代码/文本模板中替换占位符Sort对列表项排序Survey对一组问题逐一反馈评分Text纯文本输入Toggle在两个值之间切换返回布尔值Quiz多选问答同时lib/types/目录保留了 5 个底层类型类ArrayPrompt、AuthPrompt、BooleanPrompt、NumberPrompt、StringPrompt文档中注明DatePrompt即将到来它们是创建高阶 Prompt 的起点——这正是既内置常用 Prompt、又保留自定义能力的架构体现。2. 依赖数降到极低公告承诺 Enquirer 只有一个运行时依赖ansi-colors该库自身无其他依赖以此降低维护成本、加快安装速度。以当前仓库 package.json版本 2.4.1为准实际运行时依赖为ansi-colors与strip-ansi两个engines要求node 8.6。也就是说极简依赖的设计目标在实现中得到了延续只是从公告期的单个依赖演进为当前的两个轻量依赖。3. 移除注册 questions的方法1.x 允许预注册问题question并在之后按需调用。2.0 移除了这一机制——公告的解释是预注册完全可以用自定义代码轻松实现与其内置一套注册表不如把这件事留给实现者让 API 更小、更聚焦。这同时是渐进式披露设计见第三节的一部分新手只需掌握极少 API 即可上手。三、Whats new2.0 的新特性1. 更易使用创建、运行一个 Prompt 只需几行代码。例如 docs/prompts.md 中的最小示例const { prompt } require(enquirer); const question { type: input, name: username, message: What is your username? }; prompt(question) .then(answer console.log(Answer:, answer)) .catch(console.error);也可以直接实例化具体 Prompt 类并调用.run()const { Input } require(enquirer); const prompt new Input({ message: What is your username?, initial: jonschlinkert }); prompt.run() .then(answer console.log(Answer:, answer)) .catch(console.log);2. 动态渲染Promise 与 async/await 贯穿全程2.0 全面基于 Promise 与 async/await让 Prompt 的组合、链式与堆叠变得极其简单。更重要的是message、样式、符号都可以按 Prompt 状态或任意条件同步/异步地动态计算。这一点在 lib/prompt.js 中有直接印证run()返回 Promise通过submit/cancel事件决议lib/prompt.jsinitialize()中initial、onRun、onSubmit等选项均支持异步函数并被awaitlib/prompt.jselement()方法对每个元素统一走resolve()解析天然支持函数返回值与 Promiselib/prompt.js。因此在 question 对象中message、initial、format、result、validate、skip都可以写成function | async function从而实现随状态变化的动态交互。3. 渐进式披露Progressive disclosure新手不需要理解完整 API 就能创建 Prompt方法、选项和高级特性则按需提供给进阶用户。对应地所有 Prompt 共享同一套 question 选项接口详见 docs/prompts.md{ // 必填 type: string | function, name: string | function, message: string | function | async function, // 可选 skip: boolean | function | async function, initial: string | function | async function, format: function | async function, result: function | async function, validate: function | async function, }属性必填类型说明type是string\|function决定运行哪种 Prompt直接运行具体 Prompt 类时可省略name是string\|function返回结果对象answers中的键名message是string\|function终端中渲染的提示文本skip否boolean\|function为true时跳过该问题initial否string\|function用户未输入时的默认值format否function格式化终端中的用户输入result否function格式化最终提交值后再返回validate否function校验提交值返回布尔值或字符串字符串作为错误消息四、语义化样式系统Semantic Styles颜色与符号的一致化公告投入了大量篇幅讲述样式设计目标是三点可定制性最大化、在整个 Prompt 中一致应用、对实现者和终端用户都友好。2.0 的做法是内置一套语义命名的样式调色板保存在prompt.styles上。1. 语义调色板公告给出的调色板如下左侧为语义名右侧为颜色/修饰样式名公告描述当前仓库实现infocyan青色默认取primary青色dangerred红色colors.magenta品红strongbold加粗colors.boldsuccessgreen绿色colors.greenwarningyellow黄色colors.yellowdisabledgray灰色colors.graymuteddim暗色colors.dimdarkdim.gray暗灰colors.dim.gray需要说明的是公告文本中danger写作 red而当前 lib/styles.js 的实现是colors.magenta品红——文章以仓库实际实现为准。2. 状态驱动的样式pending / submitted / cancelled语义样式不只用于静态配色还直接与 Prompt 生命周期状态绑定。查看 lib/state.js状态机为pending等待输入submitted已提交cancelled已取消lib/styles.js 为每个状态预置了样式pending取primary、submitted取success绿色、cancelled取danger。同时prompt.stylegetter 会按当前状态返回对应样式lib/prompt.js而 lib/state.js 的state.color也按cancelled → submitted → pending的顺序解析颜色。这意味着同一个 Prompt 在待输入、已提交、已取消三种状态下会自动呈现不同配色实现者无需手动分支判断。3. 样式可覆盖按需定制或整体替换样式既可以a-la-carte按需覆盖也可以在 options 上一次性整体替换。例如 examples/input/option-styles.jsconst { Input } require(enquirer); const colors require(ansi-colors); const prompt new Input({ message: What is your username?, initial: jonschlinkert, styles: { primary: colors.blue, get submitted() { return this.complement; // 提交状态使用互补色 } } }); prompt.run() .then(answer console.log(ANSWER, answer)) .catch(console.log);styles.merge()lib/styles.js会把用户传入的options.styles与默认调色板合并并且未覆盖的键会自动透传到ansi-colors的全部颜色方法因此你可以用任意 ANSI 颜色方法作为自定义样式。除上述 8 个核心语义名外源码还提供了一批特殊用途样式均可覆盖primary主色默认 cyan、inverse、complement、em强调主色下划线、heading标题muted 下划线、underline、typing、placeholder、highlight等lib/styles.js。五、新 Prompt 类型把表单搬进终端公告指出2.0 引入新 Prompt 概念目标是实现两个对话式能力像 Web 表单一样用户可以在一个界面上同时提供多条信息用户能够在字段间用 Tab 切换、随时修改以自己节奏推进最后一次性提交。这正是Form Prompt在单个终端屏幕上填写并提交多个值docs/prompts.mdconst { Form } require(enquirer); const prompt new Form({ name: user, message: Please provide the following information:, choices: [ { name: firstname, message: First Name, initial: Jon }, { name: lastname, message: Last Name, initial: Schlinkert }, { name: username, message: GitHub username, initial: jonschlinkert } ] }); prompt.run() .then(value console.log(Answer:, value)) .catch(console.error);Form 把写代码、搭 UI的负担从实现者身上移走让实现者把精力放在如何与用户沟通上。与之配套的同类对话式 Prompt 还有Survey对一组问题逐一反馈评分scale定义评分档位choices定义问题项ScaleSurvey 的紧凑版基于李克特量表快速打分Snippet在模板占位符中逐字段填写内容如生成package.json。六、Elements元素Prompt 的每个部分都可定制公告提出了Elements概念Prompt 的各个组成部分称为元素用户可以为任意部分应用自定义样式、文本或 Unicode 符号。在 lib/prompt.js 中可以看到元素渲染的完整体系prefix前缀符号、message提示文本、separator分隔符、hint提示语、error错误信息、header/footer头尾文本、pointer指向当前选项的指针、indicator选项选中指示等。element()的解析顺序是options[name] || state[name] || symbols[name]lib/prompt.js也就是说选项配置优先其次是运行状态最后回落到默认符号表。符号默认值集中在 lib/symbols.js其中prefix、separator会按pending / submitted / cancelled三种状态切换符号如待输入用?、已提交用✓、取消用✘指针、单选圆点、复选方框、星级评分等也都支持按状态/索引动态计算。七、主题Themes一次性定制整个 Prompt公告将Themes与语义样式、元素、符号并列为 2.0 的可定制化支柱。主题机制的实现非常轻量——lib/theme.js 只有三行核心逻辑module.exports prompt { prompt.options utils.merge({}, prompt.options.theme, prompt.options); prompt.symbols symbols.merge(prompt.options); prompt.styles styles.merge(prompt.options); };即把options.theme与options合并theme 作为默认值具体 options 优先然后依次生成prompt.symbols与prompt.styles。因此一个 theme 对象里可以同时包含styles、symbols、prefix、pointer等任意元素配置直接传给任意 Prompt 即可整体生效。仓库中的 examples/select/option-theme.js 是一个完整的万圣节主题示例自定义primary/muted颜色、用函数按选项索引返回 emoji 单选符号、让prefix随pending/cancelled/submitted状态切换南瓜头、墓碑、骷髅 emojiconst colors require(ansi-colors); const { Select } require(enquirer); const emoji { pending: , cancelled: ⚰️ , submitted: }; const halloween { styles: { primary: colors.blue, muted: colors.yellow }, symbols: { radio: { on: state [, , , ][state.index], off: } }, prefix: state emoji[state.status], pointer(state, choice, i) { let status state.index i ? on : off; let symbol this.symbols.radio[status]; let fallback ️ ; if (typeof symbol function) { return symbol(...arguments) || fallback; } return symbol || fallback; } }; const prompt new Select({ name: halloween, message: Trick or treat! Take your pick, theme: halloween, choices: [ { name: candy, value: Sweet! }, { name: apple, value: Hard... core? }, { name: toothpaste, value: Orange juice? }, { name: insult, value: You stink! }, { name: razor blade, value: Ouch! } ] }); prompt.run() .then(key { let choice prompt.choices.find(ch ch.name key); console.log(answer:, { [key]: choice.value }); }) .catch(console.error);注意示例中pointer返回的符号是带 ANSI 颜色的字符串直接原样输出未带颜色的符号则由prompt.pointer()自动应用primary样式并做对齐处理lib/prompt.js。八、关于多语言支持的说明公告在特性列表中提到了 Multi-language support。从当前仓库源码结构看Enquirer 并未内置 i18n 字典或语言资源文件而是通过三项机制为多语言场景提供支持message可以是同步/异步函数可按运行时条件返回不同语言的提示文本语义样式与符号体系支持按需覆盖可适配不同 locale 的排版与符号习惯终端符号如☑/☐、◉/◯在 Windows 上会自动回退为纯文本形式lib/symbols.js避免跨平台乱码。因此多语言更准确地说是让实现者以最少代码自由适配多语言与多终端环境而非开箱即用的翻译系统。九、组合实战链式与堆叠多个 Prompt2.0 基于 Promise/async/await 的设计让组合多个问题非常自然。使用prompt()函数传入 question 数组即可顺序、链式地完成一次多步对话const { prompt } require(enquirer); const questions [ { type: input, name: username, message: What is your username? }, { type: password, name: password, message: What is your password? }, { type: confirm, name: confirm, message: Ready to submit?, initial: true } ]; prompt(questions) .then(answers console.log(Answers:, answers)) .catch(console.error);更复杂的场景下可以基于Prompt基类创建自定义 Promptconst { Prompt } require(enquirer); class MyCustomPrompt extends Prompt {}将format、result、validate等钩子与语义样式、元素、主题机制结合构建完全贴合业务形态的对话式 CLI。十、总结Enquirer 2.0 的发布公告所承诺的能力在当前仓库中均有对应实现常用 Prompt 全部内置lib/prompts/index.js、极简依赖package.json、语义化样式系统lib/styles.js、状态驱动的动态渲染lib/state.js、元素与符号体系lib/symbols.js以及轻量主题合并机制lib/theme.js。对实现者而言2.0 的价值在于用最小的 API 快速上手按需渐进掌握高级特性并用一套统一、可覆盖、可整体替换的样式语言把 CLI 提示真正打磨成一场友好的对话。赞分享开发工具【免费下载链接】enquirerStylish, intuitive and user-friendly prompts. Used by eslint, webpack, yarn, pm2, pnpm, RedwoodJS, FactorJS, salesforce, Cypress, Google Lighthouse, Generate, tencent cloudbase, lint-staged, gluegun, hygen, hardhat, AWS Amplify, GitHub Actions Toolkit, airbnb/nimbus, and more! Please follow Enquirers author: https://github.com/jonschlinkert项目地址https://gitcode.com/gh_mirrors/en/enquirer点击查看免费下载相关推荐Enquirer CLI 交互式提示库完全指南从安装、内置 Prompts 到自定义扩展Enquirer CLI 交互式提示库完全指南从安装、内置 Prompts 到自定义扩展 Enquirer 是一个用于构建 Node.js 交互式命令行提示开发工具告别混乱对话Gemini CLI对话管理与流式交互全攻略告别混乱对话Gemini CLI对话管理与流式交互全攻略 在AI终端工具层出不穷的今天你是否还在为对话历史丢失、长文本响应卡顿而烦恼Gemini CLI作人工智能AI Agent交互助手CLIMCP Clients从Docker到生产环境Yamtrack部署最佳实践与性能优化从Docker到生产环境Yamtrack部署最佳实践与性能优化 Yamtrack是一款强大的自托管媒体追踪工具能够帮助用户高效管理电影、电视剧、动漫等媒体内上一篇WebAssembly.js 项目常见问题解决方案下一篇彻底解决Windows Defender异常3种修复方案深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考