UNPKG

vva-cli

Version:

A CLI of Vue 3 and Typescript and Element-plus in Vite

145 lines (133 loc) 3.69 kB
#!/usr/bin/env node const { readdirSync, lstatSync, existsSync, mkdirSync, writeFileSync, readFileSync } = require('fs'); const { join } = require('path'); const { prompt } = require('inquirer'); const { renderFile } = require('ejs'); const { white, green, red } = require("chalk"); const boxen = require("boxen"); // utils function successBox(message, title) { return box(message, green(title), green('✔ Success'), { borderColor: "green", }); } function errorBox(message, title) { return box(message, red(title), red('✖ Error'), { borderColor: "red", }); } function box(message, title, boxTitle, options) { return ( boxen( [ boxTitle, title, "", white(message), ].join("\n"), Object.assign( { borderColor: "white", borderStyle: "round", padding: 1, margin: 1, }, options ) ) + "\n" ); } const questions = [{ type: 'input', name: 'name', message: 'Project name ?', default: "my_vva", }, { type: 'input', name: 'version', message: 'Project version ?', default: "0.0.0", }] // main prompt([ { type: 'list', name: 'template', message: 'Please select a template ?', choices: ['csr', 'ssr'], default: "csr", }, ]).then(async (templateAnwsers) => { const { template } = templateAnwsers; if (template === 'csr') { questions.push({ type: 'list', name: 'language', message: 'Select language ?', choices: ['Chinese', 'English'], default: "cn", filter: (v) => { const map = { Chinese: 'cn', English: 'en' }; return map[v] || 'cn'; } }) } const anwsers = await prompt(questions); let isSuccess = true; // 创建项目目录 const { name = 'myVva' } = { ...anwsers }; const projectDir = join(process.cwd(), name); mkdir(projectDir); // 开始读取模板目录文件 readTempl(join(__dirname, 'templates', template), projectDir); if (isSuccess) { process.stdout.write(successBox(`您可以通过以下命令运行项目:\n\n$ cd ${name} \n$ npm install \n$ npm run dev`, `${name} 创建完成 🎉`)) } function readTempl(templDir, distDir) { try { const files = readdirSync(templDir); files.forEach(async (file) => { const filePath = join(templDir, file); const isDir = lstatSync(filePath).isDirectory(); const clientDir = join(distDir, file); if (isDir) { mkdir(clientDir); readTempl(filePath, clientDir); } else { await transTempl(clientDir, filePath); } }) } catch (error) { isSuccess = false; process.stdout.write(errorBox(error, '创建失败')); } } // 创建目录 function mkdir(clientDir) { if (!existsSync(clientDir)) { mkdirSync(clientDir); } } // 替换模板 function transTempl(clientDir, filePath) { return new Promise((rs) => { try { if (['.jpg','.jpeg','.png', '.gif'].filter((formate) => filePath.includes(formate)).length) { writeFileSync(clientDir, readFileSync(filePath)); rs(true); } else { renderFile(filePath, anwsers, (err, result) => { if(err) throw err; writeFileSync(clientDir, result); rs(true); }) } } catch (err) { isSuccess = false; process.stdout.write(errorBox(err, '模板替换出错')); rs(false); } }) } })