Node.js CLI 与 readline:交互脚本与 REPL

很多人只把 Node 当 服务端运行时;其实 工具链、脚手架、运维脚本 也大量用 Node 写 CLI。
这一篇围绕 命令行入口 展开,想讲清楚几件事:process.argv 与参数约定、readline 适合什么交互、以及 REPL 在调试里扮演什么角色

process.argv 是一个字符串数组:

  • 前两项通常是 node 路径脚本路径
  • 真正业务参数从 下标 2 起。

手写解析很快会乱,工程上常见:

  • minimist / yargs / commander 等库做 子命令、选项、默认值
  • -- 之后 透传给子进程的规则要 文档化

习惯:

  • 退出码:成功 0,用法错误 1 或其它约定,和 CI 联动;
  • stderr 打错误stdout 打出给机器或管道用的结果,方便 shell 组合

process.stdin 可读,stdout / stderr 可写。

要点:

  • 判断 是否 TTYprocess.stdin.isTTY):交互式 CLI 和 管道喂数据 是两条路径;
  • 大输入流式读,不要 readFileSync(0) 一把梭 unless 场景明确。

Stream 篇一致:字节流 进,按行或按协议 切。

readline.createInterface({ input, output }) 常用于:

  • 密码工具、迁移向导:一问一答;
  • input 接文件流或 stdin逐行 处理日志、CSV。

特点:

  • 按行 舒服,二进制协议 不适合;
  • 关闭时要 rl.close(),避免 句柄挂住进程(配合 unref 或显式 exit)。

复杂 全屏 TUI(表格、快捷键)会换 blessed、ink 等库,readline 只管 简单文本交互

node 直接进入 REPL:交互执行 JS,适合:

  • 试一小段 API
  • 看模块导出require('fs'));
  • 临时算个数

局限:

  • 和项目里的 tsconfig / 路径别名 不一致时要 node -r 或先编译
  • 有副作用的模块 不要随便 require 试。

repl 模块 也可嵌进自有工具里做 小控制台,属于进阶用法。

发布 CLI 包时常在入口文件第一行:

  • #!/usr/bin/env node(Unix);
  • package.jsonbin 字段映射到该文件。

Windows 下 npm 会生成 cmd 包装,具体行为以 npm 文档 为准。

  • 参数与退出码 是可组合性的一部分;
  • stdin/stdout 语义 分清,方便脚本串联;
  • readline 覆盖 问答与按行;复杂 UI 另选栈;
  • REPL 适合 快试,不等于 替代测试

CLI 写稳,和 包管理、生产运行 两篇一起看,工具发布与运维体验会连成一条线。