
当我们使用Node.js原生开发命令行程序时或许会有一定的门槛,但通过依赖一些开源模块却能够帮助我们简化命令行开发,从而达到事半功倍的效果。本文主要通过一些示例来演示commander.js、inquirer.js的一些基本玩法。下面老司机将带着我,我带着大家一起来玩转Node命令行吧!
温馨提示
本文部分代码参考自凹凸实验室前端流程工具 athena
本文需要一点Node基础
本文涉及到一些es6语法,并且请确保Node版本在4.0及以上
不属于本文的知识点一秒带过哈
基础准备
{
"name": "app",
"version": "1.0.0",
"description": "玩转命令行开发",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "ykg",
"license": "ISC",
"devDependencies": {
"chalk": "^1.1.3",
"commander": "^2.9.0",
"inquirer": "^1.1.2"
}
}
主体内容
commander 简介
参数解析
强制多态
可变参数
Git 风格的子命令
自动化帮助信息
自定义帮助等
一个简单的实例
const program = require('commander')
const inquirer = require('inquirer')
const chalk = require('chalk')
program
.command('module')
.alias('m')
.description('创建新的模块')
.option('-a, --name [moduleName]', '模块名称')
.action(option => {
console.log('Hello World')
//为什么是Hello World 给你个眼神,自己去体会...
})
program.parse(process.argv)
全局方式运行
配置package.json的bin字段。bin字段有啥用呢?它可以用来存放一个可执行的文件,如下配置所示
"bin": {
"app": "app"
}
执行npm link。它将会把app这个字段复制到npm的全局模块安装文件夹node_modules内,并创建符号链接(symbolic link,软链接),也就是将 app 的路径加入环境变量 PATH
在主入口文件的最上方添加代码 #! /usr/bin/env node, 表明这是一个可执行的应用,如下所示
#! /usr/bin/env node
const program = require('commander')
const inquirer = require('inquirer')
const chalk = require('chalk')
program
.command('module')
.alias('m')
.description('创建新的模块')
.option('-a, --name [moduleName]', '模块名称')
.action(option => {
console.log('Hello World')
})
program.parse(process.argv)
commander API
command -- 定义命令行指令,后面可跟上一个name,用空格隔开,如 .command( 'app [name] ')
alias -- 定义一个更短的命令行指令 ,如执行命令$ app m 与之是等价的
description -- 描述,它会在help里面展示
option -- 定义参数。它接受四个参数,在第一个参数中,它可输入短名字 -a和长名字--app ,使用 | 或者,分隔,在命令行里使用时,这两个是等价的,区别是后者可以在程序里通过回调获取到;第二个为描述, 会在 help 信息里展示出来;第三个参数为回调函数,他接收的参数为一个string,有时候我们需要一个命令行创建多个模块,就需要一个回调来处理;第四个参数为默认值
action -- 注册一个callback函数,这里需注意目前回调不支持let声明变量
parse -- 解析命令行
生成帮助信息
自动生成
自定义生成
const program = require('commander')
const inquirer = require('inquirer')
const chalk = require('chalk')
program
.command('module [moduleName]')
.alias('m')
.description('创建新的项目')
.option('-a, --name [moduleName]', '模块名称')
.action(option => {
console.log('Hello World')
})
//自定义帮助信息
.on('--help', function() {
console.log(' Examples:')
console.log('')
console.log('$ app module moduleName')
console.log('$ app m moduleName')
})
program.parse(process.argv)
inquirer
var inquirer = require('inquirer')
inquirer.prompt([/* Pass your questions in here */]).then(function (answers) {
// Use user feedback for... whatever!!
})
var inquirer = require('inquirer')
inquirer.prompt([/* Pass your questions in here */], function (answers) {
// Use user feedback for... whatever!!
})
inquirer功能简介
input--输入
validate--验证
list--列表选项
confirm--提示
checkbox--复选框等等
#! /usr/bin/env node
const program = require('commander')
const inquirer = require('inquirer')
const _ = require('lodash')
const chalk = require('chalk')
program
.command('module')
.alias('m')
.description('创建新的模块')
.option('--name [moduleName]')
.option('--sass', '启用sass')
.option('--less', '启用less')
.action(option => {
var config = _.assign({
moduleName: null,
description: '',
sass: false,
less: false
}, option)
var promps = []
if(config.moduleName !== 'string') {
promps.push({
type: 'input',
name: 'moduleName',
message: '请输入模块名称',
validate: function (input){
if(!input) {
return '不能为空'
}
return true
}
})
}
if(config.description !== 'string') {
promps.push({
type: 'input',
name: 'moduleDescription',
message: '请输入模块描述'
})
}
if(config.sass === false && config.less === false) {
promps.push({
type: 'list',
name: 'cssPretreatment',
message: '想用什么css预处理器呢',
choices: [
{
name: 'Sass/Compass',
value: 'sass'
},
{
name: 'Less',
value: 'less'
}
]
})
}
inquirer.prompt(promps).then(function (answers) {
console.log(answers)
})
})
.on('--help', function() {
console.log(' Examples:')
console.log('')
console.log('$ app module moduleName')
console.log('$ app m moduleName')
})
program.parse(process.argv)
chalk
#! /usr/bin/env node
const program = require('commander')
const inquirer = require('inquirer')
const _ = require('lodash')
const chalk = require('chalk')
program
.command('module')
.alias('m')
.description('创建新的模块')
.option('--name [moduleName]')
.option('--sass', '启用sass')
.option('--less', '启用less')
.action(option => {
var config = _.assign({
moduleName: null,
description: '',
sass: false,
less: false
}, option)
var promps = []
console.log('')
console.log(chalk.red('开启前端工程化之路'))
console.log('')
if(config.moduleName !== 'string') {
promps.push({
type: 'input',
name: 'moduleName',
message: '请输入模块名称',
validate: function (input){
if(!input) {
return '不能为空'
}
return true
}
})
}
if(config.description !== 'string') {
promps.push({
type: 'input',
name: 'moduleDescription',
message: '请输入模块描述'
})
}
if(config.sass === false && config.less ===false) {
promps.push({
type: 'list',
name: 'cssPretreatment',
message: '想用什么css预处理器呢',
choices: [
{
name: 'Sass/Compass',
value: 'sass'
},
{
name: 'Less',
value: 'less'
}
]
})
}
inquirer.prompt(promps).then(function (answers) {
console.log(chalk.green('收工咯'))
console.log(chalk.blue('收工咯'))
console.log(chalk.blue.bgRed('收工咯')) //支持设置背景
console.log(chalk.blue(answers))
})
})
.on('--help', function() {
console.log(' Examples:')
console.log('')
console.log('$ app module moduleName')
console.log('$ app m moduleName')
})
program.parse(process.argv)
参考文献
感谢您的阅读,本文由 凹凸实验室 版权所有。如若转载,请注明出处:凹凸实验室
本文分享自微信公众号 - 凹凸实验室(AOTULabs)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。