node cli开发介绍

最近在写项目生成工具butter-cli,把vue-cli源码看了一遍,总结一下使用node做cli开发的一些点.

1.package定义

相比普通的npm项目,在package中我们需要增加bin属性以及preferGlobal属性.

  • bin:可以指定一个或多个shell文件,node会在-g安装后自动在node目录生成对应系统的运行文件.详见package.json
  • preferGlobal:可以指定使用命令行运行,如果本地安装时会提示警告.详见package.json

2.使用commander定义cli命令

我们使用commander来定义cli命令的参数,见butter-cli.js

#!/usr/bin/env node
'use strict';  
const program = require('commander');  
const pkg = require('../package.json');  
program  
    .version(pkg.version)
    .usage('<project-name>');

program.on('--help', function () {  
    global.console.log('  示例(Examples):');
    global.console.log();
    global.console.log(chalk.gray('    # 创建新项目(Create a new project)'));
    global.console.log('    $ butter-cli my-project');
});

除此之外,还可以通过定义option,来定义选填选项.如:

program  
.option('-p, --peppers', 'Add peppers')

定义之后,当用户使用cli来执行时,我们可以通过以下代码来呼出参数

program.parse(process.argv);  
program.args  

使用以下代码来呼出选项

program.peppers  

3.使用inquirer定义问答选项

当cli使用时,我们可能需要根据用户的选择来定义执行的命令.这个时候,我们就需要使用inquirer来定义选择列表.

使用inquirer.prompt,我们可以快速创建一个问答promise对象,返回的数据内可以获得答案对象.

const inquirer = require('inquirer');  
inquirer.prompt([/* Pass your questions in here */]).then(function (answers) {  
    // Use user feedback for... whatever!! 
});

数组中按先后顺序指定问题列表,可以查看支持的问题参数.其中when指定了可以跳过的内容.如:

[
{
    'name':'redis',
    'type':'confirm',
    'default':true,
    'message':'是否开启redis?\nOpen redis?'
},
{
    'name':'redis-cluster',
    'type':'confirm',
    'default':true,
    'message':'是否开启redis集群?\nOpen redis cluster?',
    'when':function(answers) {
        return answers.redis;
    }
}
]

上面的示例指定了当redis选项为开启时,则可以选择redis-cluster是否开启.

4.其他

初上面必要的内容以外,我们还可以使用以下包来提升用户体验:

  • chalk:改变cli中提示文字颜色
  • configstore:记录配置到文件缓存中,用于记录用户之前的填写
  • ora:增加loading进程样式,帮助用户理解当前的状态