|
1 | | -This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). |
| 1 | +# jayychoi.github.io |
2 | 2 |
|
3 | | -## Getting Started |
| 3 | +개인 학습 기록 블로그. Next.js 정적 사이트로 빌드하여 GitHub Pages에 배포한다. |
4 | 4 |
|
5 | | -First, run the development server: |
| 5 | +> https://jayychoi.github.io |
| 6 | +
|
| 7 | +## 기술 스택 |
| 8 | + |
| 9 | +| 분류 | 기술 | |
| 10 | +|---|---| |
| 11 | +| 프레임워크 | Next.js 16 (App Router, `output: "export"`, React Compiler) | |
| 12 | +| 언어 | TypeScript 5, React 19 | |
| 13 | +| 콘텐츠 | Velite (Markdown → 정적 JSON) | |
| 14 | +| 스타일링 | Tailwind CSS 4 + Shadcn/ui (New York) | |
| 15 | +| 검색 | Fuse.js + cmdk (`⌘K`) | |
| 16 | +| 코드 하이라이팅 | Shiki (github-light / github-dark 듀얼 테마) | |
| 17 | +| 댓글 | Giscus (GitHub Discussions) | |
| 18 | +| 다크모드 | next-themes | |
| 19 | +| 린팅/포매팅 | Biome | |
| 20 | +| 패키지 매니저 | pnpm | |
| 21 | +| 폰트 | Pretendard (본문), Quicksand (디스플레이) | |
| 22 | + |
| 23 | +## 브랜치 구조 |
| 24 | + |
| 25 | +이 리포지토리는 두 개의 독립된 브랜치로 운영된다. |
| 26 | + |
| 27 | +| 브랜치 | 역할 | 내용 | |
| 28 | +|---|---|---| |
| 29 | +| `main` | 앱 코드 | Next.js 소스코드, 설정, 배포 워크플로우 | |
| 30 | +| `content` | 콘텐츠 (고아 브랜치) | Markdown 게시글, 프로젝트, about, 배포 트리거 워크플로우 | |
| 31 | + |
| 32 | +`content`는 `main`과 커밋 히스토리를 공유하지 않는 고아 브랜치(orphan branch)다. 코드 변경과 글 작성의 커밋이 서로 섞이지 않는다. |
| 33 | + |
| 34 | +두 브랜치 중 어느 쪽에 push하든 GitHub Actions가 자동으로 빌드 및 배포한다. |
| 35 | + |
| 36 | +## 시작하기 |
| 37 | + |
| 38 | +### 필수 요구사항 |
| 39 | + |
| 40 | +- Node.js 24+ |
| 41 | +- pnpm 10+ |
| 42 | + |
| 43 | +### 설치 |
| 44 | + |
| 45 | +```bash |
| 46 | +git clone https://github.com/jayychoi/jayychoi.github.io.git |
| 47 | +cd jayychoi.github.io |
| 48 | + |
| 49 | +# content 고아 브랜치를 content/ 디렉토리에 worktree로 연결 |
| 50 | +git worktree add content content |
| 51 | + |
| 52 | +# 의존성 설치 |
| 53 | +pnpm install |
| 54 | +``` |
| 55 | + |
| 56 | +### 개발 서버 |
6 | 57 |
|
7 | 58 | ```bash |
8 | | -npm run dev |
9 | | -# or |
10 | | -yarn dev |
11 | | -# or |
12 | 59 | pnpm dev |
13 | | -# or |
14 | | -bun dev |
15 | 60 | ``` |
16 | 61 |
|
17 | | -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. |
| 62 | +`http://localhost:3000`에서 확인할 수 있다. Velite watch 모드가 자동 실행되어 콘텐츠 변경 시 핫 리로드된다. |
| 63 | + |
| 64 | +## 명령어 |
| 65 | + |
| 66 | +| 명령어 | 설명 | |
| 67 | +|---|---| |
| 68 | +| `pnpm dev` | 개발 서버 (Velite watch 모드 자동 실행) | |
| 69 | +| `pnpm build` | 정적 빌드 (`out/` 생성) | |
| 70 | +| `pnpm lint` | Biome 린트 검사 | |
| 71 | +| `pnpm format` | Biome 자동 포매팅 | |
| 72 | +| `pnpm content` | Velite 콘텐츠만 단독 재빌드 (`velite --clean`) | |
| 73 | + |
| 74 | +## 디렉토리 구조 |
| 75 | + |
| 76 | +``` |
| 77 | +src/ |
| 78 | +├── app/ # App Router 페이지 |
| 79 | +│ ├── layout.tsx # 루트 레이아웃 (폰트, 테마, 검색 프로바이더) |
| 80 | +│ ├── page.tsx # 홈 (활동 히트맵 + 최근 글) |
| 81 | +│ ├── blog/ |
| 82 | +│ │ ├── layout.tsx # 블로그 레이아웃 (사이드바) |
| 83 | +│ │ ├── page.tsx # 전체 글 목록 |
| 84 | +│ │ ├── posts/[slug]/ # 개별 포스트 |
| 85 | +│ │ ├── categories/[category]/ |
| 86 | +│ │ ├── tags/[tag]/ |
| 87 | +│ │ ├── series/[series]/ |
| 88 | +│ │ └── til/[date]/ |
| 89 | +│ ├── projects/ # 프로젝트 목록 및 상세 |
| 90 | +│ └── about/ |
| 91 | +├── components/ |
| 92 | +│ ├── ui/ # Shadcn/ui 컴포넌트 |
| 93 | +│ └── blog/ # 블로그 전용 컴포넌트 |
| 94 | +├── lib/ # 유틸리티 및 데이터 쿼리 |
| 95 | +└── styles/ # 글로벌 스타일, 마크다운 타이포그래피 |
| 96 | +
|
| 97 | +content/ # content 브랜치 (git worktree) |
| 98 | +├── posts/**/*.md # 블로그 게시글 |
| 99 | +├── projects/**/*.md # 프로젝트 |
| 100 | +└── about.md |
| 101 | +``` |
| 102 | + |
| 103 | +## 콘텐츠 작성 |
| 104 | + |
| 105 | +### 게시글 작성 |
| 106 | + |
| 107 | +`content/posts/` 아래에 Markdown 파일을 생성한다. |
| 108 | + |
| 109 | +```yaml |
| 110 | +--- |
| 111 | +title: "제목" |
| 112 | +slug: unique-slug |
| 113 | +created: 2026-01-29 |
| 114 | +description: "설명" # 선택 (없으면 본문 첫 200자) |
| 115 | +category: "java" # categories.ts의 id 값 |
| 116 | +tags: [tag1, tag2] |
| 117 | +type: [til, series] # 선택 |
| 118 | +series: "시리즈 이름" # 선택 |
| 119 | +order: 1 # 시리즈 내 순서, 선택 |
| 120 | +--- |
| 121 | + |
| 122 | +본문 내용... |
| 123 | +``` |
| 124 | + |
| 125 | +### 카테고리 |
| 126 | + |
| 127 | +| 대분류 | 카테고리 | |
| 128 | +|---|---| |
| 129 | +| Language | java, kotlin, rust, cpp | |
| 130 | +| Web | spring, blog2 | |
| 131 | +| DevOps | docker, github-actions | |
| 132 | +| Linux | arch-linux, linux | |
| 133 | +| Algorithm | algorithm | |
| 134 | +| Tool | nvim | |
| 135 | +| Etc | etc | |
18 | 136 |
|
19 | | -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. |
| 137 | +새 카테고리 추가 시 `src/lib/categories.ts`의 `CATEGORY_GROUPS`를 수정한다. |
| 138 | + |
| 139 | +### 콘텐츠 커밋 및 배포 |
| 140 | + |
| 141 | +`content/`는 `content` 브랜치의 worktree이므로, 앱 코드와 독립적으로 커밋하고 push한다. |
| 142 | + |
| 143 | +```bash |
| 144 | +cd content |
| 145 | +git add posts/blog2/new-post.md |
| 146 | +git commit -m "새 글 작성" |
| 147 | +git push origin content |
| 148 | +``` |
| 149 | + |
| 150 | +push하면 GitHub Actions가 자동으로 빌드 및 배포한다. |
| 151 | + |
| 152 | +## 콘텐츠 빌드 파이프라인 |
| 153 | + |
| 154 | +``` |
| 155 | +content/*.md → Velite → .velite/*.json → Next.js SSG → out/*.html |
| 156 | +``` |
20 | 157 |
|
21 | | -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. |
| 158 | +1. `content/` 디렉토리의 Markdown 파일을 Velite가 읽음 |
| 159 | +2. Rehype 플러그인 적용 (slug → autolink-headings → shiki) |
| 160 | +3. `.velite/` 디렉토리에 JSON 데이터 출력 |
| 161 | +4. 코드에서 `import { posts, projects, about } from "#velite"` 로 사용 |
| 162 | +5. Next.js가 정적 HTML로 빌드하여 `out/`에 출력 |
22 | 163 |
|
23 | | -## Learn More |
| 164 | +## 배포 |
24 | 165 |
|
25 | | -To learn more about Next.js, take a look at the following resources: |
| 166 | +`main` 또는 `content` 브랜치에 push하면 GitHub Actions가 자동으로 GitHub Pages에 배포한다. |
26 | 167 |
|
27 | | -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. |
28 | | -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. |
| 168 | +- `main` push → `deploy-pages.yml`이 직접 빌드 및 배포 |
| 169 | +- `content` push → `trigger-deploy.yml`이 `main`의 배포 워크플로우를 트리거 |
29 | 170 |
|
30 | | -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! |
| 171 | +GitHub Actions의 `push` 트리거는 해당 브랜치에 워크플로우 파일이 있어야 동작하므로, `content` 브랜치에는 `main`의 배포를 호출하는 트리거 워크플로우를 별도로 두었다. |
31 | 172 |
|
32 | | -## Deploy on Vercel |
| 173 | +### 캐시 전략 |
33 | 174 |
|
34 | | -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. |
| 175 | +| 트리거 | Next.js 컴파일 캐시 | Velite 캐시 | 효과 | |
| 176 | +|---|---|---|---| |
| 177 | +| content push | 히트 (소스 불변) | 미스 (콘텐츠 변경) | 컴파일 시간 절약 | |
| 178 | +| main push | 미스 (소스 변경) | 히트 (콘텐츠 불변) | Velite 빌드 시간 절약 | |
35 | 179 |
|
36 | | -Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. |
| 180 | +정적 페이지 생성(`next build`)은 두 경우 모두 항상 실행된다. |
0 commit comments