阶段 2:命令行参数就该这么玩
这篇博客用更接地气的方式,带你从
process.argv玩到minimist的双路径流程设计。
1. 参数解析的一日三餐
1.1 process.argv 到底长啥样
process.argv[0]:Node 可执行文件路径process.argv[1]:当前脚本路径process.argv.slice(2):只剩用户传的真实参数
flowchart LR
A(process.argv) --> B["argv[0]=/path/to/node"]
A --> C["argv[1]=/path/to/script"]
A --> D["argv[2...]=用户参数"]
D --> E[".slice(2) = 纯净参数数组"]
1.2 demo-argv.js 快速验证
node demo-argv.js my-app -t base --verbose
输出就是一串字符串,slice(2) 之后就剩 ['my-app','-t','base','--verbose']。
2. minimist:把数组揉成好用的对象
import minimist from 'minimist'
const argv = minimist(process.argv.slice(2), {
alias: { templateType: ['t'] },
string: ['_'],
})
2.1 开箱即用的解析结果
pnpm create unibest my-app -t base --verbose
会被解析成:
argv._[0] = 'my-app'位置参数(项目名)argv.t = 'base'argv.templateType = 'base'(alias 自动映射)argv.verbose = true
2.2 配置项的真实作用
alias: 让-t和--templateType永远同步string: ['_']: 就算用户输入纯数字项目名,也强制保留字符串- 其他常用:
boolean,default,stopEarly等,可按场景加
3. 双路径:既要傻瓜也要高效
flowchart TD
Start[用户运行 CLI] --> Parse[minimist 解析]
Parse --> Check{projectName 存在吗?}
Check -- 否 --> PathA[路径A: 完全交互]
Check -- 是 --> PathB[路径B: 部分交互]
路径 A:没传项目名
- 触发命令:
pnpm create unibest - 逻辑:调用
question(),依次询问项目名、覆盖策略、模板 - 用户随时取消 → 捕获异常后退出
路径 B:传了项目名
- 触发命令:
pnpm create unibest my-app [-t demo] - 关键步骤:
templateList.find()匹配模板;若指定但不存在则直接提示错误并退出canSkipEmptying(projectName)判断目标目录是否为空- 若目录不空,调用
filePrompt+prompts二次确认是否覆盖 - 没传模板就 fallback 到默认
base
4. 设计心法:让 CLI 更聪明
- 渐进式交互:命令越完整,提问越少;新手只敲
pnpm create unibest也能跑通 - 智能默认值:默认模板选最常用的 base;目录为空就不打扰用户
- 别名友好:
-t更顺手,--templateType更清晰,全靠 alias 同步 - 类型安全:
string: ['_']保证项目名一直是字符串,避免123→Number带来的坑
5. 命令实战对照表
| 命令 | 解析结果 | 交互 |
|---|---|---|
pnpm create unibest | argv._ = [] | 询问项目名 + 覆盖 + 模板 |
pnpm create unibest my-app | argv._[0] = 'my-app' | 只在目录非空时询问覆盖 |
pnpm create unibest my-app -t demo | argv.t = argv.templateType = 'demo' | 不再询问模板 |
pnpm create unibest my-app --templateType i18n | alias 自动同步 t=i18n | 同上 |
6. minimist 配置速查
| 配置项 | 作用 | create-unibest 用法 |
|---|---|---|
alias | 选项别名 | { templateType: ['t'] } |
string | 强制字符串 | ['_'] |
boolean | 布尔开关 | 可扩展到 --force 等 |
default | 默认值 | 需要时补全,如 port |
stopEarly | 遇到非选项停下 | 默认 false |
7. 下一步预告
阶段 3 将深入 prompts 的交互细节:如何设计多步提问、取消回退、以及不同模板的展示方式。准备好继续了吗?