如何实现一个自己的脚手架工具
- 创建自定义全局命令
- 获取命令行的交互参数
- 终端交互
- 下载远程项目代码
创建自定义全局命令
在项目文件夹中创建一个bin文件夹,再去npm init
初始化项目,生成的package.json 里面就有一个bin的选项参数指定了命令和执行文件路径
"bin": {"mycli"; "bin/cli.js"
},
执行 npm link
挂载到了全局命令中
bin/cli.js
在文件首行加上这句,意思让这个环境变量下的node去执行相关代码
#! /usr/bin/env node
获取命令行的交互参数
process.argv[2]
可以获取
借助commander来处理相关参数
#! /usr/bin/env node
const {program} = require( 'commander')
program.option(’-f --framwork <framwork>°,“设置框架’)
program
.command ('create <project› [other ...]')
.alias('crt') // 设置别名
.description('创建项目')
.action((project ‚args)=>{// 在回调函数中可以获取到配置的参数// 命令行的执行逻辑代码console.log (project);console.log (args) ;
})
program.parse (process.argv)
将不同的命令拆分成不同模块 lib/core文件夹下不同模块代码
help.js
const myhelp = function(program){program.option('-f --framwork <framwork>','设置框架')
}
module.exports = myhelp
mycommander.js
const myaction = require('./action')const mycommander = function (program) {program.command('create <project> [other...]').alias('crt').description('创建项目').action(myaction)
}module.exports = mycommander
action.js
ar inquirer = require('inquirer')
var config = require('../../config')
var downloadFun = require('./download')
const myAction = async (project, args) => {// 命令行的执行逻辑代码console.log(project);console.log(args);
}module.exports = myAction
bin/cli.js
#! /usr/bin/env node
const {program} = require('commander')
const myhelp = require('../lib/core/help')
myhelp(program)const mycommander = require('../lib/core/mycommander')
mycommander(program)
program.parse(process.argv)
终端交互
命令行问答交互工具:inquirer
inquirer.prompt([{type: 'list',name: 'framwork',choices: ['express', 'koa', 'egg'],message: '请选择你所使用的框架'}]).then(answer => {console.log(answer)})
下载远程项目代码
插件download-git-repo, 命令行任务等待工具Ora,命令行样式渲染工具chalk
lib/core/download.js
const download = require('download-git-repo')
const ora = require('ora')
const chalk = require('chalk')
const downloadFun = function (url, project) {const spinner = ora().start()spinner.text = '代码正在下载……'download('direct:' + url, project, { clone: true }, (err) => {if (!err) {spinner.succeed('代码下载成功')console.log(chalk.blue.bold('Done!'), chalk.bold('you run:'));console.log('cd ' + project);console.log('npm install ');console.log('npm run dev ');} else {spinner.fail('代码下载失败')}})
}module.exports = downloadFun
lib/core/action.js
var inquirer = require('inquirer')
var config = require('../../config')
var downloadFun = require('./download')
const myAction = async (project, args) => {// 命令行的执行逻辑代码const answer = await inquirer.prompt([{type: 'list',name: 'framwork',choices: config.framwork,message: '请选择你所使用的框架'}])// console.log(answer);// 下载代码模板downloadFun(config.foramworkUrl[answer.framwork],project)
}module.exports = myAction