本文主要来实现实现一个从gitlab拉取项目模板的可交互命令行工具,旨在让大家来理解开发一个交互式命令行工具的整个流程。
创建项目
首先当然是npm init node-cli-demo -y 直接创建出一个空白项目,之后修改package.json文件,之后创建src和bin文件夹,之后目录结构如下图所示:
npm init node-cli-demo -y
package.json
"scripts": {
"convert": "babel src --out-dir ./bin/"
},
"bin": {
"tm": "./bin/index.js"
},
index.js文件初始化如下:
#!/usr/bin/env node
console.log('Hello node-cli')
之后我们直接在命令行输入tm就会看到控制台出现console语句了,如果提示不存在的话,可以先用npm link来绑定,之后再输入tm即可。
这样一个最基础的架子就完成了,现在我们来解释下初始化代码的作用:#!/usr/bin/env node是通知当前系统要用node来解析当前脚本的意思。
处理命令行参数
当初始化架构搭好之后,我们就需要开始处理输入的命令参数了,这里我们用到的是commander:(https://github.com/tj/commander.js/)
首先安装:
The complete solution for node.js command-line interfaces, inspired by Ruby's commander.
npm i -- save commander
然后我们就在index.js里开始使用commander了:
const program = require('commander')
// 实现命令行工具的help描述
program
.version(require('../package').version)
.description('a test commander program to achieve the goal of cloning template from gitLab')
.option('-i --init', 'init template')
// 具体开发某个命令的行为方法
program
.command('init')
.action((dir, cmd) => {
console.log('dir, cmd', dir, cmd)
})
// commander 执行
program.parse(process.argv)
如上我们就实现了对命令行参数的处理
处理交互式命令
在可以接收到用户的命令参数之后,我们就开始处理内部逻辑,即需要用户选择下载哪个模板,这里我们就会用到inquirer(https://github.com/SBoudrias/Inquirer.js/)
首先还是安装:
npm i --save commander
之后修改index.js来实现交互式操作的逻辑:
const inquirer = require('inquirer')
const templates = [
{name: 'template-1', value: {url: 'https://template-1', branch: 'master'}},
{name: 'template-2', value: {url: 'https://template-2', branch: 'dev'}}
]
program
.command('init')
.action(async (dir, cmd) => {
const res = await inquirer.prompt([{
type: 'list',
name: 'template',
message: 'please check template',
choices: () => {
return templates
},
default: templates[0],
}])
console.log('res: ', res)
const {url, branch} = res.template
await cloneTemplate(url, branch)
console.log('clone success !!!')
})
node操作Git下载
最后我们来用下载git上的代码,clone到本地,这里我们需要用到的是simple-git
首先还是安装:
npm i --save simple-git
之后使用当前包的API来clone代码到本地目录,如下:
const simpleGit = require('simple-git/promise');
async function cloneTemplate(url, branch) {
const path = process.cwd()
// 创建clone仓库需要用的git
const cloneGit = simpleGit(path);
await cloneGit.clone(url, path, { depth: 1 });
}
上传
开发完成之后,使用npm run convert转化下代码,之后npm publish就可以发布上去了,之后使用的时候全局安装当前工具就可以开心滴使用了,妈妈再也不用担心我不会写命令行工具了!!!