把所有逻辑放在一起会显得冗余,将代码抽取整理
libs/data/demo.config.json:模板选择
[
{
"name": "features",
"message": "请选择要创建的项目模板",
"type": "list",
"choices": [
{
"name": "vue",
"value": "vue",
"description": "vue3+vite+ts",
"link": "https://gitee.com/Hehanjian/vue-vite-template"
},
{
"name": "react",
"value": "react",
"description": "react+vite+ts",
"link": "https://gitee.com/Hehanjian/react-vite-template"
}
]
}
]
2.libs/constant.js:主要放一些常量
import fs from 'fs-extra'
import path from 'path'
import { fileURLToPath } from 'url'
const __filenameNew = fileURLToPath(import.meta.url)
const __dirnameNew = path.dirname(__filenameNew)
// 根目录
export const rootPath = __dirnameNew.slice(0, __dirnameNew.length - 4)
// 获取package.json文件内容
export const packageJsonData = JSON.parse(fs.readFileSync(rootPath + 'package.json', 'utf8'))
// 获取当前模板列表
export const questionList = JSON.parse(fs.readFileSync(rootPath + 'libs/data/demo.config.json', 'utf8'))
3.libs/utils/index.js:放工具方法函数
import fs from 'fs-extra'
import path from 'path'
/*** 判断是否有同名文件夹 start */
export const isFileExist = (projectName) => { // projectName是用户输入的目录名
const targetDir = path.join(process.cwd(), projectName)
return fs.existsSync(targetDir)
}
4.libs/command/index.js:命名行逻辑
import downLoad from 'download-git-repo'
import path from 'path'
import inquirer from 'inquirer'
import ora from 'ora';
import chalk from 'chalk';
import fs from 'fs-extra'
import {questionList} from '../constant.js';
import {isFileExist} from '../utils/index.js'
//设置检测重名的问题交互
const folder = [
{
name: "folder",
message: "当前目录已存在,请选择",
type: "list",
choices: [
{
name: "覆盖",
value: "cover"
},
{
name: "重命名",
value: "rename"
}
]
},
{
name: 'newName',
// 这里设置当前面用户选择重命名后,让用户输入新名称
when: answer => answer.folder === 'rename',
type: 'input',
message: '目录名称为:'
}
]
const handleDownLoad = (projectName) => {
const spinner = ora('模版资源下载中 ...')
const targetDir = path.join(process.cwd(), projectName)
inquirer.prompt(questionList).then(res => {
//获取选择的是那个choice
const project = questionList[0].choices.find(item => item.value === res.features)
downLoad(`direct:${project.link}`, targetDir, { clone: true }, (err) => {
if (err) {
spinner.fail()
console.log(chalk.red('获取模版失败'))
} else {
spinner.succeed()
console.log(chalk.green('获取模版成功!'))
}
spinner.stop()
})
})
}
const handleChecKName = (name) => {
// 清空控制台
console.clear()
if (isFileExist(name)) {
inquirer.prompt(folder).then(res => {
if (res.folder === 'cover') {
const targetDir = path.join(process.cwd(), name)
const loadingMsg = ora(`正在删除 ${chalk.cyan(targetDir)}...`)
loadingMsg.start()
fs.remove(targetDir).then(val => {
loadingMsg.succeed()
loadingMsg.stop()
handleDownLoad(name)
})
} else {
handleChecKName(res.newName)
}
})
} else {
handleDownLoad(name)
}
}
export default handleChecKName;
bin/index.js:入口文件
#! /usr/bin/env node
import handleChecKName from '../libs/command/index.js'
import {packageJsonData} from '../libs/constant.js';
import { program } from 'commander';
program
.command('create <projectName>')
.action((projectName) => {
console.log(`项目名${projectName}`);
handleChecKName(projectName)
})
//读取版本
program.version(packageJsonData.version, '-v, --version')
program.parse(process.args)
执行