UNPKG

geeks-cli

Version:

simple vue cli

144 lines (120 loc) 4.84 kB
// lib/Generator.js const { getRepoList, getTagList } = require('./http') const ora = require('ora') const inquirer = require('inquirer') const util = require('util') const downloadGitRepo = require('download-git-repo') // 不支持 Promise const chalk = require('chalk') const path = require('path'); const fs = require("fs-extra"); const jsoncParser = require('jsonc-parser'); // 添加加载动画 async function wrapLoading(fn, message, ...args) { const spinner = ora(message).start(); try { const result = await fn(...args); spinner.succeed(); return result; } catch (error) { spinner.fail('Request failed, refetch ...'); throw error; // 重新抛出异常 } } // 获取JSON文件并修改其属性 async function operationJSon(name, filePath) { const fullPath = `./${name}/${filePath}.json`; let data = await fs.readFile(fullPath, 'utf8'); const edits = jsoncParser.modify(data, ['name'], name, { formattingOptions: { insertSpaces: true, tabSize: 4 } }); const modifiedData = jsoncParser.applyEdits(data, edits); await fs.ensureDir(path.dirname(fullPath)); // 确保路径存在 await fs.writeFile(fullPath, modifiedData); // 使用 Promise 版本 console.log('File written successfully'); } class Generator { constructor(name, targetDir) { // 目录名称 this.name = name; // 创建位置 this.targetDir = targetDir; // 对 download-git-repo 进行 promise 化改造 this.downloadGitRepo = util.promisify(downloadGitRepo); } // 获取用户选择的模板 // 1)从远程拉取模板数据 // 2)用户选择自己新下载的模板名称 // 3)return 用户选择的名称 async getRepo() { // 1)从远程拉取模板数据 const repoList = await wrapLoading(getRepoList, 'waiting fetch template'); if (!repoList) return; // 过滤我们需要的模板名称 const repos = repoList.map(item => item.name); // 2)用户选择自己新下载的模板名称 const { repo } = await inquirer.prompt({ name: 'repo', type: 'list', choices: repos, message: 'Please choose a template to create project' }) // 3)return 用户选择的名称 return repo; } // 获取用户选择的版本 // 1)基于 repo 结果,远程拉取对应的 tag 列表 // 2)自动选择最新版的 tag async getTag(repo) { // 1)基于 repo 结果,远程拉取对应的 tag 列表 const tags = await wrapLoading(getTagList, 'waiting fetch tag', repo); if (!tags) return; // 过滤我们需要的 tag 名称 const tagsList = tags.map(item => item.name); // 2)return 用户选择的 tag return tagsList[0] } // 下载远程模板 // 1)拼接下载地址 // 2)调用下载方法 async download(repo, tag) { // 1)拼接下载地址 const requestUrl = `geek-cli/${repo}${tag ? '#' + tag : ''}`; // 2)调用下载方法 await wrapLoading( this.downloadGitRepo, // 远程下载方法 'waiting download template', // 加载提示信息 requestUrl, // 参数1: 下载地址 await path.resolve(process.cwd(), this.targetDir) // 参数2: 创建位置 ) console.log('create success') } // 核心创建逻辑 // 1)获取模板名称 // 2)获取 tag 名称 // 3)下载模板到模板目录 // 4) 对uniapp模板中部分文件进行读写 // 5) 模板使用提示 async create() { // 1)获取模板名称 const repo = await this.getRepo() // 2) 获取 tag 名称 const tag = await this.getTag(repo) // 3)下载模板到模板目录 await this.download(repo, tag); // 4) 对uniapp模板中部分文件进行读写 await operationJSon(this.name, 'src/manifest') await operationJSon(this.name, 'package-lock') await operationJSon(this.name, 'package') // 修改README.md 文件 const md = await fs.readFile(`./${this.name}/README.md`, "utf8"); await fs.writeFile(`./${this.name}/README.md`, `# ${this.name}\n` + md, 'utf8'); // 5)模板使用提示 console.log(`\r\nSuccessfully created project ${chalk.cyan(this.name)}`) console.log(`\r\n cd ${chalk.cyan(this.name)}`) console.log(`\r\n 启动前请务必阅读 ${chalk.cyan("README.md")} 文件`) } } module.exports = Generator;