如何开发一个 CLI 工具包

You,4 min read

如何开发一个 CLI 工具包

结合公司业务将常用的工具提炼出来 类似 vue-cli、create-react-app 这类CLI工具不仅能帮我们快速生成项目也将一些最佳实践聚合到工具内部,基于这个我们需要实现有着如下功能的CLI工具🔧

目标

Features

实现

package.json 注册bin

官方文档示例 (opens in a new tab)

{
 
 "name": "my-cli",
 
 "version": "1.0.0",
 
 "description": "",
 
 "main": "index.js",
 
 "bin": {
 
  "mycli": "/bin/cli.js"
 
 },
 
 "scripts": {
 
  "test": "echo \"Error: no test specified\" && exit 1"
 
 },
 
 "author": "lizhenyu",
 
 "license": "MIT"
 
}

好像不大行

需要在bin下的文件中加上 #!/usr/bin/env node 否则脚本启动时没有node可执行文件

#!/usr/bin/env node 
 
console.log('hello world');

果然加上之后执行成功了

commander 构建命令行界面

注册选项 option('-d, --debug', 'output extra debugging')

commander 命令行工具库 (opens in a new tab)

编写代码来描述你的命令行界面。 Commander 负责将参数解析为选项和命令参数,为问题显示使用错误,并实现一个有帮助的系统。

Commander 是严格的,并且会针对无法识别的选项显示错误。 两种最常用的选项类型是布尔选项,和从参数中获取值的选项

#!/usr/bin/env node

const { Command } = require('commander');
const program = new Command();

program
 .name('my-cli')
 .description('CLI to some JavaScript string utilities')
 .version('0.0.1', '-v, --vers', 'output the current version')
 .requiredOption('-c1, --cheese1 <type>', 'pizza must have cheese', 'yellow')
 .option('-d, --debug', 'output extra debugging')
 .option('-s, --small', 'small pizza size')
 .option('-p, --pizza-type <type>', 'flavour of pizza')
 .option('-c, --cheese <type>', 'add the specified type of cheese', 'blue')
 .option('-n, --number <numbers...>', 'specify numbers')
 .option('-l, --letter [letters...]', 'specify letters')
 .option('--no-sauce', 'Remove sauce');

program.parse();

const options = program.opts();
console.log('Options :', options)
console.log('Remaining arguments: ', program.args);

注册命令 command('start <service>', 'start named service')

通过.command().addCommand()可以配置命令,有两种实现方式:为命令绑定处理函数,或者将命令单独写成一个可执行文件(详述见后文)。子命令支持嵌套(示例代码 (opens in a new tab))。

.command()的第一个参数为命令名称。命令参数可以跟在名称后面,也可以用.argument()单独指定。参数可为必选的(尖括号表示)、可选的(方括号表示)或变长参数(点号表示,如果使用,只能是最后一个参数)。

使用.addCommand()program增加配置好的子命令

命令参数 argument('<username>', 'user to login')

如上所述,子命令的参数可以通过.command()指定。对于有独立可执行文件的子命令来说,参数只能以这种方法指定。而对其他子命令,参数也可用以下方法。

Command对象上使用.argument()来按次序指定命令参数。该方法接受参数名称和参数描述。参数可为必选的(尖括号表示,例如<required>)或可选的(方括号表示,例如[optional]

program
  .version('0.1.0')
  .argument('<username>', 'user to login')
  .argument('[password]', 'password for user, if required', 'no password given')
  .action((username, password) => {
    console.log('username:', username);
    console.log('password:', password);
  });

inquirer 构建交互式命令

仓库地址 (opens in a new tab)

examples 示例 (opens in a new tab)

ts-node 学习 (opens in a new tab)

实施

问题

01|Error [ERR_REQUIRE_ESM]: require() of ES Module

结果

2026 © Lizhenyui.