背景
在工作中新开一个项目会有很多重复的配置需要逐一添加,比如菜单权限,选项卡权限,页面权限,拖拽,api代理拦截器,统一样式,定制化样式等,因此想自己建立一个生成模板的脚手架工具,以模板为基础构建对应的项目,而目前前端主要是使用vue,react,所以分成两套模板,这样的话,如果新开始一个项目的前期工作将会事半功倍。
依赖
"dependencies": {
"commander": "^3.0.1", //将文字输出到终端当中
"async": "^2.6.1",
"chalk": "^2.4.1", //终端字体颜色
"consolidate": "^0.15.1",//模板引擎整合库
"download-git-repo": "^1.0.2",//现在github中的模板
"handlebars": "^4.0.11", //模板编译器
"inquirer": "^6.0.0", //命令行的回答的模块
"metalsmith": "^2.3.0",//静态网站的生成库
"ora": "^3.0.0", //终端里有显示载入动画
"request": "^2.87.0", //请求
"rimraf": "^2.6.2", //使用 UNIX 命令 rm -rf的模块
"user-home": "^2.0.0"// 获取用户主目录的路径
...
}
流程
- 拉取模板信息
- 选择模板
- 判断本地是否存在模板: 存在则选择是否覆盖(覆盖则删除原有模板从新下载生成)否则直接生成,本地不存在则下载并生成
- 选择下载的分支
- 输入项目名称 项目生成地址
- 结束-开始编码
部分代码详解
拉取模板列表
const spinner = ora('fetching template list...')
spinner.start()
request({
uri:'http://47.98.120.163:8080/list.json',
timeout:5000
},(err, response, body)=>{
if(err) {
spinner.fail(chalk.red('fetch template list unsuccessfully'))
console.log(err)
}
if(response&&response.statusCode===200){
spinner.succeed(chalk.green('fetch template list successfully'))
callback(JSON.parse(body));
}
})
下载模板
function downloadAndGenerate(tmpRepo,tmpName,tmpUrl){
const spinner=ora('downloading template...')
const tmpDest=path.join(tmpRepo,tmpName)
inquirer.prompt([{
type:'input',
name:'branch',
message:`the name of branch you need in ${tmpName}`,
default:'master'
}]).then(answer=>{
spinner.start()
download(`${tmpUrl}#${answer.branch}`,tmpDest,{
clone:false
},(err)=>{
if(err){
spinner.fail(chalk.red('download template unsuccessfully'))
console.log(err)
}else{
spinner.succeed(chalk.green('download template successfully'))
generate(tmpDest)
}
})
})
}
生成模板
const metalsmith=Metalsmith(tmpPath)
inquirer.prompt([{
type:'input',
name:'name',
message:'The name of project',
default:'swy-fe'
},{
type:'input',
name:'destination',
message:'The destination of project',
default:process.cwd()
}]).then(answer=>{
//项目生成路径
const destination=path.join(transformIntoAbsolutePath(answer.destination),answer.name)
const spinner = ora('generating...').start()
//加入新的全局变量
Object.assign(metalsmith.metadata(),answer)
spinner.start()
metalsmith
.source('.')
.destination(destination)
.clean(false)
.build(function(err) {
spinner.stop()
if (err) throw err
console.log()
console.log(chalk.green('Build Successfully'))
console.log()
console.log((`${chalk.green('Please cd')} ${destination} ${chalk.green('to start your coding')}`))
console.log()
})
})