@tianyio/quality-helper
Version:
A comprehensive quality helper tool for project scaffolding and management
324 lines (323 loc) • 11.1 kB
JavaScript
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