UNPKG

create-palladium

Version:

A modern CLI tool to create Vite + React + TypeScript projects with various configurations

117 lines (116 loc) 4.62 kB
import fs from "fs-extra"; import path from "path"; import { fileURLToPath } from "url"; import { logger } from "../utils/logger.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export class TemplateManager { constructor(targetDir, answers) { Object.defineProperty(this, "templatesDir", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "targetDir", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "answers", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.templatesDir = path.resolve(__dirname, "../../src/templates/base"); this.targetDir = targetDir; this.answers = answers; } async copyTemplate() { logger.step("템플릿 파일 복사 중..."); // 템플릿 디렉토리 존재 확인 if (!await fs.pathExists(this.templatesDir)) { throw new Error(`템플릿 디렉토리를 찾을 수 없습니다: ${this.templatesDir}`); } // 기본 파일 목록 const filesToCopy = [ "postcss.config.js", "tailwind.config.js", "vite.config.ts", "index.html", "package.json", "tsconfig.json", "tsconfig.node.json", ".prettierrc", ".eslintrc.cjs" ]; // 루트 파일 복사 for (const file of filesToCopy) { const srcPath = path.join(this.templatesDir, file); if (await fs.pathExists(srcPath)) { await fs.copy(srcPath, path.join(this.targetDir, file)); } } // src 폴더 복사 await fs.copy(path.join(this.templatesDir, "src"), path.join(this.targetDir, "src")); // public 폴더 복사 (존재하는 경우) if (await fs.pathExists(path.join(this.templatesDir, "public"))) { await fs.copy(path.join(this.templatesDir, "public"), path.join(this.targetDir, "public")); } logger.success("템플릿 파일 복사 완료"); } async processConditionals() { logger.step("조건부 파일 처리 중..."); const conditionals = [ { file: "src/router.tsx", condition: (answers) => !answers.useRouter, action: "remove" }, { file: "tailwind.config.js", condition: (answers) => answers.cssFramework !== "Tailwind CSS", action: "remove" }, { file: "src/main.tsx", condition: (answers) => !answers.useRouter, action: "modify", modifier: (content) => { return content .replace(/import.*router.*\n/g, "") .replace(/<RouterProvider.*\/>/g, "<App />"); } } ]; for (const conditional of conditionals) { if (conditional.condition(this.answers)) { const filePath = path.join(this.targetDir, conditional.file); if (conditional.action === "remove") { if (await fs.pathExists(filePath)) { await fs.remove(filePath); logger.info(`제거됨: ${conditional.file}`); } } else if (conditional.action === "modify" && conditional.modifier) { if (await fs.pathExists(filePath)) { const content = await fs.readFile(filePath, "utf-8"); const modifiedContent = conditional.modifier(content, this.answers); await fs.writeFile(filePath, modifiedContent); logger.info(`수정됨: ${conditional.file}`); } } } } logger.success("조건부 파일 처리 완료"); } async validateTargetDirectory() { // 디렉토리가 비어있는지 확인 const files = await fs.readdir(this.targetDir); if (files.length > 0) { throw new Error(`디렉토리 '${path.basename(this.targetDir)}'가 비어있지 않습니다. 다른 이름을 사용하거나 디렉토리를 비워주세요.`); } } }