UNPKG

@tianyio/quality-helper

Version:

A comprehensive quality helper tool for project scaffolding and management

324 lines (323 loc) 11.1 kB
import { join, dirname } from "path"; import { fileURLToPath } from "url"; import chalk from "chalk"; import ora from "ora"; import { u as updateConfig } from "./update-config-COvElx1e.js"; import { c as createDependencyManager, i as installProjectDependencies, a as initializeGit, b as initializeHusky, f as formatProject } from "./utils-JjdnUrNK.js"; import { F as FileOperations } from "./core-file-ops-d43o99eg.js"; import { P as ProjectOptionsService } from "./services-DXX3cT7y.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); class CreateProjectWorkflow { options; constructor(options) { this.options = options; } /** * 执行完整的项目创建流程 */ async execute() { const totalSteps = 6; let currentStep = 0; const logProgress = (stepName) => { currentStep++; console.log(chalk.gray(`[${currentStep}/${totalSteps}] ${stepName}`)); }; console.log(chalk.blue("🚀 开始创建项目...")); console.log(); try { logProgress("创建项目结构"); await this.createProjectFolder(); logProgress("复制模板文件"); await this.copyFrameworkFiles(); logProgress("更新项目配置"); await this.updatePackageJsonDependencies(); await this.updateConfigFiles(); logProgress("安装项目依赖"); await this.installDependencies(); logProgress("初始化版本控制"); await this.initializeGitRepository(); await this.initializeHuskyHooks(); await this.copyGitHooksFiles(); logProgress("格式化代码"); await this.formatProjectCode(); this.displayCompletionMessage(); } catch (error) { console.error(chalk.red("❌ 项目创建失败:"), error); throw error; } } /** * 创建项目文件夹 */ async createProjectFolder() { const spinner = ora("创建项目文件夹...").start(); try { const projectPath = join(this.options.targetPath, this.options.projectName); await FileOperations.ensureDir(projectPath); spinner.succeed(chalk.green("项目文件夹创建完成")); } catch (error) { spinner.fail(chalk.red("项目文件夹创建失败")); throw error; } } /** * 拷贝框架文件 */ async copyFrameworkFiles() { const spinner = ora("复制模板文件...").start(); try { const projectPath = join(this.options.targetPath, this.options.projectName); const templatesDir = join(dirname(__dirname), "templates", "project-templates"); const templateDir = this.options.architectureType === "single" ? join(templatesDir, "base") : join(templatesDir, "monorepo"); if (!await FileOperations.exists(templateDir)) { throw new Error(`模板目录不存在: ${templateDir}`); } await this.copyDirectory(templateDir, projectPath); spinner.succeed(chalk.green("模板文件复制完成")); } catch (error) { spinner.fail(chalk.red("模板文件复制失败")); throw error; } } /** * 更新配置文件 */ async updateConfigFiles() { const spinner = ora("更新项目配置...").start(); try { const projectPath = join(this.options.targetPath, this.options.projectName); if (this.options.architectureType === "single") { await updateConfig({ projectPath, rootPath: projectPath, architectureType: "single", projectType: "app", excludeGitHooks: true, excludeNpmrc: true, excludeScripts: true, silent: true }); } else { await this.updateMonorepoConfigs(projectPath); } spinner.succeed(chalk.green("项目配置更新完成")); } catch (error) { spinner.fail(chalk.red("项目配置更新失败")); throw error; } } /** * 更新Monorepo配置 */ async updateMonorepoConfigs(projectPath) { await updateConfig({ projectPath, rootPath: projectPath, architectureType: "monorepo", projectType: "root", excludeGitHooks: true, excludeStaticFiles: true, excludeNpmrc: true, excludeScripts: true, silent: true }); await this.updateAppsConfigs(projectPath); await this.updatePackagesConfigs(projectPath); } /** * 更新apps目录配置 */ async updateAppsConfigs(projectPath) { const appsDir = join(projectPath, "apps"); try { const appDirs = await FileOperations.readDirWithFileTypes(appsDir); for (const appDir of appDirs) { if (appDir.isDirectory()) { const appPath = join(appsDir, appDir.name); await updateConfig({ projectPath: appPath, rootPath: projectPath, architectureType: "monorepo", projectType: "app", includeOnly: ["build-tools", "static-files", "types"], silent: true }); } } } catch (error) { console.warn("无法读取apps目录:", error); } } /** * 更新packages目录配置 */ async updatePackagesConfigs(projectPath) { const packagesDir = join(projectPath, "tools"); try { const packageDirs = await FileOperations.readDirWithFileTypes(packagesDir); for (const packageDir of packageDirs) { if (packageDir.isDirectory()) { const packagePath = join(packagesDir, packageDir.name); await updateConfig({ projectPath: packagePath, rootPath: projectPath, architectureType: "monorepo", projectType: "lib", includeOnly: ["build-tools", "types"], silent: true }); } } } catch (error) { console.warn("无法读取packages目录:", error); } } /** * 更新package.json依赖 */ async updatePackageJsonDependencies() { const spinner = ora("更新项目依赖配置...").start(); const projectPath = join(this.options.targetPath, this.options.projectName); try { await createDependencyManager().updateToRecommendedVersions(projectPath); } catch (error) { spinner.fail(chalk.red(`依赖配置更新失败:${String(error)}`)); throw error; } spinner.succeed(chalk.green("依赖配置更新完成")); } /** * 安装依赖 */ async installDependencies() { const projectPath = join(this.options.targetPath, this.options.projectName); const spinner = ora("安装项目依赖...").start(); try { await installProjectDependencies(projectPath); spinner.succeed(chalk.green("项目依赖安装完成")); } catch (error) { spinner.fail(chalk.red("依赖安装失败")); throw error; } } /** * 初始化Git仓库 */ async initializeGitRepository() { const projectPath = join(this.options.targetPath, this.options.projectName); const spinner = ora("初始化Git仓库...").start(); try { await initializeGit(projectPath); spinner.succeed(chalk.green("Git仓库初始化完成")); } catch (error) { spinner.fail(chalk.red("Git仓库初始化失败")); throw error; } } /** * 初始化Husky钩子 */ async initializeHuskyHooks() { const projectPath = join(this.options.targetPath, this.options.projectName); const spinner = ora("配置Git钩子...").start(); try { await initializeHusky(projectPath); spinner.succeed(chalk.green("Git钩子配置完成")); } catch { spinner.warn(chalk.yellow("Git钩子配置失败,已跳过")); } } /** * 复制git-hooks */ async copyGitHooksFiles() { const projectPath = join(this.options.targetPath, this.options.projectName); const templatesDir = join(dirname(__dirname), "templates"); const spinner = ora("复制Git钩子文件...").start(); try { const gitHooksDir = join(templatesDir, "configs", "git-hooks"); const targetHuskyDir = join(projectPath, ".husky"); try { await FileOperations.ensureDir(targetHuskyDir); const files = await FileOperations.readDir(gitHooksDir); for (const file of files) { const sourcePath = join(gitHooksDir, file); const targetPath = join(targetHuskyDir, file); const isFile = await FileOperations.isFile(sourcePath); if (isFile) { await FileOperations.copyFile(sourcePath, targetPath); await FileOperations.setExecutable(targetPath, 493); } } } catch (error) { console.warn("⚠️ Git钩子复制失败,请手动配置:", error); } spinner.succeed(chalk.green("Git钩子文件复制完成")); } catch (error) { spinner.fail(chalk.red("Git钩子文件复制失败")); throw error; } } /** * 格式化项目代码 */ async formatProjectCode() { const projectPath = join(this.options.targetPath, this.options.projectName); const formatSpinner = ora("格式化代码...").start(); try { await formatProject(projectPath, false); formatSpinner.succeed(chalk.green("代码格式化完成")); } catch { formatSpinner.warn(chalk.yellow("代码格式化失败,可稍后手动执行")); } } /** * 显示完成信息 */ displayCompletionMessage() { console.log(); console.log(chalk.green("🎉 项目创建成功!")); console.log(chalk.cyan(`🚀 下一步: cd ${this.options.projectName} && npm run dev`)); console.log(); const architectureText = this.options.architectureType === "single" ? "单体应用" : "Monorepo"; const frameworkText = this.options.framework === "vue3" ? "Vue 3" : this.options.framework ?? "Vue 3"; console.log( chalk.blue(`📦 项目: ${this.options.projectName} (${architectureText} - ${frameworkText})`) ); } /** * 递归复制目录 */ async copyDirectory(source, target) { await FileOperations.ensureDir(target); const entries = await FileOperations.readDirWithFileTypes(source); for (const entry of entries) { const sourcePath = join(source, entry.name); const targetPath = join(target, entry.name); if (entry.isDirectory()) { await this.copyDirectory(sourcePath, targetPath); } else { await this.copyFileWithTemplateReplacement(sourcePath, targetPath); } } } /** * 复制文件并替换模板变量 */ async copyFileWithTemplateReplacement(sourcePath, targetPath) { const content = await FileOperations.readFile(sourcePath); const replacedContent = content.replace(/\{\{projectName\}\}/g, this.options.projectName); await FileOperations.writeFile(targetPath, replacedContent); } } async function createProject(projectName, options = {}) { const optionsService = new ProjectOptionsService(); const projectOptions = await optionsService.getProjectOptions(projectName, options); const workflow = new CreateProjectWorkflow(projectOptions); await workflow.execute(); } export { createProject as c }; //# sourceMappingURL=create-project-JAxbL8m_.js.map