본문 바로가기
JavaScript/React

template 자동화

by curious week 2025. 6. 12.

bun + Vite 환경 빠르고 깔끔한 템플릿 자동 생성 도구

bun run create-feature note

명령어 실행 시:

src/features/note/
├── note.service.ts
├── note.types.ts
├── note.hooks.ts
├── note.schema.ts
├── note.constants.ts
├── note.utils.ts

1단계: 템플릿 파일 만들기

먼저 템플릿 파일을 아래 경로에 저장:

scripts/templates/feature/
├── __name__.service.ts
├── __name__.types.ts
├── __name__.hooks.ts
├── __name__.schema.ts
├── __name__.constants.ts
├── __name__.utils.ts

각 파일에는 플레이스홀더가 포함되어 있어야 해:

예: __name__.service.ts

// Auto-generated service for __name__
export const get__Name__List = () => {
  // TODO: implement __name__ API
};

2단계: create-feature.ts 스크립트 생성 (Bun 전용)

scripts/create-feature.ts:

import { mkdir, writeFile, readdir, readFile } from 'fs/promises';
import { existsSync } from 'fs';
import path from 'path';

const name = Bun.argv[2];
if (!name) {
  console.error('❌ Please provide a feature name.');
  process.exit(1);
}

const PascalCase = name[0].toUpperCase() + name.slice(1);
const templateDir = path.resolve('scripts/templates/feature');
const targetDir = path.resolve(`src/features/${name}`);

if (existsSync(targetDir)) {
  console.error('❌ Feature already exists.');
  process.exit(1);
}

await mkdir(targetDir, { recursive: true });

const templateFiles = await readdir(templateDir);

for (const fileName of templateFiles) {
  const content = await readFile(path.join(templateDir, fileName), 'utf8');
  const replaced = content
    .replace(/__name__/g, name)
    .replace(/__Name__/g, PascalCase);

  const newFileName = fileName.replace(/__name__/g, name);
  await writeFile(path.join(targetDir, newFileName), replaced);
}

console.log(`✅ Feature '${name}' created in src/features/${name}`);

3단계: bunfig.toml 또는 package.json에 명령어 등록

// package.json
{
  "scripts": {
    "create-feature": "bun scripts/create-feature.ts"
  }
}

또는 bunfig.toml:

[scripts]
create-feature = "bun scripts/create-feature.ts"

사용 방법

bun run create-feature note

자동으로 생성됨:

src/features/note/
├── note.service.ts
├── note.types.ts
├── ...

 


create-feature.js (node.js npm)

import fs from 'fs/promises';
import path from 'path';
import { existsSync } from 'fs';

const name = process.argv[2];
if (!name) {
  console.error('❌ Please provide a feature name.');
  process.exit(1);
}

const PascalCase = name.charAt(0).toUpperCase() + name.slice(1);
const templateDir = path.resolve('scripts/templates/feature');
const targetDir = path.resolve(`src/features/${name}`);

if (existsSync(targetDir)) {
  console.error('❌ Feature already exists.');
  process.exit(1);
}

await fs.mkdir(targetDir, { recursive: true });

const templateFiles = await fs.readdir(templateDir);

for (const fileName of templateFiles) {
  const content = await fs.readFile(path.join(templateDir, fileName), 'utf8');
  const replaced = content
    .replace(/__name__/g, name)
    .replace(/__Name__/g, PascalCase);

  const newFileName = fileName.replace(/__name__/g, name);
  await fs.writeFile(path.join(targetDir, newFileName), replaced);
}

console.log(`✅ Feature '${name}' created in src/features/${name}`);