sth-cli
Version:
stonehg vue cli
190 lines (184 loc) • 5.93 kB
JavaScript
/*
* @Description:
* @Autor: houyueke
* @Date: 2022-04-24 15:05:50
* @LastEditors: houyueke
* @LastEditTime: 2022-05-06 10:51:40
*/
const { getRepoList } = require('./http')
const ora = require('ora')
const inquirer = require('inquirer')
const util = require('util')
const downloadGitRepo = require('download-git-repo') // 不支持 Promise
const path = require('path')
const chalk = require('chalk');
const fs = require('fs-extra')
async function wrapLoading(fn, message, ...args) {
// 使用 ora 初始化,传入提示信息 message
const spinner = ora(message)
//开始加载动画
spinner.start()
try {
const result = await fn(...args)
spinner.succeed()
return result
} catch (error) {
spinner.fail('请求失败, 重试中 ...')
}
}
class Generator {
constructor(name, target) {
this.name = name
this.target = target
// 对 download-git-repo 进行 promise 化改造
this.downloadGitRepo = util.promisify(downloadGitRepo)
}
// 1)从远程拉取模板数据
// 2)用户选择自己新下载的模板名称
// 3)return 用户选择的名称
async getRepo() {
// 1)从远程拉取模板数据
const repoList = await wrapLoading(getRepoList, '项目基础模板拉取中...')
if (!repoList) {
return
}
//过滤我们需要的模板名称
const repos = repoList.map(item => item.name).filter(el => el.startsWith('vue'));
// 2)用户选择自己新下载的模板名称
const { repo } = await inquirer.prompt({
name: 'repo',
type: 'list',
choices: repos,
message: '请选择一个模板创建项目'
})
// 3)return 用户选择的名称
return repo
}
async getIsNeedMapUtil() {
const { isMap } = await inquirer.prompt({
name: 'isMap',
type: 'list',
choices: [
{
name: "否",
value: false
},
{
name: "是",
value: true
}
],
message: '请选择是否需要集成地图工具类'
})
return isMap
}
// 核心创建逻辑
//获取模板名称
// 下载模板到模板目录
async create() {
//模板名称
const repo = await this.getRepo()
//是否需要集成地图工具类
const isMap = await this.getIsNeedMapUtil()
// 2)下载模板到目录
await this.download(repo, isMap)
}
/**
* @description: 外网下载
* @param {*String} repo
* @return {*void}
* @author: houyueke
*/
async download(repo, isMap) {
const repoUrl = `st-cli/${repo}#main`
await wrapLoading(this.downloadGitRepo, '模板下载中', repoUrl, path.resolve(process.cwd(), this.target)
)
if (isMap) {
this.createMapUtil(repo)
} else {
this.createSuccessLog(repo)
}
}
/**
* @description: 是否为vue2项目
* @param {* void }
* @return {* void }
* @author: houyueke
*/
isVue2(name) {
return name.startsWith('vue2')
}
/**
* @description: 模板创建成功提示信息
* @param {*void}
* @return {*void}
* @author: houyueke
*/
createSuccessLog(repo) {
console.log(`\r\n成功创建项目 ${chalk.cyan(this.name)}`)
console.log(`\r\n cd ${chalk.cyan(this.name)}`)
console.log(`\r\n npm install`)
if (this.isVue2(repo)) {
console.log(' npm run serve\r\n')
} else {
console.log(' npm run dev\r\n')
}
}
/**
* @description: 创建地图工具
* @param {*void}
* @return {*void}
* @author: houyueke
*/
async createMapUtil(name) {
//地图工具类github地址
const mapRepoUrl = `st-cli/openlayers-base-util#main`
//清空目录
this.emptyDir(path.join(__dirname, 'mapUtil'))
//下载地图工具类项目到脚手架中mapUtil目录下
await wrapLoading(this.downloadGitRepo, '地图工具类创建中', mapRepoUrl, path.join(__dirname, 'mapUtil'))
//将地图工具类代码复制到项目utils目录下
//项目目录
const currentPath = path.resolve(process.cwd(), this.target)
//模板目录
this.copyDir(path.join(__dirname, 'mapUtil/src/utils/SMap'), path.join(currentPath, 'src/utils/SMap'))
//更新package.json文件
this.updatePackageJson(path.join(currentPath, 'package.json'))
//清空目录
this.emptyDir(path.join(__dirname, 'mapUtil'))
//项目创建成功提示log
this.createSuccessLog(name)
}
/**
* @description: 清空目录
* @param {*String} path
* @return {*void}
* @author: houyueke
*/
emptyDir(path) {
fs.emptyDir(path)
}
/**
* @description: 复制目录
* @param {*String} tmp 模板目录
* @param {*String} target 目标目录
* @return {*void}
* @author: houyueke
*/
copyDir(tmp, target) {
fs.copySync(tmp, target)
}
/**
* @description: 更新package.json
* @param {*String} path package.josn文件目录
* @return {*void}
* @author: houyueke
*/
updatePackageJson(path) {
const pkg = fs.readJsonSync(path)
pkg.dependencies['ol'] = "^6.14.1"
pkg.dependencies['ol-contextmenu'] = "^4.1.0"
fs.outputJSONSync(path, pkg)
}
}
module.exports = Generator