diff --git a/.vitepress/plugins/markdown-picture.ts b/.vitepress/plugins/markdown-picture.ts
index c903ceb..7b69e87 100644
--- a/.vitepress/plugins/markdown-picture.ts
+++ b/.vitepress/plugins/markdown-picture.ts
@@ -52,11 +52,36 @@ function convertImgToPicture(
additionalAttrs: string = "",
): string {
const safeAlt = alt || "";
- const safeAttrs = additionalAttrs && additionalAttrs.trim() ? " " + additionalAttrs.trim() : "";
+ let safeAttrs = additionalAttrs && additionalAttrs.trim() ? " " + additionalAttrs.trim() : "";
+ let pictureStyle = "";
+
+ // width 속성 처리: 퍼센트나 단위가 있는 경우 picture의 스타일로 이동하여 중첩 계산 방지
+ const widthMatch = /width=["']([^"']+)["']/i.exec(safeAttrs);
+ if (widthMatch) {
+ const widthVal = widthMatch[1];
+ if (widthVal.includes("%") || widthVal.includes("px")) {
+ pictureStyle = `width: ${widthVal}; display: inline-block;`;
+ // img 태그에서는 원본 width 속성을 제거하고 내부적으로 100%를 가지도록 함
+ safeAttrs = safeAttrs.replace(/width=["'][^"']*["']/gi, "").trim();
+
+ if (safeAttrs.includes("style=\"")) {
+ safeAttrs = safeAttrs.replace(/style=["']([^"']*)["']/i, (m, s) => {
+ const baseStyle = s.trim();
+ const separator = baseStyle && !baseStyle.endsWith(";") ? ";" : "";
+ return `style="${baseStyle}${separator} width: 100%;"`;
+ });
+ } else {
+ safeAttrs += " style=\"width: 100%;\"";
+ }
+ } else {
+ // 숫자만 있는 경우(HTML5 표준) px 제거 로직 유지
+ safeAttrs = safeAttrs.replace(/width="(\d+)(px)?"/gi, "width=\"$1\"");
+ }
+ }
// 외부 URL이거나 svg, gif는 picture 태그로 변환하지 않음
if (src.startsWith("http") || src.endsWith(".svg") || src.endsWith(".gif")) {
- return ``;
+ return ``;
}
// 이미지 포맷별 경로 생성
@@ -82,13 +107,14 @@ function convertImgToPicture(
// 변환된 이미지가 없으면 원본만 사용
if (sources.length === 0) {
- return ``;
+ return ``;
}
// picture 태그 생성 (원본을 최종 fallback으로 사용)
- return `
+ const pictureAttr = pictureStyle ? ` style="${pictureStyle}"` : "";
+ return `
${sources.join("\n ")}
-
+ `;
}
@@ -117,6 +143,7 @@ function processHtmlImages(html: string, markdownPath: string): string {
.replace(/src=["'][^"']*["']/gi, "")
.replace(/alt=["'][^"']*["']/gi, "")
.replace(/loading=["'][^"']*["']/gi, "") // loading은 우리가 추가할 것이므로 제거
+ .replace(/\s+/g, " ") // 중복 공백 제거
.trim();
// 속성이 비어있거나 공백만 있으면 빈 문자열로
@@ -142,16 +169,23 @@ export function markdownPicturePlugin(md: MarkdownIt) {
md.renderer.rules.image = (tokens, idx, options, env, self) => {
const token = tokens[idx];
const srcIndex = token.attrIndex("src");
+ const altIndex = token.attrIndex("alt");
if (srcIndex < 0) {
return defaultRender(tokens, idx, options, env, self);
}
const src = token.attrs![srcIndex][1];
- const alt = token.content;
+ const alt = altIndex >= 0 ? token.attrs![altIndex][1] : token.content || "";
const markdownPath = env.path || "";
- return convertImgToPicture(src, alt, markdownPath);
+ // src, alt를 제외한 나머지 속성들 추출 (width, height 등)
+ const additionalAttrs = token.attrs!
+ .filter(([name]) => name !== "src" && name !== "alt")
+ .map(([name, value]) => `${name}="${value}"`)
+ .join(" ");
+
+ return convertImgToPicture(src, alt, markdownPath, additionalAttrs);
};
// 2. HTML inline 이미지 () 처리
diff --git a/GEMINI.md b/GEMINI.md
new file mode 100644
index 0000000..2788ce1
--- /dev/null
+++ b/GEMINI.md
@@ -0,0 +1,57 @@
+# ToothlessDev Blog
+
+이 프로젝트는 VitePress를 기반으로 구축된 기술 블로그 및 포트폴리오 사이트입니다.
+
+## 프로젝트 개요
+- **프레임워크:** [VitePress](https://vitepress.dev/) (Vue 기반 정적 사이트 생성기)
+- **주요 기술:** TypeScript, Vue 3, Vanilla CSS
+- **콘텐츠 관리:** `contents/` 디렉토리 내의 마크다운 파일
+- **주요 기능:**
+ - 이미지 자동 최적화 (Sharp 사용)
+ - KaTeX를 이용한 수식 렌더링
+ - Giscus를 이용한 댓글 시스템
+ - 포스트 목록 및 사이드바 자동 생성 플러그인
+
+## 디렉토리 구조
+- `.vitepress/`: VitePress 설정 및 커스텀 플러그인 (`plugins/`)
+- `contents/`: 마크다운 콘텐츠
+ - `posts/`: 기술 블로그 포스트
+ - `projects/`: 프로젝트 소개
+ - `archive/`: 아카이브 페이지
+- `src/`: 테마 커스터마이징을 위한 Vue 컴포넌트 및 유틸리티
+- `scripts/`: 포스트 데이터 생성을 위한 스크립트
+- `data/`: 자동 생성된 포스트 데이터 (`posts.json`)
+
+## 개발 및 빌드 명령
+- **의존성 설치:** `yarn install`
+- **로컬 개발 서버 실행:** `npm run docs:dev`
+- **프로젝트 빌드:** `npm run docs:build`
+- **빌드 결과물 미리보기:** `npm run docs:preview`
+- **포스트 데이터 수동 생성:** `npm run generate-posts`
+
+## 개발 컨벤션
+### 포스트 작성 (Markdown)
+모든 포스트는 `contents/posts/` 하위 디렉토리에 위치해야 하며, 다음의 frontmatter 형식을 반드시 준수해야 합니다:
+```yaml
+---
+title: "포스트 제목"
+description: "포스트 요약 설명"
+createdAt: "2024-03-20"
+category: "카테고리명"
+comment: true # 댓글 활성화 여부
+---
+```
+- `index.md` 파일은 포스트 목록 생성에서 제외됩니다.
+- 이미지는 각 포스트 디렉토리 내의 `img/` 폴더에 위치시키는 것을 권장합니다.
+
+### 스타일링
+- 컴포넌트별로 전용 `.css` 파일을 생성하여 관리합니다 (`src/components/` 참조).
+- 전역 스타일은 `.vitepress/theme/style.css`에서 관리합니다.
+
+### 아키텍처 및 플러그인
+- **플러그인 시스템:** `.vitepress/plugins/`에 위치한 커스텀 Vite 플러그인을 통해 빌드 시 포스트 목록 생성, 이미지 최적화 등을 자동화합니다.
+- **데이터 흐름:** 마크다운 파일 수정 -> Vite 플러그인 감지 -> `generate-posts.mjs` 실행 -> `data/posts.json` 업데이트 -> UI 반영
+
+## 배포
+- GitHub Actions를 통해 `main` 브랜치 푸시 시 자동 배포됩니다.
+- 배포 설정은 `.github/workflows/deploy.yml`에 정의되어 있습니다.
diff --git a/contents/posts/Aws/img/lambda-img-optimization/optimize.jpeg b/contents/posts/Aws/lambda-image-optimization/img/optimize.jpeg
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/optimize.jpeg
rename to contents/posts/Aws/lambda-image-optimization/img/optimize.jpeg
diff --git a/contents/posts/Aws/img/lambda-img-optimization/optimize.jpg b/contents/posts/Aws/lambda-image-optimization/img/optimize.jpg
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/optimize.jpg
rename to contents/posts/Aws/lambda-image-optimization/img/optimize.jpg
diff --git a/contents/posts/Aws/img/lambda-img-optimization/optimize.webp b/contents/posts/Aws/lambda-image-optimization/img/optimize.webp
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/optimize.webp
rename to contents/posts/Aws/lambda-image-optimization/img/optimize.webp
diff --git a/contents/posts/Aws/img/lambda-img-optimization/setup-lambda.jpeg b/contents/posts/Aws/lambda-image-optimization/img/setup-lambda.jpeg
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/setup-lambda.jpeg
rename to contents/posts/Aws/lambda-image-optimization/img/setup-lambda.jpeg
diff --git a/contents/posts/Aws/img/lambda-img-optimization/setup-lambda.png b/contents/posts/Aws/lambda-image-optimization/img/setup-lambda.png
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/setup-lambda.png
rename to contents/posts/Aws/lambda-image-optimization/img/setup-lambda.png
diff --git a/contents/posts/Aws/img/lambda-img-optimization/setup-lambda.webp b/contents/posts/Aws/lambda-image-optimization/img/setup-lambda.webp
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/setup-lambda.webp
rename to contents/posts/Aws/lambda-image-optimization/img/setup-lambda.webp
diff --git a/contents/posts/Aws/img/lambda-img-optimization/setup-trigger.jpeg b/contents/posts/Aws/lambda-image-optimization/img/setup-trigger.jpeg
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/setup-trigger.jpeg
rename to contents/posts/Aws/lambda-image-optimization/img/setup-trigger.jpeg
diff --git a/contents/posts/Aws/img/lambda-img-optimization/setup-trigger.png b/contents/posts/Aws/lambda-image-optimization/img/setup-trigger.png
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/setup-trigger.png
rename to contents/posts/Aws/lambda-image-optimization/img/setup-trigger.png
diff --git a/contents/posts/Aws/img/lambda-img-optimization/setup-trigger.webp b/contents/posts/Aws/lambda-image-optimization/img/setup-trigger.webp
similarity index 100%
rename from contents/posts/Aws/img/lambda-img-optimization/setup-trigger.webp
rename to contents/posts/Aws/lambda-image-optimization/img/setup-trigger.webp
diff --git a/contents/posts/Aws/lambda-image-optimization.md b/contents/posts/Aws/lambda-image-optimization/index.md
similarity index 93%
rename from contents/posts/Aws/lambda-image-optimization.md
rename to contents/posts/Aws/lambda-image-optimization/index.md
index 69186b7..1292329 100644
--- a/contents/posts/Aws/lambda-image-optimization.md
+++ b/contents/posts/Aws/lambda-image-optimization/index.md
@@ -7,7 +7,7 @@ comment: true
---
:::info
-이 글은 [응~ 이미지 키워봐~ 최적화 하면 그만이야 🤡 (pt1. 이미지 포맷)](../Web/image-format.md) 글의 속편입니다.
+이 글은 [응~ 이미지 키워봐~ 최적화 하면 그만이야 🤡 (pt1. 이미지 포맷)](../../Web/image-format/index.md) 글의 속편입니다.
지난 글에서 이미지 포맷 선택이 얼마나 중요한지 살펴봤다면,
이번 글에서는 **AWS Lambda와 S3 이벤트를 활용해 업로드 시점에서 자동으로 이미지 최적화**하는 방법을 다룹니다.
:::
@@ -17,7 +17,7 @@ comment: true
디자인학과 졸업전시 웹사이트를 만들면서, 이미지 때문에 꽤나 고생을 했습니다.
학생들이 주는 작품 사진은 대부분 몇 MB가 넘는 고화질의 원본이었고, 저는 그걸 웹에 맞게 리사이즈해서 올려야 했습니다.
-
+
처음에는 로컬에서 일일이 줄여 업로드했지만, 작품 수가 수십 개, 이미지가 수백 장을 넘어가자 상황은 달라졌습니다.
리사이즈 작업만으로도 반나절이 날아가고, 썸네일·포맷별 파일까지 관리하려니 점점 감당하기 힘들어졌습니다.
@@ -50,11 +50,11 @@ AWS Lambda는 서버를 직접 관리하지 않고도 코드를 실행할 수
그 다음, AWS Lambda 콘솔에서 새 Lambda 함수를 생성합니다.
-
+
아래쪽에 `구성` > `트리거` > `트리거 추가` 를 클릭해 S3 트리거를 설정합니다.
-
+
## Presigned URL 로 이미지 업로드 시점에 Lambda 트리거하기
diff --git a/contents/posts/CS/Algorithm/img/permutation-dfs.gif b/contents/posts/CS/Algorithm/permutation-combination/img/permutation-dfs.gif
similarity index 100%
rename from contents/posts/CS/Algorithm/img/permutation-dfs.gif
rename to contents/posts/CS/Algorithm/permutation-combination/img/permutation-dfs.gif
diff --git a/contents/posts/CS/Algorithm/img/permutation-swap.gif b/contents/posts/CS/Algorithm/permutation-combination/img/permutation-swap.gif
similarity index 100%
rename from contents/posts/CS/Algorithm/img/permutation-swap.gif
rename to contents/posts/CS/Algorithm/permutation-combination/img/permutation-swap.gif
diff --git a/contents/posts/CS/Algorithm/permutation-combination.md b/contents/posts/CS/Algorithm/permutation-combination/index.md
similarity index 100%
rename from contents/posts/CS/Algorithm/permutation-combination.md
rename to contents/posts/CS/Algorithm/permutation-combination/index.md
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/base-cas.jpeg b/contents/posts/CS/DataStructure/content-addressable-store/img/base-cas.jpeg
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/base-cas.jpeg
rename to contents/posts/CS/DataStructure/content-addressable-store/img/base-cas.jpeg
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/base-cas.png b/contents/posts/CS/DataStructure/content-addressable-store/img/base-cas.png
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/base-cas.png
rename to contents/posts/CS/DataStructure/content-addressable-store/img/base-cas.png
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/base-cas.webp b/contents/posts/CS/DataStructure/content-addressable-store/img/base-cas.webp
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/base-cas.webp
rename to contents/posts/CS/DataStructure/content-addressable-store/img/base-cas.webp
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/chunking-sharding.jpeg b/contents/posts/CS/DataStructure/content-addressable-store/img/chunking-sharding.jpeg
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/chunking-sharding.jpeg
rename to contents/posts/CS/DataStructure/content-addressable-store/img/chunking-sharding.jpeg
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/chunking-sharding.png b/contents/posts/CS/DataStructure/content-addressable-store/img/chunking-sharding.png
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/chunking-sharding.png
rename to contents/posts/CS/DataStructure/content-addressable-store/img/chunking-sharding.png
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/chunking-sharding.webp b/contents/posts/CS/DataStructure/content-addressable-store/img/chunking-sharding.webp
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/chunking-sharding.webp
rename to contents/posts/CS/DataStructure/content-addressable-store/img/chunking-sharding.webp
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hash-tree.jpeg b/contents/posts/CS/DataStructure/content-addressable-store/img/hash-tree.jpeg
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hash-tree.jpeg
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hash-tree.jpeg
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hash-tree.png b/contents/posts/CS/DataStructure/content-addressable-store/img/hash-tree.png
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hash-tree.png
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hash-tree.png
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hash-tree.webp b/contents/posts/CS/DataStructure/content-addressable-store/img/hash-tree.webp
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hash-tree.webp
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hash-tree.webp
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hash.jpeg b/contents/posts/CS/DataStructure/content-addressable-store/img/hash.jpeg
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hash.jpeg
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hash.jpeg
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hash.png b/contents/posts/CS/DataStructure/content-addressable-store/img/hash.png
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hash.png
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hash.png
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hash.webp b/contents/posts/CS/DataStructure/content-addressable-store/img/hash.webp
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hash.webp
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hash.webp
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hashmap-inconsistent.jpeg b/contents/posts/CS/DataStructure/content-addressable-store/img/hashmap-inconsistent.jpeg
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hashmap-inconsistent.jpeg
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hashmap-inconsistent.jpeg
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hashmap-inconsistent.png b/contents/posts/CS/DataStructure/content-addressable-store/img/hashmap-inconsistent.png
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hashmap-inconsistent.png
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hashmap-inconsistent.png
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/hashmap-inconsistent.webp b/contents/posts/CS/DataStructure/content-addressable-store/img/hashmap-inconsistent.webp
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/hashmap-inconsistent.webp
rename to contents/posts/CS/DataStructure/content-addressable-store/img/hashmap-inconsistent.webp
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/metadata-disk.jpeg b/contents/posts/CS/DataStructure/content-addressable-store/img/metadata-disk.jpeg
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/metadata-disk.jpeg
rename to contents/posts/CS/DataStructure/content-addressable-store/img/metadata-disk.jpeg
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/metadata-disk.png b/contents/posts/CS/DataStructure/content-addressable-store/img/metadata-disk.png
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/metadata-disk.png
rename to contents/posts/CS/DataStructure/content-addressable-store/img/metadata-disk.png
diff --git a/contents/posts/CS/DataStructure/img/content-addressable-store/metadata-disk.webp b/contents/posts/CS/DataStructure/content-addressable-store/img/metadata-disk.webp
similarity index 100%
rename from contents/posts/CS/DataStructure/img/content-addressable-store/metadata-disk.webp
rename to contents/posts/CS/DataStructure/content-addressable-store/img/metadata-disk.webp
diff --git a/contents/posts/CS/DataStructure/content-addressable-store.md b/contents/posts/CS/DataStructure/content-addressable-store/index.md
similarity index 93%
rename from contents/posts/CS/DataStructure/content-addressable-store.md
rename to contents/posts/CS/DataStructure/content-addressable-store/index.md
index 8285943..947ca79 100644
--- a/contents/posts/CS/DataStructure/content-addressable-store.md
+++ b/contents/posts/CS/DataStructure/content-addressable-store/index.md
@@ -27,7 +27,7 @@ CAS는 간단히 말해서 내용기반 식별입니다
여기서, CAS 가 주는 불변성이 매우 중요합니다
-
+
### 1️⃣ 동일내용 = 동일 키 (Deduplication)
@@ -61,7 +61,7 @@ const contentAddressableStore = new Map();
```
-
+
이것만으로도 CAS 의 기본 기능은 구현할 수 있습니다
@@ -85,7 +85,7 @@ const contentAddressableStore = new Map();
가 있습니다.
-
+
해시맵의 키로 Content 의 해시값을 사용하고,
@@ -117,7 +117,7 @@ ab12cd... -> ab/12cd...
Chunking 과 Prefix Sharding 을 함께 사용하면 다음과 같은 구조가 됩니다
-
+
## Hash Tree 를 이용한 내용 무결성 검증
@@ -131,7 +131,7 @@ Content Addressable Store 는 데이터를 `내용 기반 주소` 로 식별하
예를들어 데이터를 저장할때, metadata 는 메모리 (해시 맵) 에 저장됐지만, content 는 디스크 (BlobStorage) 에 저장이 안된 경우가 있을 수 있습니다
-
+
이런 경우 CAS 는 `주소 - 내용` 매핑이 깨지게 됩니다.
@@ -177,7 +177,7 @@ TCP 는 Checksum 을 두고 TLS 는 MAC(Message Authentication Code) 을 사용
- 리프 노드는 실제 데이터 블록의 해시값을 저장하고,
- 내부 노드는 자식 노드들의 해시값을 조합하여 해시값을 계산합니다
-
+
#### 🤔 Merkle Tree 로 무결성 검증이 어떻게 이루어질까 ?
diff --git a/contents/posts/CS/DataStructure/img/idempotency-hash-table/cart-hash-func.jpeg b/contents/posts/CS/DataStructure/idempotency-hash-table/img/cart-hash-func.jpeg
similarity index 100%
rename from contents/posts/CS/DataStructure/img/idempotency-hash-table/cart-hash-func.jpeg
rename to contents/posts/CS/DataStructure/idempotency-hash-table/img/cart-hash-func.jpeg
diff --git a/contents/posts/CS/DataStructure/img/idempotency-hash-table/cart-hash-func.png b/contents/posts/CS/DataStructure/idempotency-hash-table/img/cart-hash-func.png
similarity index 100%
rename from contents/posts/CS/DataStructure/img/idempotency-hash-table/cart-hash-func.png
rename to contents/posts/CS/DataStructure/idempotency-hash-table/img/cart-hash-func.png
diff --git a/contents/posts/CS/DataStructure/img/idempotency-hash-table/cart-hash-func.webp b/contents/posts/CS/DataStructure/idempotency-hash-table/img/cart-hash-func.webp
similarity index 100%
rename from contents/posts/CS/DataStructure/img/idempotency-hash-table/cart-hash-func.webp
rename to contents/posts/CS/DataStructure/idempotency-hash-table/img/cart-hash-func.webp
diff --git a/contents/posts/CS/DataStructure/idempotency-hash-table.md b/contents/posts/CS/DataStructure/idempotency-hash-table/index.md
similarity index 99%
rename from contents/posts/CS/DataStructure/idempotency-hash-table.md
rename to contents/posts/CS/DataStructure/idempotency-hash-table/index.md
index 46c8e72..f2bf135 100644
--- a/contents/posts/CS/DataStructure/idempotency-hash-table.md
+++ b/contents/posts/CS/DataStructure/idempotency-hash-table/index.md
@@ -135,7 +135,7 @@ const cartItem2 = {
> 같은 입력 = 샌드위치 id + 옵션 조합
> 같은 결과 = 장바구니 항목의 고유키
-
+
### 1️⃣ 단순 순회하면서 비교하기
diff --git a/contents/posts/Etc/img/2025-toss-interview/gemini.jpeg b/contents/posts/Etc/2025-toss-interview/img/gemini.jpeg
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/gemini.jpeg
rename to contents/posts/Etc/2025-toss-interview/img/gemini.jpeg
diff --git a/contents/posts/Etc/img/2025-toss-interview/gemini.png b/contents/posts/Etc/2025-toss-interview/img/gemini.png
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/gemini.png
rename to contents/posts/Etc/2025-toss-interview/img/gemini.png
diff --git a/contents/posts/Etc/img/2025-toss-interview/gemini.webp b/contents/posts/Etc/2025-toss-interview/img/gemini.webp
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/gemini.webp
rename to contents/posts/Etc/2025-toss-interview/img/gemini.webp
diff --git a/contents/posts/Etc/img/2025-toss-interview/study-1.webp b/contents/posts/Etc/2025-toss-interview/img/study-1.webp
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/study-1.webp
rename to contents/posts/Etc/2025-toss-interview/img/study-1.webp
diff --git a/contents/posts/Etc/img/2025-toss-interview/study-2.jpeg b/contents/posts/Etc/2025-toss-interview/img/study-2.jpeg
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/study-2.jpeg
rename to contents/posts/Etc/2025-toss-interview/img/study-2.jpeg
diff --git a/contents/posts/Etc/img/2025-toss-interview/study-2.png b/contents/posts/Etc/2025-toss-interview/img/study-2.png
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/study-2.png
rename to contents/posts/Etc/2025-toss-interview/img/study-2.png
diff --git a/contents/posts/Etc/img/2025-toss-interview/study-2.webp b/contents/posts/Etc/2025-toss-interview/img/study-2.webp
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/study-2.webp
rename to contents/posts/Etc/2025-toss-interview/img/study-2.webp
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-auth.jpeg b/contents/posts/Etc/2025-toss-interview/img/toss-auth.jpeg
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-auth.jpeg
rename to contents/posts/Etc/2025-toss-interview/img/toss-auth.jpeg
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-auth.png b/contents/posts/Etc/2025-toss-interview/img/toss-auth.png
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-auth.png
rename to contents/posts/Etc/2025-toss-interview/img/toss-auth.png
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-auth.webp b/contents/posts/Etc/2025-toss-interview/img/toss-auth.webp
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-auth.webp
rename to contents/posts/Etc/2025-toss-interview/img/toss-auth.webp
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-cta.jpeg b/contents/posts/Etc/2025-toss-interview/img/toss-cta.jpeg
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-cta.jpeg
rename to contents/posts/Etc/2025-toss-interview/img/toss-cta.jpeg
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-cta.png b/contents/posts/Etc/2025-toss-interview/img/toss-cta.png
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-cta.png
rename to contents/posts/Etc/2025-toss-interview/img/toss-cta.png
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-cta.webp b/contents/posts/Etc/2025-toss-interview/img/toss-cta.webp
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-cta.webp
rename to contents/posts/Etc/2025-toss-interview/img/toss-cta.webp
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-failed.jpeg b/contents/posts/Etc/2025-toss-interview/img/toss-failed.jpeg
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-failed.jpeg
rename to contents/posts/Etc/2025-toss-interview/img/toss-failed.jpeg
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-failed.png b/contents/posts/Etc/2025-toss-interview/img/toss-failed.png
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-failed.png
rename to contents/posts/Etc/2025-toss-interview/img/toss-failed.png
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-failed.webp b/contents/posts/Etc/2025-toss-interview/img/toss-failed.webp
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-failed.webp
rename to contents/posts/Etc/2025-toss-interview/img/toss-failed.webp
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-passed.jpeg b/contents/posts/Etc/2025-toss-interview/img/toss-passed.jpeg
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-passed.jpeg
rename to contents/posts/Etc/2025-toss-interview/img/toss-passed.jpeg
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-passed.png b/contents/posts/Etc/2025-toss-interview/img/toss-passed.png
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-passed.png
rename to contents/posts/Etc/2025-toss-interview/img/toss-passed.png
diff --git a/contents/posts/Etc/img/2025-toss-interview/toss-passed.webp b/contents/posts/Etc/2025-toss-interview/img/toss-passed.webp
similarity index 100%
rename from contents/posts/Etc/img/2025-toss-interview/toss-passed.webp
rename to contents/posts/Etc/2025-toss-interview/img/toss-passed.webp
diff --git a/contents/posts/Etc/2025-toss-interview.md b/contents/posts/Etc/2025-toss-interview/index.md
similarity index 93%
rename from contents/posts/Etc/2025-toss-interview.md
rename to contents/posts/Etc/2025-toss-interview/index.md
index f7965c3..c8c0bf7 100644
--- a/contents/posts/Etc/2025-toss-interview.md
+++ b/contents/posts/Etc/2025-toss-interview/index.md
@@ -22,7 +22,7 @@ head:
토스뱅크는 단순히 가기 어려운 회사가 아니라, 내가 되고 싶은 개발자의 모습이 담긴 회사였다
-[대학 시절 창업을 도전했다가 실패한 경험](./roomfit-failure.md) 이 있었는데, 그 과정에서 토스 이승건 대표님의 영상을 보고 많은 깨달음을 얻었다
+[대학 시절 창업을 도전했다가 실패한 경험](../roomfit-failure/) 이 있었는데, 그 과정에서 토스 이승건 대표님의 영상을 보고 많은 깨달음을 얻었다
그 과정에서 토스가 추구하는 가치관과 개발 문화가 나와 잘 맞는다는 생각이 들었고, 언젠가 꼭 토스에서 일하고 싶다는 목표를 가지게 되었다
특히 "사용자를 위해 불편을 부수는 집요함" 이라는 철학을 접했고, 내가 생각했던 개발자의 모습과도 일치했다.
@@ -32,8 +32,8 @@ head:
토스는 이걸 진짜 현실로 만들어낸 팀이라고 생각했다.
-
-
+
+
:::details [개발자를 성장시키는 토스의 개발 문화 3가지 | 박서진 토스 Head of Frontend | Square of Toss](https://www.youtube.com/watch?v=RzVABPt9f-g)
@@ -79,7 +79,7 @@ UX, 유지보수성, 아키텍쳐 각각에서 개발자경험과 사용자 경
모든 레포에 Gemini Code Assist를 붙여놓은 상태였는데, PR을 제출하고 나니 얘가 갑자기 크리티컬한 문제가 있다고 소리를 지르는것이었다
-
+
하... 떨어졌구나
@@ -90,7 +90,7 @@ UX, 유지보수성, 아키텍쳐 각각에서 개발자경험과 사용자 경
근데 며칠 뒤, 과제합격 메일이 도착했다
현실을 잠깐 의심했다. 진짜?? 아니 이게 진짜라고?
-
+
진짜 하루종일 이렇게 기쁠 수가 없었다.
@@ -101,7 +101,7 @@ UX, 유지보수성, 아키텍쳐 각각에서 개발자경험과 사용자 경
너무가고싶은 마음에 면접보기 전까지 쥐죽은듯이 공부했다.
근 몇달간 가장 집중을 많이하고 공부를 많이 했지 않나.. 싶다
-
+
## 😵 대망의 면접날 고해성사를 시작합니다
@@ -288,7 +288,7 @@ UX, 유지보수성, 아키텍쳐 각각에서 개발자경험과 사용자 경
## 🥲 다음 기회를 기약하며..
-
+
뭐... 결국은 불합격했다.
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/feedback.jpeg b/contents/posts/Etc/kakao-tech-campus-record/img/feedback.jpeg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/feedback.jpeg
rename to contents/posts/Etc/kakao-tech-campus-record/img/feedback.jpeg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/feedback.png b/contents/posts/Etc/kakao-tech-campus-record/img/feedback.png
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/feedback.png
rename to contents/posts/Etc/kakao-tech-campus-record/img/feedback.png
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/feedback.webp b/contents/posts/Etc/kakao-tech-campus-record/img/feedback.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/feedback.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/feedback.webp
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/ideathon-1.jpeg b/contents/posts/Etc/kakao-tech-campus-record/img/ideathon-1.jpeg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/ideathon-1.jpeg
rename to contents/posts/Etc/kakao-tech-campus-record/img/ideathon-1.jpeg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/ideathon-1.jpg b/contents/posts/Etc/kakao-tech-campus-record/img/ideathon-1.jpg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/ideathon-1.jpg
rename to contents/posts/Etc/kakao-tech-campus-record/img/ideathon-1.jpg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/ideathon-1.webp b/contents/posts/Etc/kakao-tech-campus-record/img/ideathon-1.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/ideathon-1.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/ideathon-1.webp
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/ideathon-2.jpeg b/contents/posts/Etc/kakao-tech-campus-record/img/ideathon-2.jpeg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/ideathon-2.jpeg
rename to contents/posts/Etc/kakao-tech-campus-record/img/ideathon-2.jpeg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/ideathon-2.jpg b/contents/posts/Etc/kakao-tech-campus-record/img/ideathon-2.jpg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/ideathon-2.jpg
rename to contents/posts/Etc/kakao-tech-campus-record/img/ideathon-2.jpg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/ideathon-2.webp b/contents/posts/Etc/kakao-tech-campus-record/img/ideathon-2.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/ideathon-2.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/ideathon-2.webp
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/lec-1.webp b/contents/posts/Etc/kakao-tech-campus-record/img/lec-1.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/lec-1.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/lec-1.webp
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/lec-2.webp b/contents/posts/Etc/kakao-tech-campus-record/img/lec-2.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/lec-2.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/lec-2.webp
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pass.jpeg b/contents/posts/Etc/kakao-tech-campus-record/img/pass.jpeg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pass.jpeg
rename to contents/posts/Etc/kakao-tech-campus-record/img/pass.jpeg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pass.png b/contents/posts/Etc/kakao-tech-campus-record/img/pass.png
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pass.png
rename to contents/posts/Etc/kakao-tech-campus-record/img/pass.png
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pass.webp b/contents/posts/Etc/kakao-tech-campus-record/img/pass.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pass.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/pass.webp
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pr-1.jpeg b/contents/posts/Etc/kakao-tech-campus-record/img/pr-1.jpeg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pr-1.jpeg
rename to contents/posts/Etc/kakao-tech-campus-record/img/pr-1.jpeg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pr-1.png b/contents/posts/Etc/kakao-tech-campus-record/img/pr-1.png
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pr-1.png
rename to contents/posts/Etc/kakao-tech-campus-record/img/pr-1.png
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pr-1.webp b/contents/posts/Etc/kakao-tech-campus-record/img/pr-1.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pr-1.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/pr-1.webp
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pr-2.jpeg b/contents/posts/Etc/kakao-tech-campus-record/img/pr-2.jpeg
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pr-2.jpeg
rename to contents/posts/Etc/kakao-tech-campus-record/img/pr-2.jpeg
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pr-2.png b/contents/posts/Etc/kakao-tech-campus-record/img/pr-2.png
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pr-2.png
rename to contents/posts/Etc/kakao-tech-campus-record/img/pr-2.png
diff --git a/contents/posts/Etc/img/kakao-tech-campus-record/pr-2.webp b/contents/posts/Etc/kakao-tech-campus-record/img/pr-2.webp
similarity index 100%
rename from contents/posts/Etc/img/kakao-tech-campus-record/pr-2.webp
rename to contents/posts/Etc/kakao-tech-campus-record/img/pr-2.webp
diff --git a/contents/posts/Etc/kakao-tech-campus-record.md b/contents/posts/Etc/kakao-tech-campus-record/index.md
similarity index 94%
rename from contents/posts/Etc/kakao-tech-campus-record.md
rename to contents/posts/Etc/kakao-tech-campus-record/index.md
index c80051c..528f181 100644
--- a/contents/posts/Etc/kakao-tech-campus-record.md
+++ b/contents/posts/Etc/kakao-tech-campus-record/index.md
@@ -18,7 +18,7 @@ head:
졸업을 위한 현장실습 대체 학점을 채워야 했고, 마침 카카오 테크캠퍼스가 그걸 채워줄 수 있었고, "어차피 할 거면 카카오 이름 달린 데서 하면 좋지" 정도의 마음가짐이었습니다
-
+
부트캠프에 대한 이미지도 솔직히 그렇게 좋진 않았습니다.
@@ -73,8 +73,8 @@ PR 을 올릴 때, 질문을 진짜 많이 적었고, 고민한 흔적 설계
리뷰해주시는 멘토님들이 꽤 고생을 많이 하셨을 것 같습니다 ㅋㅋㅋ
-
-
+
+
:::details 💬 멘토님과 함께한 코드리뷰 PR 모음
@@ -172,7 +172,7 @@ PR 을 올릴 때, 질문을 진짜 많이 적었고, 고민한 흔적 설계
실무에서 `generator` 많이 쓰시나요? 라고 여쭤봤는데 멘토님이 이렇게 답해주셨습니다.
-
+
좋은 코드는 단순히 변수명이 깔끔하고, 여러 설계원칙을 잘 지키는 그런 코드가 아니라
@@ -191,8 +191,8 @@ PR 을 올릴 때, 질문을 진짜 많이 적었고, 고민한 흔적 설계
아직 취업은 못했지만, 이런 사소해보이는 습관들이 저를 조금은 더 준비된 상태로 만들어줬다고 생각합니다 ㅎㅎ
-
-
+
+
특히 취업관련 특강, 기술특강, 서류작성 포트폴리오 방향성 등
@@ -208,6 +208,6 @@ PR 을 올릴 때, 질문을 진짜 많이 적었고, 고민한 흔적 설계
쫌 힘들고 아프고 그래야 성장하는 타입인것같습니다.. 약간 ~~마조히스트~~ 기질이 있는것 같기도 하고요
-
-
+
+
diff --git a/contents/posts/Etc/img/overcoming-difficult-times/image.jpeg b/contents/posts/Etc/overcoming-difficult-times/img/image.jpeg
similarity index 100%
rename from contents/posts/Etc/img/overcoming-difficult-times/image.jpeg
rename to contents/posts/Etc/overcoming-difficult-times/img/image.jpeg
diff --git a/contents/posts/Etc/img/overcoming-difficult-times/image.png b/contents/posts/Etc/overcoming-difficult-times/img/image.png
similarity index 100%
rename from contents/posts/Etc/img/overcoming-difficult-times/image.png
rename to contents/posts/Etc/overcoming-difficult-times/img/image.png
diff --git a/contents/posts/Etc/img/overcoming-difficult-times/image.webp b/contents/posts/Etc/overcoming-difficult-times/img/image.webp
similarity index 100%
rename from contents/posts/Etc/img/overcoming-difficult-times/image.webp
rename to contents/posts/Etc/overcoming-difficult-times/img/image.webp
diff --git a/contents/posts/Etc/overcoming-difficult-times.md b/contents/posts/Etc/overcoming-difficult-times/index.md
similarity index 98%
rename from contents/posts/Etc/overcoming-difficult-times.md
rename to contents/posts/Etc/overcoming-difficult-times/index.md
index cbb856e..6251ca7 100644
--- a/contents/posts/Etc/overcoming-difficult-times.md
+++ b/contents/posts/Etc/overcoming-difficult-times/index.md
@@ -62,7 +62,7 @@ head:
힘든것은 사실이지만, 그 이후에 어떤 태도를 선택할지는 결국 각자의 몫이다
-
+
diff --git a/contents/posts/Etc/roomfit-failure.md b/contents/posts/Etc/roomfit-failure/index.md
similarity index 100%
rename from contents/posts/Etc/roomfit-failure.md
rename to contents/posts/Etc/roomfit-failure/index.md
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-1.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-1.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-1.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-1.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-1.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-1.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-1.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-1.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-1.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-1.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-1.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-1.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-10.gif b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-10.gif
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-10.gif
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-10.gif
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-11.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-11.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-11.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-11.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-11.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-11.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-11.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-11.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-11.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-11.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-11.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-11.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-2.gif b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-2.gif
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-2.gif
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-2.gif
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-3.gif b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-3.gif
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-3.gif
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-3.gif
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-4.gif b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-4.gif
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-4.gif
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-4.gif
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-5.gif b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-5.gif
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-5.gif
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-5.gif
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-6.gif b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-6.gif
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-6.gif
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-6.gif
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-7.gif b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-7.gif
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-7.gif
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-7.gif
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-8.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-8.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-8.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-8.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-8.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-8.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-8.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-8.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-8.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-8.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-8.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-8.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-9.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-9.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-9.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-9.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-9.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-9.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-9.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-9.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-ec-example-9.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-9.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-ec-example-9.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-ec-example-9.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-0.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-0.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-0.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-0.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-0.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-0.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-0.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-0.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-0.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-0.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-0.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-0.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-1.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-1.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-1.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-1.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-1.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-1.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-1.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-1.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-1.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-1.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-1.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-1.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-2.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-2.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-2.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-2.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-2.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-2.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-2.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-2.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-2.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-2.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-2.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-2.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-3.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-3.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-3.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-3.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-3.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-3.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-3.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-3.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-3.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-3.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-3.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-3.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-overview.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-overview.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-overview.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-overview.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-overview.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-overview.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-overview.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-overview.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-overview.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-overview.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-overview.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-overview.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-realm.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-realm.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-realm.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-realm.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-realm.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-realm.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-realm.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-realm.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-realm.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-realm.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-realm.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-realm.webp
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-summary.jpeg b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-summary.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-summary.jpeg
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-summary.jpeg
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-summary.png b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-summary.png
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-summary.png
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-summary.png
diff --git a/contents/posts/JavaScript/img/execution-context/js-execution-context-summary.webp b/contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-summary.webp
similarity index 100%
rename from contents/posts/JavaScript/img/execution-context/js-execution-context-summary.webp
rename to contents/posts/JavaScript/js-execution-context-part1/img/js-execution-context-summary.webp
diff --git a/contents/posts/JavaScript/js-execution-context-part1.md b/contents/posts/JavaScript/js-execution-context-part1/index.md
similarity index 95%
rename from contents/posts/JavaScript/js-execution-context-part1.md
rename to contents/posts/JavaScript/js-execution-context-part1/index.md
index 82bea8c..0e0e551 100644
--- a/contents/posts/JavaScript/js-execution-context-part1.md
+++ b/contents/posts/JavaScript/js-execution-context-part1/index.md
@@ -12,7 +12,7 @@ comment: true
스코프 (Scope), 클로저 (Closure), this 바인딩까지 모두 실행 컨텍스트와 연관되어 있습니다.
-
+
실제 면접에서도 "자바스크립트의 실행 컨텍스트에 대해 설명해보세요"는 단골 질문입니다.
@@ -25,7 +25,7 @@ comment: true
## 🤔 실행 컨텍스트란 무엇인가?
-
+
우리가 JavaScript 코드를 작성하고 실행될 때, `import` `export` 를 통해 모듈 코드를 실행할때, 함수 호출을 할 때,
@@ -35,7 +35,7 @@ comment: true
## 🏗️ 실행 컨텍스트의 구성 요소
-
+
실행 컨텍스트는 크게 다음과 같은 요소로 구성되어 있습니다.
@@ -56,7 +56,7 @@ Realm 은 JavaScript 코드가 실행되는 독립된 (Isolated) 환경을 의
Realm 은 다음과 같은 요소로 구성되어 있습니다.
-
+
#### 1.1. Intrinsics (내장객체)
@@ -101,7 +101,7 @@ Environment Record 는 **식별자 바인딩**을 저장하는 객체입니다.
또한, 공통적으로 **상위 Environment Record 에 대한 참조를 저장**하는 `[[Outer Env Reference]]` 슬롯을 가집니다.
-
+
`Environment Record` 는 식별자를 어떻게 선언하느냐에 따라 `Lexical Environment` 와 `Variable Environment` 로 나뉩니다.
@@ -121,7 +121,7 @@ Variable Environment 는
### ⭐️ 실행컨텍스트의 구성요소 정리
-
+
정리하자면, 실행컨텍스트는
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.jpeg
new file mode 100644
index 0000000..59eb9fc
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.png
new file mode 100644
index 0000000..94c8495
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.webp
new file mode 100644
index 0000000..561e5c1
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-1.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-10.gif b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-10.gif
new file mode 100644
index 0000000..ba772e1
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-10.gif differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.jpeg
new file mode 100644
index 0000000..fa4dc14
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.png
new file mode 100644
index 0000000..5bbc7c1
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.webp
new file mode 100644
index 0000000..6b6ae6e
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-11.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-2.gif b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-2.gif
new file mode 100644
index 0000000..9b48f6a
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-2.gif differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-3.gif b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-3.gif
new file mode 100644
index 0000000..c18294d
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-3.gif differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-4.gif b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-4.gif
new file mode 100644
index 0000000..3bbf97d
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-4.gif differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-5.gif b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-5.gif
new file mode 100644
index 0000000..6f8687e
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-5.gif differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-6.gif b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-6.gif
new file mode 100644
index 0000000..53903be
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-6.gif differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-7.gif b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-7.gif
new file mode 100644
index 0000000..70ba515
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-7.gif differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.jpeg
new file mode 100644
index 0000000..812fc30
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.png
new file mode 100644
index 0000000..0b734e6
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.webp
new file mode 100644
index 0000000..b9ca020
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-8.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.jpeg
new file mode 100644
index 0000000..28ea709
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.png
new file mode 100644
index 0000000..e8deb85
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.webp
new file mode 100644
index 0000000..3d65127
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-ec-example-9.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.jpeg
new file mode 100644
index 0000000..131a415
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.png
new file mode 100644
index 0000000..15caa5e
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.webp
new file mode 100644
index 0000000..e10410e
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-0.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.jpeg
new file mode 100644
index 0000000..3adc613
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.png
new file mode 100644
index 0000000..4da2cdd
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.webp
new file mode 100644
index 0000000..221c44e
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-1.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.jpeg
new file mode 100644
index 0000000..e2aac70
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.png
new file mode 100644
index 0000000..fee5484
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.webp
new file mode 100644
index 0000000..0e3ac81
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-2.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.jpeg
new file mode 100644
index 0000000..1ac8edd
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.png
new file mode 100644
index 0000000..12552da
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.webp
new file mode 100644
index 0000000..f15c4c7
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-3.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.jpeg
new file mode 100644
index 0000000..ae8aa24
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.png
new file mode 100644
index 0000000..fb319e6
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.webp
new file mode 100644
index 0000000..d496317
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-overview.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.jpeg
new file mode 100644
index 0000000..1d37059
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.png
new file mode 100644
index 0000000..8bb47d2
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.webp
new file mode 100644
index 0000000..7912d81
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-realm.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.jpeg b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.jpeg
new file mode 100644
index 0000000..62d71b4
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.jpeg differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.png b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.png
new file mode 100644
index 0000000..3c4799b
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.png differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.webp b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.webp
new file mode 100644
index 0000000..5028ee5
Binary files /dev/null and b/contents/posts/JavaScript/js-execution-context-part2/img/js-execution-context-summary.webp differ
diff --git a/contents/posts/JavaScript/js-execution-context-part2.md b/contents/posts/JavaScript/js-execution-context-part2/index.md
similarity index 92%
rename from contents/posts/JavaScript/js-execution-context-part2.md
rename to contents/posts/JavaScript/js-execution-context-part2/index.md
index 51968ee..49d5e7b 100644
--- a/contents/posts/JavaScript/js-execution-context-part2.md
+++ b/contents/posts/JavaScript/js-execution-context-part2/index.md
@@ -8,12 +8,12 @@ comment: true
## 🤔 Recap
-이전 글에서는 [JavaScript 실행 컨텍스트의 개념과 구성요소, Creation Phase와 Execution Phase](./js-execution-context-part1.md)에 대해 알아보았습니다.
+이전 글에서는 [JavaScript 실행 컨텍스트의 개념과 구성요소, Creation Phase와 Execution Phase](../js-execution-context-part1/)에 대해 알아보았습니다.
다시 한번 정리하자면,
가장 먼저 스크립트가 로드되면, **Realm** 이 생성됩니다.
@@ -85,7 +85,7 @@ console.log(sayHello()); // "안녕하세요! 대건 김"
Realm 이 생성되면, **Global Execution Context** 가 생성(Creation Phase)됩니다.
-
+
Global Execution Context 의 `Lexical Environment` 는 Realm 의 `Global Environment Record` 의 `[[Declarative Record]]` 슬롯을 참조합니다.
@@ -98,7 +98,7 @@ Global Execution Context 의 `Lexical Environment` 는 Realm 의 `Global Environ
Creation Phase 에서는 식별자들을 스캔하여 메모리 공간을 예약합니다.
-
+
> 1. `message` : `var` 키워드로 선언되었으므로, `Variable Environment Record` 에 등록되고 `undefined` 로 초기화됩니다.
@@ -111,14 +111,14 @@ Creation Phase 에서는 식별자들을 스캔하여 메모리 공간을 예약
### 3. Global Execution Context - Execution Phase
-
+
Creation Phase 가 끝나면, 실제 코드가 실행되는 **Execution Phase** 가 실행됩니다
생성된 Global Execution Context 는 콜스택에 쌓이고, 실행됩니다.
-
+
> 1. `message` : "안녕하세요! " 문자열이 Heap 영역에 생성되고, `message` 변수는 해당 값을 가리킵니다.
@@ -136,7 +136,7 @@ Function Execution Context 또한 Creation Phase 와 Execution Phase 를 거칩
### 4. greet Function Execution Context - Creation Phase
-
+
`greet` 함수가 호출되기위해 **greet Function Execution Context** 의 Creation Phase 가 시작됩니다.
@@ -151,7 +151,7 @@ Function Execution Context 또한 Creation Phase 와 Execution Phase 를 거칩
`greet` 함수의 Execution Context Creation Phase 가 끝났으므로, 콜스택에 쌓이고, Execution Phase 가 시작됩니다.
-
+
> 1. `person` : `new Person(firstName, lastName)` 를 통해 `Person` 클래스의 인스턴스가 생성되고, `person` 변수는 해당 인스턴스를 가리킵니다.
@@ -163,7 +163,7 @@ Function Execution Context 또한 Creation Phase 와 Execution Phase 를 거칩
### 6. Global Execution Context - Execution Phase (계속)
-
+
`greet` 함수의 Execution Phase 가 끝나고, `sayHello` 변수에 `createGreetingMessage` 함수 객체가 바인딩됩니다.
@@ -172,7 +172,7 @@ Function Execution Context 또한 Creation Phase 와 Execution Phase 를 거칩
### 7. createGreetingMessage Function Execution Context - Creation Phase
-
+
`createGreetingMessage` 함수가 호출되기위해 **createGreetingMessage Function Execution Context** 의 Creation Phase 가 시작됩니다.
@@ -185,7 +185,7 @@ Function Execution Context 또한 Creation Phase 와 Execution Phase 를 거칩
`createGreetingMessage` 함수의 Execution Context Creation Phase 가 끝났으므로, 콜스택에 쌓이고, Execution Phase 가 시작됩니다.
-
+
> 1. `baseGreetMessage` : (‼️ 4-3 에서 생성된 Closure 를 통해) `greet` 함수의 `Lexical Environment` 에 접근하여, `baseGreetMessage` 는 "안녕하세요! " 가 됩니다
@@ -197,7 +197,7 @@ Function Execution Context 또한 Creation Phase 와 Execution Phase 를 거칩
### 9. Global Execution Context - Execution Phase (계속)
-
+
> 1. `console` : `console` 식별자를 찾기위해 Global Execution Context 의 `Lexical Environment` 를 참조하고, 이는 Global Object 를 참조합니다.
diff --git a/contents/posts/JavaScript/img/js-immutability/primitive.jpeg b/contents/posts/JavaScript/js-immutability/img/primitive.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/js-immutability/primitive.jpeg
rename to contents/posts/JavaScript/js-immutability/img/primitive.jpeg
diff --git a/contents/posts/JavaScript/img/js-immutability/primitive.png b/contents/posts/JavaScript/js-immutability/img/primitive.png
similarity index 100%
rename from contents/posts/JavaScript/img/js-immutability/primitive.png
rename to contents/posts/JavaScript/js-immutability/img/primitive.png
diff --git a/contents/posts/JavaScript/img/js-immutability/primitive.webp b/contents/posts/JavaScript/js-immutability/img/primitive.webp
similarity index 100%
rename from contents/posts/JavaScript/img/js-immutability/primitive.webp
rename to contents/posts/JavaScript/js-immutability/img/primitive.webp
diff --git a/contents/posts/JavaScript/img/js-immutability/reference.jpeg b/contents/posts/JavaScript/js-immutability/img/reference.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/js-immutability/reference.jpeg
rename to contents/posts/JavaScript/js-immutability/img/reference.jpeg
diff --git a/contents/posts/JavaScript/img/js-immutability/reference.png b/contents/posts/JavaScript/js-immutability/img/reference.png
similarity index 100%
rename from contents/posts/JavaScript/img/js-immutability/reference.png
rename to contents/posts/JavaScript/js-immutability/img/reference.png
diff --git a/contents/posts/JavaScript/img/js-immutability/reference.webp b/contents/posts/JavaScript/js-immutability/img/reference.webp
similarity index 100%
rename from contents/posts/JavaScript/img/js-immutability/reference.webp
rename to contents/posts/JavaScript/js-immutability/img/reference.webp
diff --git a/contents/posts/JavaScript/js-immutability.md b/contents/posts/JavaScript/js-immutability/index.md
similarity index 98%
rename from contents/posts/JavaScript/js-immutability.md
rename to contents/posts/JavaScript/js-immutability/index.md
index 582e0fe..a9d24e8 100644
--- a/contents/posts/JavaScript/js-immutability.md
+++ b/contents/posts/JavaScript/js-immutability/index.md
@@ -54,7 +54,7 @@ num = 20; // ✅ 새로운 숫자 재할당
console.log(num); // 20
```
-
+
```ts
let str = "hello";
@@ -80,7 +80,7 @@ obj.a = 10; // ✅ 내부 프로퍼티 변경
console.log(obj); // { a: 10, b: 2 }
```
-
+
```ts
const user = { name: "Alice", age: 25 };
diff --git a/contents/posts/JavaScript/img/js-object-1.jpeg b/contents/posts/JavaScript/js-object-comparison/img/js-object-1.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/js-object-1.jpeg
rename to contents/posts/JavaScript/js-object-comparison/img/js-object-1.jpeg
diff --git a/contents/posts/JavaScript/img/js-object-1.png b/contents/posts/JavaScript/js-object-comparison/img/js-object-1.png
similarity index 100%
rename from contents/posts/JavaScript/img/js-object-1.png
rename to contents/posts/JavaScript/js-object-comparison/img/js-object-1.png
diff --git a/contents/posts/JavaScript/img/js-object-1.webp b/contents/posts/JavaScript/js-object-comparison/img/js-object-1.webp
similarity index 100%
rename from contents/posts/JavaScript/img/js-object-1.webp
rename to contents/posts/JavaScript/js-object-comparison/img/js-object-1.webp
diff --git a/contents/posts/JavaScript/js-object-comparison.md b/contents/posts/JavaScript/js-object-comparison/index.md
similarity index 100%
rename from contents/posts/JavaScript/js-object-comparison.md
rename to contents/posts/JavaScript/js-object-comparison/index.md
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/chatgpt-event-stream.jpeg b/contents/posts/JavaScript/server-sent-event-generator/img/chatgpt-event-stream.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/chatgpt-event-stream.jpeg
rename to contents/posts/JavaScript/server-sent-event-generator/img/chatgpt-event-stream.jpeg
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/chatgpt-event-stream.png b/contents/posts/JavaScript/server-sent-event-generator/img/chatgpt-event-stream.png
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/chatgpt-event-stream.png
rename to contents/posts/JavaScript/server-sent-event-generator/img/chatgpt-event-stream.png
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/chatgpt-event-stream.webp b/contents/posts/JavaScript/server-sent-event-generator/img/chatgpt-event-stream.webp
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/chatgpt-event-stream.webp
rename to contents/posts/JavaScript/server-sent-event-generator/img/chatgpt-event-stream.webp
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/chatgpt.jpeg b/contents/posts/JavaScript/server-sent-event-generator/img/chatgpt.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/chatgpt.jpeg
rename to contents/posts/JavaScript/server-sent-event-generator/img/chatgpt.jpeg
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/chatgpt.png b/contents/posts/JavaScript/server-sent-event-generator/img/chatgpt.png
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/chatgpt.png
rename to contents/posts/JavaScript/server-sent-event-generator/img/chatgpt.png
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/chatgpt.webp b/contents/posts/JavaScript/server-sent-event-generator/img/chatgpt.webp
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/chatgpt.webp
rename to contents/posts/JavaScript/server-sent-event-generator/img/chatgpt.webp
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/sse.jpeg b/contents/posts/JavaScript/server-sent-event-generator/img/sse.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/sse.jpeg
rename to contents/posts/JavaScript/server-sent-event-generator/img/sse.jpeg
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/sse.png b/contents/posts/JavaScript/server-sent-event-generator/img/sse.png
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/sse.png
rename to contents/posts/JavaScript/server-sent-event-generator/img/sse.png
diff --git a/contents/posts/JavaScript/img/server-sent-event-generator/sse.webp b/contents/posts/JavaScript/server-sent-event-generator/img/sse.webp
similarity index 100%
rename from contents/posts/JavaScript/img/server-sent-event-generator/sse.webp
rename to contents/posts/JavaScript/server-sent-event-generator/img/sse.webp
diff --git a/contents/posts/JavaScript/server-sent-event-generator.md b/contents/posts/JavaScript/server-sent-event-generator/index.md
similarity index 98%
rename from contents/posts/JavaScript/server-sent-event-generator.md
rename to contents/posts/JavaScript/server-sent-event-generator/index.md
index 879a00f..0003487 100644
--- a/contents/posts/JavaScript/server-sent-event-generator.md
+++ b/contents/posts/JavaScript/server-sent-event-generator/index.md
@@ -13,8 +13,8 @@ head:
GPT, Gemini, Claude 등 다양한 LLM 모델들이 등장하면서, 이 모델들과 상호작용하는 방법도 다양해지고 있습니다. 특히, 서버에서 클라이언트로 실시간으로 데이터를 푸시하는 `Server Sent Events (SSE)` 는 LLM 의 스트리밍 응답을 처리하는데 유용한 기술입니다.
-
-
+
+
그렇다면 먼저 `Server Sent Events` 는 뭔지 알아보겠습니다
@@ -24,7 +24,7 @@ GPT, Gemini, Claude 등 다양한 LLM 모델들이 등장하면서, 이 모델
> Server Sent Events(SSE) 는 서버가 클라이언트(브라우저)에 단방향으로 지속적으로 데이터를 push 할 수 있게 해주는 기술
-
+
SSE 는 HTTP 프로토콜을 기반으로 하고, 클라이언트가 서버에 연결을 열면 서버는 이벤트 스트림을 통해 데이터를 지속적으로 전송할 수 있습니다. 클라이언트는 `EventSource` API 나 `fetch` API 를 사용하여 SSE 스트림에 연결할 수 있습니다.
diff --git a/contents/posts/JavaScript/img/v8-pointer-compression-1.jpeg b/contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-1.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/v8-pointer-compression-1.jpeg
rename to contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-1.jpeg
diff --git a/contents/posts/JavaScript/img/v8-pointer-compression-1.png b/contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-1.png
similarity index 100%
rename from contents/posts/JavaScript/img/v8-pointer-compression-1.png
rename to contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-1.png
diff --git a/contents/posts/JavaScript/img/v8-pointer-compression-1.webp b/contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-1.webp
similarity index 100%
rename from contents/posts/JavaScript/img/v8-pointer-compression-1.webp
rename to contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-1.webp
diff --git a/contents/posts/JavaScript/img/v8-pointer-compression-2.jpeg b/contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-2.jpeg
similarity index 100%
rename from contents/posts/JavaScript/img/v8-pointer-compression-2.jpeg
rename to contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-2.jpeg
diff --git a/contents/posts/JavaScript/img/v8-pointer-compression-2.png b/contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-2.png
similarity index 100%
rename from contents/posts/JavaScript/img/v8-pointer-compression-2.png
rename to contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-2.png
diff --git a/contents/posts/JavaScript/img/v8-pointer-compression-2.webp b/contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-2.webp
similarity index 100%
rename from contents/posts/JavaScript/img/v8-pointer-compression-2.webp
rename to contents/posts/JavaScript/v8-how-the-value-stored/img/v8-pointer-compression-2.webp
diff --git a/contents/posts/JavaScript/v8-how-the-value-stored.md b/contents/posts/JavaScript/v8-how-the-value-stored/index.md
similarity index 100%
rename from contents/posts/JavaScript/v8-how-the-value-stored.md
rename to contents/posts/JavaScript/v8-how-the-value-stored/index.md
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-1.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-1.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-1.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-1.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-1.png b/contents/posts/Next/next-rendering-patterns/img/image-1.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-1.png
rename to contents/posts/Next/next-rendering-patterns/img/image-1.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-1.webp b/contents/posts/Next/next-rendering-patterns/img/image-1.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-1.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-1.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-10.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-10.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-10.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-10.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-10.png b/contents/posts/Next/next-rendering-patterns/img/image-10.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-10.png
rename to contents/posts/Next/next-rendering-patterns/img/image-10.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-10.webp b/contents/posts/Next/next-rendering-patterns/img/image-10.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-10.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-10.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-11.gif b/contents/posts/Next/next-rendering-patterns/img/image-11.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-11.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-11.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-12.gif b/contents/posts/Next/next-rendering-patterns/img/image-12.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-12.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-12.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-13.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-13.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-13.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-13.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-13.png b/contents/posts/Next/next-rendering-patterns/img/image-13.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-13.png
rename to contents/posts/Next/next-rendering-patterns/img/image-13.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-13.webp b/contents/posts/Next/next-rendering-patterns/img/image-13.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-13.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-13.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-14.gif b/contents/posts/Next/next-rendering-patterns/img/image-14.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-14.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-14.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-15.gif b/contents/posts/Next/next-rendering-patterns/img/image-15.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-15.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-15.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-16.gif b/contents/posts/Next/next-rendering-patterns/img/image-16.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-16.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-16.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-17.gif b/contents/posts/Next/next-rendering-patterns/img/image-17.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-17.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-17.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-18.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-18.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-18.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-18.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-18.png b/contents/posts/Next/next-rendering-patterns/img/image-18.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-18.png
rename to contents/posts/Next/next-rendering-patterns/img/image-18.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-18.webp b/contents/posts/Next/next-rendering-patterns/img/image-18.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-18.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-18.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-19.gif b/contents/posts/Next/next-rendering-patterns/img/image-19.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-19.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-19.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-2.gif b/contents/posts/Next/next-rendering-patterns/img/image-2.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-2.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-2.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-20.gif b/contents/posts/Next/next-rendering-patterns/img/image-20.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-20.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-20.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-21.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-21.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-21.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-21.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-21.png b/contents/posts/Next/next-rendering-patterns/img/image-21.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-21.png
rename to contents/posts/Next/next-rendering-patterns/img/image-21.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-21.webp b/contents/posts/Next/next-rendering-patterns/img/image-21.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-21.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-21.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-22.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-22.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-22.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-22.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-22.png b/contents/posts/Next/next-rendering-patterns/img/image-22.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-22.png
rename to contents/posts/Next/next-rendering-patterns/img/image-22.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-22.webp b/contents/posts/Next/next-rendering-patterns/img/image-22.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-22.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-22.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-3.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-3.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-3.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-3.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-3.png b/contents/posts/Next/next-rendering-patterns/img/image-3.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-3.png
rename to contents/posts/Next/next-rendering-patterns/img/image-3.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-3.webp b/contents/posts/Next/next-rendering-patterns/img/image-3.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-3.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-3.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-4.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-4.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-4.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-4.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-4.png b/contents/posts/Next/next-rendering-patterns/img/image-4.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-4.png
rename to contents/posts/Next/next-rendering-patterns/img/image-4.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-4.webp b/contents/posts/Next/next-rendering-patterns/img/image-4.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-4.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-4.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-5.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-5.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-5.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-5.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-5.png b/contents/posts/Next/next-rendering-patterns/img/image-5.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-5.png
rename to contents/posts/Next/next-rendering-patterns/img/image-5.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-5.webp b/contents/posts/Next/next-rendering-patterns/img/image-5.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-5.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-5.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-6.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-6.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-6.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-6.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-6.png b/contents/posts/Next/next-rendering-patterns/img/image-6.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-6.png
rename to contents/posts/Next/next-rendering-patterns/img/image-6.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-6.webp b/contents/posts/Next/next-rendering-patterns/img/image-6.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-6.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-6.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-7.gif b/contents/posts/Next/next-rendering-patterns/img/image-7.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-7.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-7.gif
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-8.jpeg b/contents/posts/Next/next-rendering-patterns/img/image-8.jpeg
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-8.jpeg
rename to contents/posts/Next/next-rendering-patterns/img/image-8.jpeg
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-8.png b/contents/posts/Next/next-rendering-patterns/img/image-8.png
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-8.png
rename to contents/posts/Next/next-rendering-patterns/img/image-8.png
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-8.webp b/contents/posts/Next/next-rendering-patterns/img/image-8.webp
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-8.webp
rename to contents/posts/Next/next-rendering-patterns/img/image-8.webp
diff --git a/contents/posts/Next/img/next-rendering-patterns/image-9.gif b/contents/posts/Next/next-rendering-patterns/img/image-9.gif
similarity index 100%
rename from contents/posts/Next/img/next-rendering-patterns/image-9.gif
rename to contents/posts/Next/next-rendering-patterns/img/image-9.gif
diff --git a/contents/posts/Next/next-rendering-patterns.md b/contents/posts/Next/next-rendering-patterns/index.md
similarity index 90%
rename from contents/posts/Next/next-rendering-patterns.md
rename to contents/posts/Next/next-rendering-patterns/index.md
index 9fa9e6a..2d222e6 100644
--- a/contents/posts/Next/next-rendering-patterns.md
+++ b/contents/posts/Next/next-rendering-patterns/index.md
@@ -10,7 +10,7 @@ comment: true
## ✍️ NextJS 란 ?
-
+
NextJS 는 무엇일까요? NextJS 공식 웹사이트에 들어가면
@@ -31,7 +31,7 @@ NextJS 는 리액트 기반의 웹 프레임워크이기 때문에 다음과 같
그렇다면 NextJS 의 렌더링 패턴을 자세히 알아보기에 앞서, 렌더링(Rendering) 이 무엇인지 알아보겠습니다
-
+
우리가 브라우저에서 유튜브에 접속하는 상황을 가정해보도록 하겠습니다
@@ -47,7 +47,7 @@ WAS (Web Application Server) 가 데이터베이스와 정보를 주고받으며
### Construction 단계
-
+
먼저 브라우저는
@@ -62,7 +62,7 @@ WAS (Web Application Server) 가 데이터베이스와 정보를 주고받으며
### Operation 단계
-
+
다음으로 Render Tree 의 노드를 표시할 위치를 결정하는 Layout 단계와, Render Tree 를 순회하며 Node 를 그리는 Paint 단계를 거쳐,
@@ -76,9 +76,9 @@ z-index 가 낮은 요소부터 차례로 레이어를 구성하는 composition
본격적으로 렌더링 패턴들에 대해 알아보기에 앞서서,
구글에서 제안하는 웹 페이지들의 사용자 경험을 평가하는 지표인 Core Web Vitals 에 대해 잠깐 알아보겠습니다
-
+
-
+
## ✍️ Rendering Patterns
@@ -90,12 +90,12 @@ z-index 가 낮은 요소부터 차례로 레이어를 구성하는 composition
초기에 웹은 정적인 컨텐츠를 보여주는것에 그쳤습니다.
-
+
클라이언트가 특정 페이지에 접속하면, 정적인 HTML, CSS, JS 를 제공합니다.
AWS S3 버킷과 같은 저장소에 올리거나, NginX 등을 사용해 정적인 페이지는 서빙됩니다
-
+
Static Site 를 Core Web Vitals 관점에서 보면,
@@ -106,7 +106,7 @@ Static Site 를 Core Web Vitals 관점에서 보면,
### Server Side Rendering (SSR)
-
+
다음으로는 서버사이드 렌더링입니다.
@@ -115,7 +115,7 @@ Static Site 를 Core Web Vitals 관점에서 보면,
요청에 따라 서버에서 데이터를 삽입한 완성된 HTML 을 클라이언트에게 제공합니다.
JSP, TimeLeaf, HandleBars 등과 같은 템플릿 엔진을 사용해 구현할 수 있습니다.
-
+
Static Site 와 동일하게 TTI 와 FCP 가 동일하다는 점과 SEO 에 좋다는 장점이 있습니다.
@@ -129,8 +129,8 @@ AJAX 라는 기술이 나오게 되면서 새로고침 없이 동적으로 데
이에 따라 React, Angular, Vue 와 같은 라이브러리가 발전하여 앱과같은 부드러운 화면 전환이 가능해졌습니다
-
-
+
+
페이지를 요청하면, HTML 과 CSS 를 받고,
빌드된 JS 번들 파일을 응답으로 받습니다
@@ -138,7 +138,7 @@ AJAX 라는 기술이 나오게 되면서 새로고침 없이 동적으로 데
이후, 클라이언트 측에서 JS (React) 를 사용해 DOM 요소를 삽입하고 조작하며 렌더링을 진행하고,
AJAX 요청을보내서 서버로부터 동적인 데이터를 받아옵니다
-
+
앱처럼 부드러운 전환과 상호작용으로 UX 에 좋지만,
검색엔진 크롤링 봇이 텅 빈 HTML 을 크롤링하기 때문에 검색엔진 최적화 SEO 에 좋지 못합니다
@@ -151,7 +151,7 @@ FCP 와 TTI 의 차이가 크기 때문에, 사용자가 페이지가 로드되
먼저 SSR with Hydration 입니다.
-
+
이름에서 알 수 있듯이, 앞서 봤던 SSR 과 유사하게 동작합니다
@@ -160,7 +160,7 @@ API 요청을 보내 데이터를 삽입 후, 완성된 HTML 을 응답으로
여기까지는 SSR 과 동일합니다
-
+
이후, 추가적으로 React 코드가 클라이언트로 함께 전송되어 `Hydration` 이 진행됩니다
@@ -175,14 +175,14 @@ SSR with Hydration 과 유사하나,
요청마다 서버에서 렌더링을 진행하는 것이 아닌,
빌드시간에 변하지 않는 부분은 HTML 로 생성해두고
-
+
이후, React 코드가 연결되는 Hydration 이 진행되고,
API 요청은 AJAX 를 통해 진행됩니다
-
+
-
+
두 렌더링 패턴 모두 검색엔진 최적화에 좋지만,
TTFB 가 느리다는 단점이 있습니다
@@ -193,23 +193,23 @@ TTFB 가 느리다는 단점이 있습니다
SSR with Hydration 과 SSG with Hydration 을 합친 렌더링 패턴이라고 볼 수 있습니다
-
+
빌드타임에 리액트를 사용해 사전렌더링된 HTML 을 캐싱하고 (SSG with Hydration 과 유사) 응답으로 제공합니다
-
+
이후, 요청이 발생하고 캐시가 유효하지 않을때 (만료 되었을때, revalidate 시간 지정)
서버에서 개별 페이지를 재생성하여 캐싱합니다
-
+
캐싱된 페이지에 대해서는 TTFB 가 빠르다는 장점이 있지만,
데이터가 자주 바뀌는 사이트에서는 적합하지 않습니다.
## ✍️ 마치며
-
+
그래서 좋은 렌더링 패턴은 뭐고, 뭘 써야한다 라고 묻는다면,
딱히 정해진 좋은 패턴은 없습니다.
diff --git a/contents/posts/ProblemSolving/img/baekjoon-tip-for-nodejs/image.jpeg b/contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/img/image.jpeg
similarity index 100%
rename from contents/posts/ProblemSolving/img/baekjoon-tip-for-nodejs/image.jpeg
rename to contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/img/image.jpeg
diff --git a/contents/posts/ProblemSolving/img/baekjoon-tip-for-nodejs/image.png b/contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/img/image.png
similarity index 100%
rename from contents/posts/ProblemSolving/img/baekjoon-tip-for-nodejs/image.png
rename to contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/img/image.png
diff --git a/contents/posts/ProblemSolving/img/baekjoon-tip-for-nodejs/image.webp b/contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/img/image.webp
similarity index 100%
rename from contents/posts/ProblemSolving/img/baekjoon-tip-for-nodejs/image.webp
rename to contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/img/image.webp
diff --git a/contents/posts/ProblemSolving/baekjoon-tip-for-nodejs.md b/contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/index.md
similarity index 99%
rename from contents/posts/ProblemSolving/baekjoon-tip-for-nodejs.md
rename to contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/index.md
index eb3e52c..9cccb6e 100644
--- a/contents/posts/ProblemSolving/baekjoon-tip-for-nodejs.md
+++ b/contents/posts/ProblemSolving/baekjoon-tip-for-nodejs/index.md
@@ -33,7 +33,7 @@ let input = fs
[Competitive Programming Helper](https://marketplace.visualstudio.com/items?itemName=DivyanshuAgrawal.competitive-programming-helper) Extension 을 사용하면 따로 `process.platform` 을 확인하지 않고도 여러 테스트케이스에 대해 출력값을 쉽게 확인할 수 있습니다.
-
+
:::
diff --git a/contents/posts/React/img/build-react-1/dumb.jpeg b/contents/posts/React/build-react-1/img/dumb.jpeg
similarity index 100%
rename from contents/posts/React/img/build-react-1/dumb.jpeg
rename to contents/posts/React/build-react-1/img/dumb.jpeg
diff --git a/contents/posts/React/img/build-react-1/dumb.png b/contents/posts/React/build-react-1/img/dumb.png
similarity index 100%
rename from contents/posts/React/img/build-react-1/dumb.png
rename to contents/posts/React/build-react-1/img/dumb.png
diff --git a/contents/posts/React/img/build-react-1/dumb.webp b/contents/posts/React/build-react-1/img/dumb.webp
similarity index 100%
rename from contents/posts/React/img/build-react-1/dumb.webp
rename to contents/posts/React/build-react-1/img/dumb.webp
diff --git a/contents/posts/React/build-react-1.md b/contents/posts/React/build-react-1/index.md
similarity index 98%
rename from contents/posts/React/build-react-1.md
rename to contents/posts/React/build-react-1/index.md
index 17fef5e..adaf010 100644
--- a/contents/posts/React/build-react-1.md
+++ b/contents/posts/React/build-react-1/index.md
@@ -39,7 +39,7 @@ HTML 처럼 보이지만 실제로는 JavaScript 를 확장한 문법입니다.
그래서 브라우저는 JSX 를 이해하지 못해요 ㅠㅠ
-
+
### 🚀 JSX 는 어떻게 동작하는데 ?
diff --git a/contents/posts/React/constellation-impl/img/coordinate.jpeg b/contents/posts/React/constellation-impl/img/coordinate.jpeg
new file mode 100644
index 0000000..f341ff9
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/coordinate.jpeg differ
diff --git a/contents/posts/React/constellation-impl/img/coordinate.png b/contents/posts/React/constellation-impl/img/coordinate.png
new file mode 100644
index 0000000..2aaa2d5
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/coordinate.png differ
diff --git a/contents/posts/React/constellation-impl/img/coordinate.webp b/contents/posts/React/constellation-impl/img/coordinate.webp
new file mode 100644
index 0000000..2195605
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/coordinate.webp differ
diff --git a/contents/posts/React/constellation-impl/img/design-after.jpeg b/contents/posts/React/constellation-impl/img/design-after.jpeg
new file mode 100644
index 0000000..ec683c2
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/design-after.jpeg differ
diff --git a/contents/posts/React/constellation-impl/img/design-after.png b/contents/posts/React/constellation-impl/img/design-after.png
new file mode 100644
index 0000000..cd75c08
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/design-after.png differ
diff --git a/contents/posts/React/constellation-impl/img/design-after.webp b/contents/posts/React/constellation-impl/img/design-after.webp
new file mode 100644
index 0000000..82ae193
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/design-after.webp differ
diff --git a/contents/posts/React/constellation-impl/img/design-before.jpeg b/contents/posts/React/constellation-impl/img/design-before.jpeg
new file mode 100644
index 0000000..15bbc32
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/design-before.jpeg differ
diff --git a/contents/posts/React/constellation-impl/img/design-before.png b/contents/posts/React/constellation-impl/img/design-before.png
new file mode 100644
index 0000000..40e9950
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/design-before.png differ
diff --git a/contents/posts/React/constellation-impl/img/design-before.webp b/contents/posts/React/constellation-impl/img/design-before.webp
new file mode 100644
index 0000000..478da78
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/design-before.webp differ
diff --git a/contents/posts/React/constellation-impl/img/devtools.gif b/contents/posts/React/constellation-impl/img/devtools.gif
new file mode 100644
index 0000000..7ad17fb
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/devtools.gif differ
diff --git a/contents/posts/React/constellation-impl/img/image-1.jpeg b/contents/posts/React/constellation-impl/img/image-1.jpeg
new file mode 100644
index 0000000..7280aed
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/image-1.jpeg differ
diff --git a/contents/posts/React/constellation-impl/img/image-1.png b/contents/posts/React/constellation-impl/img/image-1.png
new file mode 100644
index 0000000..d81b850
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/image-1.png differ
diff --git a/contents/posts/React/constellation-impl/img/image-1.webp b/contents/posts/React/constellation-impl/img/image-1.webp
new file mode 100644
index 0000000..473a0c5
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/image-1.webp differ
diff --git a/contents/posts/React/constellation-impl/img/image.jpeg b/contents/posts/React/constellation-impl/img/image.jpeg
new file mode 100644
index 0000000..9dad4fb
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/image.jpeg differ
diff --git a/contents/posts/React/constellation-impl/img/image.png b/contents/posts/React/constellation-impl/img/image.png
new file mode 100644
index 0000000..bc52481
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/image.png differ
diff --git a/contents/posts/React/constellation-impl/img/image.webp b/contents/posts/React/constellation-impl/img/image.webp
new file mode 100644
index 0000000..302446b
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/image.webp differ
diff --git a/contents/posts/React/constellation-impl/img/layer-perspective.jpeg b/contents/posts/React/constellation-impl/img/layer-perspective.jpeg
new file mode 100644
index 0000000..b4678ab
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/layer-perspective.jpeg differ
diff --git a/contents/posts/React/constellation-impl/img/layer-perspective.png b/contents/posts/React/constellation-impl/img/layer-perspective.png
new file mode 100644
index 0000000..1760038
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/layer-perspective.png differ
diff --git a/contents/posts/React/constellation-impl/img/layer-perspective.webp b/contents/posts/React/constellation-impl/img/layer-perspective.webp
new file mode 100644
index 0000000..4fc9791
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/layer-perspective.webp differ
diff --git a/contents/posts/React/constellation-impl/img/math.jpeg b/contents/posts/React/constellation-impl/img/math.jpeg
new file mode 100644
index 0000000..44be5b7
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/math.jpeg differ
diff --git a/contents/posts/React/constellation-impl/img/math.png b/contents/posts/React/constellation-impl/img/math.png
new file mode 100644
index 0000000..b267122
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/math.png differ
diff --git a/contents/posts/React/constellation-impl/img/math.webp b/contents/posts/React/constellation-impl/img/math.webp
new file mode 100644
index 0000000..cdbf94a
Binary files /dev/null and b/contents/posts/React/constellation-impl/img/math.webp differ
diff --git a/contents/posts/React/constellation-impl/index.md b/contents/posts/React/constellation-impl/index.md
new file mode 100644
index 0000000..9ede517
--- /dev/null
+++ b/contents/posts/React/constellation-impl/index.md
@@ -0,0 +1,218 @@
+---
+title: "정적 좌표 지옥에서 탈출한 동적 별자리 노드 시스템 구축기"
+createdAt: "2026-03-02"
+category: React
+description: '누비랩 냠냠플러스 "오늘찰칵" 서비스의 별자리 맵 시스템을 하드코딩된 좌표 대신 기하학 알고리즘과 Render Props 패턴으로 해결하며 유지보수성과 확장성을 확보한 경험을 공유합니다.'
+comment: true
+head:
+ - - meta
+ - name: keywords
+ content: "React, Renderer Props, 삼각함수, 별자리 지도"
+---
+
+최근 인턴으로 재직중인 누비랩의 냠냠플러스 `오늘찰칵` 서비스 고도화 작업을 하면서, 단순 갤러리 형태의 화면을 조금 더 재미있고 감정적으로 연결되는 경험으로 바꾸는 작업을 맡게 되었습니다.
+
+기존 POC는 "사진을 나열해서 보여주는 화면"에 가까웠습니다. 기능은 있었지만, 아이의 기록을 탐험하듯 따라가게 만드는 몰입감이나, 부모 입장에서 하나씩 발견하는 재미는 부족했습니다.
+
+
+
+
+
+
+그래서 도입된 컨셉이 바로 **별자리 지도 UI**이었습니다.
+
+문제는 여기서부터였습니다. 겉으로 보기엔 별처럼 점이 이어진 예쁜 경로지만, 실제 구현 단계에 들어가면 이건 단순한 데코레이션이 아니라 다음 조건을 모두 만족해야 하는 시스템이었습니다.
+
+> - 별자리 노드 개수가 바뀌어도 대응 가능해야 함
+> - 경로 모양이 바뀌어도 유지보수가 가능해야 함
+> - 모바일 WebView에서도 버벅이지 않아야 함
+> - 디자인 QA에서 미세 조정을 요청해도 빠르게 반영 가능해야 함
+
+처음엔 그냥 하드코딩으로 정적인 좌표를 박아 넣으면 되는 문제처럼 보였지만, 추후 확장성을 고려했을때는 해당 방법이 적절하지 않다고 생각했습니다.
+
+이번 글에서는 그 과정에서 왜 단순 하드코딩을 버리고, **삼각함수 기반의 좌표 계산 + Render Props 패턴**으로 문제를 풀었는지 정리해보겠습니다.
+
+## 예쁜 시안, 끔찍한 유지보수
+
+디자인 시안을 기준으로 보면 별자리 노드는 세로 방향으로 길게 이어지고, 중간중간 좌우로 꺾이며, 특정 간격마다 큰 마커(별)가 들어가고 그 외에는 작은 점선처럼 이어지는 구조였습니다.
+
+
+
+
+
+이걸 가장 단순히 구현하는 첫 번째 접근방법은 해당 경로가 포함된 이미지를 배경으로 깔고, 상호작용이 필요한 각 별의 x, y 좌표를 추출하여 하드코딩하는 방식입니다.
+
+```tsx
+const nodes = [
+ { x: -102, y: 0 },
+ { x: -102, y: 20 },
+ { x: -102, y: 40 },
+ { x: -86, y: 60 },
+ ...
+];
+
+
+ {nodes.map((node, index) => (
+
+ ))}
+
+```
+
+가장 단순한 구현방법이지만, 다음과 같은 문제점들이 예상되었습니다
+
+### 1️⃣ 노드 개수나 경로가 바뀌는 순간, 전체 좌표를 다시 설정해야한다
+
+오늘은 20개 노드지만 기록이 추가되며 추후 40개가 될 수 있고, 경로의 각도나 밀도를 바꿔야 할 수도 있습니다.
+하드코딩 방식은 일부만 수정해도 전체 균형이 깨질 수 있고, 하나하나의 좌표를 찾아서 수정하는 것은 비효율적입니다.
+Figma MCP 를 사용하더라도 여전히 안맞는 픽셀이 있는경우 하나하나 검토하는건 개발자의 몫이었습니다
+
+### 2️⃣ 디자인 QA 대응의 비효율성
+
+"여기 조금만 더 오른쪽으로", "이 구간은 간격이 너무 촘촘함"과 같은 픽셀 단위의 요청이 들어올 때마다 수동으로 좌표를 찾고 수정하는 과정은 비효율적입니다.
+
+### 3️⃣ SVG Path의 실용성 한계
+
+SVG Path는 곡선 표현력은 좋지만, 모바일 WebView 환경에서 경로가 길고 노드가 많아질 경우 래스터화 비용과 렌더링 안정성 측면에서 부담이 될 가능성이 있었습니다.
+무엇보다 특정 노드를 개별 UI 컴포넌트로 제어하기에는 유연성이 떨어졌습니다.
+
+## 선택지 검토
+
+구현 방향은 크게 세 가지로 압축되었습니다.
+
+| 구분 | 장점 | 단점 |
+| :----------------------------- | :----------------------------------- | :----------------------------------------- |
+| **A. 수동 하드코딩** | 시안과 100% 동일하게 구현 가능 | 유지보수 비용 급증, QA 대응 취약 |
+| **B. SVG Path 기반** | 정교한 곡선 표현 | WebView 성능 우려 개별 노드 제어 어려움 |
+| **C. 삼각함수 기반 좌표 계산** | 파라미터 기반 자동 생성, 운영 최적화 | 초기 로직 설계 필요 |
+
+최종적으로 디자인 100% 복제보다 운영 가능한 시스템이 더 중요하다고 판단하여 C안을 선택했습니다.
+
+## 좌표를 저장하지 말고, 규칙으로 만들자
+
+> "노드 하나하나의 좌표를 직접 갖고 있지 말고, 시작점 + 간격 + 각도 + 방향 패턴만으로 좌표를 생성하자."
+
+
+
+
+
+이 구조가 되면 경로는 더 이상 픽셀 덩어리가 아니라, **파라미터 기반 생성 결과물**이 됩니다.
+
+- `nodeGap`: 노드 사이의 거리 (빗변)
+- `angle`: 경로가 꺾이는 기준 각도
+- `offsetArray`: 좌/우/직진 여부를 결정하는 패턴 배열
+- `offsetStartX`: 시작점 가로 위치
+
+## 구현 1: 삼각함수로 노드 간 수평/수직 이동 거리 계산
+
+
+
+
+
+처음에는 단순히 세로 간격을 고정하고 가로 이동량만 계산했으나, 대각선 경로에서도 일정한 시각적 밀도를 유지하기 위해 **빗변(`nodeGap`)을 기준**으로 잡았습니다.
+
+내려갈 때 좌우로 얼마나 이동할지(`dx`)와 아래로 얼마나 내려갈지(`dy`)를 각도와 빗변 기반으로 계산했습니다.
+
+```ts
+const deg = angle * (Math.PI / 180);
+const dx = nodeGap * Math.cos(deg);
+const dy = nodeGap * Math.sin(deg);
+```
+
+이렇게 구한 `dx`, `dy`를 패턴 배열에 적용하여 각 노드의 위치를 자동 생성하도록 했습니다.
+
+```ts
+export function createStarNodes({
+ totalNodes,
+ nodeGap,
+ angle,
+ offsetArray,
+ offsetStartX,
+}: CreatStarNodesArgs) {
+ const nodes = new Array();
+ const deg = angle * (Math.PI / 180);
+ const dx = nodeGap * Math.cos(deg);
+ const dy = nodeGap * Math.sin(deg);
+
+ let x = offsetStartX;
+ let y = 0;
+
+ for (let n = 0; n < totalNodes; n++) {
+ nodes.push({ x, y });
+
+ const dir = offsetArray[n % offsetArray.length];
+
+ if (dir === 0) {
+ // 직진할 때는 nodeGap만큼 수직으로만 이동
+ y += nodeGap;
+ } else {
+ // 꺾일 때는 계산된 dx, dy만큼 이동
+ x += dir * dx;
+ y += dy;
+ }
+ }
+
+ return nodes;
+}
+```
+
+`offsetArray`의 값이 `0`이면 직진, `1`이면 우측, `-1`이면 좌측으로 흐름을 정의하되, 꺾이는 구간에서도 노드 사이의 거리(`nodeGap`)가 일정하게 유지되도록 설계했습니다.
+
+## 구현 2: Render Props로 "좌표 생성"과 "UI"를 분리
+
+좌표 로직과 UI를 섞지 않기 위해 `StarMapLayer`는 좌표 계산과 배치만 책임지고, 각 노드에 무엇을 낼지는 외부에서 주입받는 **Render Props** 패턴을 적용했습니다.
+
+```tsx
+// 0 : 직진, 1 : 우측, -1 : 좌측
+const offsetArray = [
+ Array(9).fill(0),
+ Array(12).fill(1),
+ Array(27).fill(0),
+ Array(10).fill(-1),
+ Array(9).fill(0),
+ Array(8).fill(1),
+ Array(11).fill(0),
+ Array(12).fill(-1),
+].flat();
+
+ {
+ // 5번째 노드만 별자리 마커로 표시
+ if (index % 5 === 0) return ;
+ return ;
+ }}
+/>;
+```
+
+덕분에 특정 인덱스만 잠금 상태로 표시하거나, 보상 강조 UI를 입히는 등의 확장이 자유로워졌습니다.
+
+## 구현 3: 픽셀 맞추기 지옥에서 벗어나기 위한 "개발자 도구"
+
+수학적으로 위치를 계산하게 만들었지만, 여전히 고민은 남았습니다.
+`angle`, `gap`, `offsetArray` 같은 값들을 바꿀 때마다 코드를 수정하고 HMR을 기다리며 픽셀을 맞추는 건 여전히 비효율적이었습니다
+
+> "그냥 화면에서 직접 슬라이더로 조절하면서 최적의 값을 찾고, 그 코드만 복사해서 붙여넣으면 안 될까?"
+
+이런 고민 끝에 별자리 에디터(StarMap DevTools)를 추가했습니다.
+슬라이더를 통해 실시간으로 경로를 비틀어보며 최적의 디자인을 찾고, `코드 복사하기` 버튼으로 즉시 현재 설정값을 복사할 수 있는 도구입니다.
+
+
+
+
+
+이 개발자 도구 덕분에 며칠이 걸릴 수도 있었던 디자인 미세 조정 작업을 단 몇분만에 끝낼 수 있었습니다.
+
+## 느낀 점
+
+### 이거 좌표 하나하나를 나보고 찍으라고?
+
+처음 시안을 받았을 때 가장 먼저 든 생각은 '노드 좌표를 언제 다 따고 있지?'였습니다. 하지만 단순히 귀찮음의 문제가 아니었습니다. 운영 환경에서 노드가 추가되거나 경로를 살짝만 비틀어달라는 요청이 오면, 그때마다 피그마에서 좌표를 다시 추출하고 코드를 수정하는 '노가다'가 반복될 게 뻔햇기 때문입니다.
+
+### 디자인 재현도와 제어 가능성의 균형
+
+개발자로서 시안을 100% 똑같이 재현하고 싶은 욕심은 늘 있습니다. 하지만 실제 서비스 관점에서는 경로를 수식으로 완벽하게 그리는 것보다, **개발자가 숫자로 제어할 수 있고 운영팀의 요구에 즉각 대응할 수 있는 구조**를 만드는 게 훨씬 가치 있다는 걸 배웠습니다.
+`angle`, `gap` 같은 변수 몇 개로 전체 흐름을 바꿀 수 있게 되었습니다
diff --git a/contents/posts/React/img/context-provider-hell/prop-drilling.jpeg b/contents/posts/React/context-provider-hell/img/prop-drilling.jpeg
similarity index 100%
rename from contents/posts/React/img/context-provider-hell/prop-drilling.jpeg
rename to contents/posts/React/context-provider-hell/img/prop-drilling.jpeg
diff --git a/contents/posts/React/img/context-provider-hell/prop-drilling.png b/contents/posts/React/context-provider-hell/img/prop-drilling.png
similarity index 100%
rename from contents/posts/React/img/context-provider-hell/prop-drilling.png
rename to contents/posts/React/context-provider-hell/img/prop-drilling.png
diff --git a/contents/posts/React/img/context-provider-hell/prop-drilling.webp b/contents/posts/React/context-provider-hell/img/prop-drilling.webp
similarity index 100%
rename from contents/posts/React/img/context-provider-hell/prop-drilling.webp
rename to contents/posts/React/context-provider-hell/img/prop-drilling.webp
diff --git a/contents/posts/React/context-provider-hell.md b/contents/posts/React/context-provider-hell/index.md
similarity index 97%
rename from contents/posts/React/context-provider-hell.md
rename to contents/posts/React/context-provider-hell/index.md
index bf572e9..086fa54 100644
--- a/contents/posts/React/context-provider-hell.md
+++ b/contents/posts/React/context-provider-hell/index.md
@@ -6,7 +6,7 @@ description: React Context API를 사용할 때 발생할 수 있는 'Context Pr
comment: true
---
-
+
React 를 사용하다 보면 전역적인 상태나 설정을 공유하기 위해 자연스럽게 Context를 사용하게 됩니다. 테마, 인증정보, 폼 상태 ... 처음엔 편합니다. `` 로 감싸주면, 어디서든 데이터를 쉽게 꺼내쓸 수 있으니까요.
diff --git a/contents/posts/React/img/create-entity-adapter/global-state.jpeg b/contents/posts/React/create-entity-adapter/img/global-state.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/global-state.jpeg
rename to contents/posts/React/create-entity-adapter/img/global-state.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/global-state.png b/contents/posts/React/create-entity-adapter/img/global-state.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/global-state.png
rename to contents/posts/React/create-entity-adapter/img/global-state.png
diff --git a/contents/posts/React/img/create-entity-adapter/global-state.webp b/contents/posts/React/create-entity-adapter/img/global-state.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/global-state.webp
rename to contents/posts/React/create-entity-adapter/img/global-state.webp
diff --git a/contents/posts/React/img/create-entity-adapter/image-1.jpeg b/contents/posts/React/create-entity-adapter/img/image-1.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-1.jpeg
rename to contents/posts/React/create-entity-adapter/img/image-1.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/image-1.png b/contents/posts/React/create-entity-adapter/img/image-1.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-1.png
rename to contents/posts/React/create-entity-adapter/img/image-1.png
diff --git a/contents/posts/React/img/create-entity-adapter/image-1.webp b/contents/posts/React/create-entity-adapter/img/image-1.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-1.webp
rename to contents/posts/React/create-entity-adapter/img/image-1.webp
diff --git a/contents/posts/React/img/create-entity-adapter/image-2.jpeg b/contents/posts/React/create-entity-adapter/img/image-2.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-2.jpeg
rename to contents/posts/React/create-entity-adapter/img/image-2.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/image-2.png b/contents/posts/React/create-entity-adapter/img/image-2.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-2.png
rename to contents/posts/React/create-entity-adapter/img/image-2.png
diff --git a/contents/posts/React/img/create-entity-adapter/image-2.webp b/contents/posts/React/create-entity-adapter/img/image-2.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-2.webp
rename to contents/posts/React/create-entity-adapter/img/image-2.webp
diff --git a/contents/posts/React/img/create-entity-adapter/image-3.jpeg b/contents/posts/React/create-entity-adapter/img/image-3.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-3.jpeg
rename to contents/posts/React/create-entity-adapter/img/image-3.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/image-3.png b/contents/posts/React/create-entity-adapter/img/image-3.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-3.png
rename to contents/posts/React/create-entity-adapter/img/image-3.png
diff --git a/contents/posts/React/img/create-entity-adapter/image-3.webp b/contents/posts/React/create-entity-adapter/img/image-3.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-3.webp
rename to contents/posts/React/create-entity-adapter/img/image-3.webp
diff --git a/contents/posts/React/img/create-entity-adapter/image-4.jpeg b/contents/posts/React/create-entity-adapter/img/image-4.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-4.jpeg
rename to contents/posts/React/create-entity-adapter/img/image-4.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/image-4.png b/contents/posts/React/create-entity-adapter/img/image-4.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-4.png
rename to contents/posts/React/create-entity-adapter/img/image-4.png
diff --git a/contents/posts/React/img/create-entity-adapter/image-4.webp b/contents/posts/React/create-entity-adapter/img/image-4.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-4.webp
rename to contents/posts/React/create-entity-adapter/img/image-4.webp
diff --git a/contents/posts/React/img/create-entity-adapter/image-5.jpeg b/contents/posts/React/create-entity-adapter/img/image-5.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-5.jpeg
rename to contents/posts/React/create-entity-adapter/img/image-5.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/image-5.png b/contents/posts/React/create-entity-adapter/img/image-5.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-5.png
rename to contents/posts/React/create-entity-adapter/img/image-5.png
diff --git a/contents/posts/React/img/create-entity-adapter/image-5.webp b/contents/posts/React/create-entity-adapter/img/image-5.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-5.webp
rename to contents/posts/React/create-entity-adapter/img/image-5.webp
diff --git a/contents/posts/React/img/create-entity-adapter/image-6.jpeg b/contents/posts/React/create-entity-adapter/img/image-6.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-6.jpeg
rename to contents/posts/React/create-entity-adapter/img/image-6.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/image-6.png b/contents/posts/React/create-entity-adapter/img/image-6.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-6.png
rename to contents/posts/React/create-entity-adapter/img/image-6.png
diff --git a/contents/posts/React/img/create-entity-adapter/image-6.webp b/contents/posts/React/create-entity-adapter/img/image-6.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image-6.webp
rename to contents/posts/React/create-entity-adapter/img/image-6.webp
diff --git a/contents/posts/React/img/create-entity-adapter/image.jpeg b/contents/posts/React/create-entity-adapter/img/image.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image.jpeg
rename to contents/posts/React/create-entity-adapter/img/image.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/image.png b/contents/posts/React/create-entity-adapter/img/image.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image.png
rename to contents/posts/React/create-entity-adapter/img/image.png
diff --git a/contents/posts/React/img/create-entity-adapter/image.webp b/contents/posts/React/create-entity-adapter/img/image.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/image.webp
rename to contents/posts/React/create-entity-adapter/img/image.webp
diff --git a/contents/posts/React/img/create-entity-adapter/nested.jpeg b/contents/posts/React/create-entity-adapter/img/nested.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/nested.jpeg
rename to contents/posts/React/create-entity-adapter/img/nested.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/nested.png b/contents/posts/React/create-entity-adapter/img/nested.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/nested.png
rename to contents/posts/React/create-entity-adapter/img/nested.png
diff --git a/contents/posts/React/img/create-entity-adapter/nested.webp b/contents/posts/React/create-entity-adapter/img/nested.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/nested.webp
rename to contents/posts/React/create-entity-adapter/img/nested.webp
diff --git a/contents/posts/React/img/create-entity-adapter/spotify-global-state.jpeg b/contents/posts/React/create-entity-adapter/img/spotify-global-state.jpeg
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/spotify-global-state.jpeg
rename to contents/posts/React/create-entity-adapter/img/spotify-global-state.jpeg
diff --git a/contents/posts/React/img/create-entity-adapter/spotify-global-state.png b/contents/posts/React/create-entity-adapter/img/spotify-global-state.png
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/spotify-global-state.png
rename to contents/posts/React/create-entity-adapter/img/spotify-global-state.png
diff --git a/contents/posts/React/img/create-entity-adapter/spotify-global-state.webp b/contents/posts/React/create-entity-adapter/img/spotify-global-state.webp
similarity index 100%
rename from contents/posts/React/img/create-entity-adapter/spotify-global-state.webp
rename to contents/posts/React/create-entity-adapter/img/spotify-global-state.webp
diff --git a/contents/posts/React/create-entity-adapter.md b/contents/posts/React/create-entity-adapter/index.md
similarity index 96%
rename from contents/posts/React/create-entity-adapter.md
rename to contents/posts/React/create-entity-adapter/index.md
index 0c617b6..41e4b2b 100644
--- a/contents/posts/React/create-entity-adapter.md
+++ b/contents/posts/React/create-entity-adapter/index.md
@@ -16,7 +16,7 @@ head:
혹시 여러분은 어떤 상태를 전역상태로 관리하고 있나요 ?
-
+
사용자의 인증정보, 테마 설정, 전역적으로 관리되는 모달이나 토스트, 그리고 서버에서 받아온 데이터들까지 다양한 상태들이 전역상태로 관리될 수 있습니다.
@@ -28,7 +28,7 @@ head:
Spotify 앱을 예시로 생각해봅시다
-
+
좌측에는 재생목록이 있고, 가운데는 재생목록에 속한 노래들이 목록 형태로 주어져 있습니다.
하단에는 현재 재생중인 노래의 정보가 표시되고 있네요.
@@ -63,7 +63,7 @@ interface Playlist {
## 🫨 Nested 한 전역상태의 문제점
-
+
이러한 구조에서 발생하는 문제는 어떤 것들이 있을까요?
처음 봤을때는 별 문제가 없어 보일수도 있습니다. 저도 그랬구요..
@@ -75,11 +75,11 @@ interface Playlist {
> id 가 1인 노래가 싫어졌어요 ㅠㅠ
> 모든 플레이리스트에서 id 가 1인 노래의 liked 속성을 false 로 토글해주세요!
-
+
먼저 모든 플레이리스트를 순회합니다 ($$O(n)$$)
-
+
이후, 각 플레이리스트의 `tracks` 배열을 순회하며 ($$O(m)$$)
id 가 1인 노래를 찾으면 liked 속성을 토글합니다
@@ -90,7 +90,7 @@ id 가 1인 노래를 찾으면 liked 속성을 토글합니다
또는 구현을 했는데 `어느 한군데의 플레이리스트에서 id 가 1인 노래의 liked 속성이 토글되지 않았다면?`
디버깅하기가 너무 힘들어집니다.
-
+
그리고 두 플레이리스트를 각각 구독하고있는 컴포넌트 `` 과 `` 이 있다고 가정해봅시다.
@@ -101,7 +101,7 @@ id 가 1인 노래를 찾으면 liked 속성을 토글합니다
이처럼 Nested 한 전역상태는 다음과 같은 문제점이 있습니다.
-
+
> 1. 동일한 데이터가 중복되어 흩어져 있다 (일관성 깨짐)
> 2. 변경 범위가 너무 크다 (불필요한 재렌더링)
@@ -112,7 +112,7 @@ id 가 1인 노래를 찾으면 liked 속성을 토글합니다
## 🧐 어떻게 중복된 상태를 제거할 수 있을까 ?
-
+
데이터베이스에서는 중복된 데이터를 제거하기 위해 `정규화(Normalization)` 라는 개념을 사용합니다.
그 중, 제1정규형 (1NF) 는 `최소한의 테이블은 관계이며, 중복되는 항목이 없어야한다` 는 원칙을 가지고 있습니다.
@@ -127,7 +127,7 @@ id 가 1인 노래를 찾으면 liked 속성을 토글합니다
## 🤩 Spotify 전역상태 다시 설계하기
-
+
오른쪽 그림과 같이 기존에 중첩되어 있던 `tracks` 배열을 분리해서 각각의 id 로 접근할 수 있는 유사배열객체 형태로 바꿀 수 있습니다.
@@ -331,7 +331,7 @@ export const selectPlaylistWithTracks = (playlistId: PlaylistId) => {
## 🏁 정리하자면
-
+
1. React App 이 커질수록 전역상태는 단순한 UI 상태 저장소가 아니라 관계가 연결된 도메인 데이터를 다루게 된다.
2. Nested 구조는 중복, 비일관성, 과한 리렌더링이 발생하고, 이를 정규화를 통해 해결할 수 있다
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-1.gif b/contents/posts/React/inf-scroll/img/inf-scroll-1.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-1.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-1.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-10.gif b/contents/posts/React/inf-scroll/img/inf-scroll-10.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-10.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-10.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-11.gif b/contents/posts/React/inf-scroll/img/inf-scroll-11.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-11.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-11.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-12.gif b/contents/posts/React/inf-scroll/img/inf-scroll-12.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-12.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-12.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-13.gif b/contents/posts/React/inf-scroll/img/inf-scroll-13.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-13.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-13.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-14.gif b/contents/posts/React/inf-scroll/img/inf-scroll-14.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-14.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-14.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-2.jpeg b/contents/posts/React/inf-scroll/img/inf-scroll-2.jpeg
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-2.jpeg
rename to contents/posts/React/inf-scroll/img/inf-scroll-2.jpeg
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-2.png b/contents/posts/React/inf-scroll/img/inf-scroll-2.png
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-2.png
rename to contents/posts/React/inf-scroll/img/inf-scroll-2.png
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-2.webp b/contents/posts/React/inf-scroll/img/inf-scroll-2.webp
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-2.webp
rename to contents/posts/React/inf-scroll/img/inf-scroll-2.webp
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-3.jpeg b/contents/posts/React/inf-scroll/img/inf-scroll-3.jpeg
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-3.jpeg
rename to contents/posts/React/inf-scroll/img/inf-scroll-3.jpeg
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-3.png b/contents/posts/React/inf-scroll/img/inf-scroll-3.png
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-3.png
rename to contents/posts/React/inf-scroll/img/inf-scroll-3.png
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-3.webp b/contents/posts/React/inf-scroll/img/inf-scroll-3.webp
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-3.webp
rename to contents/posts/React/inf-scroll/img/inf-scroll-3.webp
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-4.jpeg b/contents/posts/React/inf-scroll/img/inf-scroll-4.jpeg
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-4.jpeg
rename to contents/posts/React/inf-scroll/img/inf-scroll-4.jpeg
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-4.png b/contents/posts/React/inf-scroll/img/inf-scroll-4.png
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-4.png
rename to contents/posts/React/inf-scroll/img/inf-scroll-4.png
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-4.webp b/contents/posts/React/inf-scroll/img/inf-scroll-4.webp
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-4.webp
rename to contents/posts/React/inf-scroll/img/inf-scroll-4.webp
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-5.gif b/contents/posts/React/inf-scroll/img/inf-scroll-5.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-5.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-5.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-6.jpeg b/contents/posts/React/inf-scroll/img/inf-scroll-6.jpeg
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-6.jpeg
rename to contents/posts/React/inf-scroll/img/inf-scroll-6.jpeg
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-6.png b/contents/posts/React/inf-scroll/img/inf-scroll-6.png
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-6.png
rename to contents/posts/React/inf-scroll/img/inf-scroll-6.png
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-6.webp b/contents/posts/React/inf-scroll/img/inf-scroll-6.webp
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-6.webp
rename to contents/posts/React/inf-scroll/img/inf-scroll-6.webp
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-7.jpeg b/contents/posts/React/inf-scroll/img/inf-scroll-7.jpeg
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-7.jpeg
rename to contents/posts/React/inf-scroll/img/inf-scroll-7.jpeg
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-7.png b/contents/posts/React/inf-scroll/img/inf-scroll-7.png
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-7.png
rename to contents/posts/React/inf-scroll/img/inf-scroll-7.png
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-7.webp b/contents/posts/React/inf-scroll/img/inf-scroll-7.webp
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-7.webp
rename to contents/posts/React/inf-scroll/img/inf-scroll-7.webp
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-8.gif b/contents/posts/React/inf-scroll/img/inf-scroll-8.gif
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-8.gif
rename to contents/posts/React/inf-scroll/img/inf-scroll-8.gif
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-8.jpeg b/contents/posts/React/inf-scroll/img/inf-scroll-8.jpeg
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-8.jpeg
rename to contents/posts/React/inf-scroll/img/inf-scroll-8.jpeg
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-8.png b/contents/posts/React/inf-scroll/img/inf-scroll-8.png
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-8.png
rename to contents/posts/React/inf-scroll/img/inf-scroll-8.png
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-8.webp b/contents/posts/React/inf-scroll/img/inf-scroll-8.webp
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-8.webp
rename to contents/posts/React/inf-scroll/img/inf-scroll-8.webp
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-9.jpeg b/contents/posts/React/inf-scroll/img/inf-scroll-9.jpeg
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-9.jpeg
rename to contents/posts/React/inf-scroll/img/inf-scroll-9.jpeg
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-9.png b/contents/posts/React/inf-scroll/img/inf-scroll-9.png
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-9.png
rename to contents/posts/React/inf-scroll/img/inf-scroll-9.png
diff --git a/contents/posts/React/img/inf-scroll/inf-scroll-9.webp b/contents/posts/React/inf-scroll/img/inf-scroll-9.webp
similarity index 100%
rename from contents/posts/React/img/inf-scroll/inf-scroll-9.webp
rename to contents/posts/React/inf-scroll/img/inf-scroll-9.webp
diff --git a/contents/posts/React/inf-scroll.md b/contents/posts/React/inf-scroll/index.md
similarity index 91%
rename from contents/posts/React/inf-scroll.md
rename to contents/posts/React/inf-scroll/index.md
index 234fbe7..621d659 100644
--- a/contents/posts/React/inf-scroll.md
+++ b/contents/posts/React/inf-scroll/index.md
@@ -6,7 +6,7 @@ description: React와 Intersection Observer API를 활용해 성능 최적화된
comment: true
---
-
+
현대의 모바일 웹이나 앱에서 흔이 볼 수 있는 기능 중 하나가 바로 '무한 스크롤' 입니다.
하지만, 무한 스크롤을 이해하기 위해선 먼저 '페이지네이션'을 알아볼 필요가 있습니다.
@@ -14,7 +14,7 @@ comment: true
## 📖 Pagination 페이지네이션이란?
-
+
페이지네이션이란? 많은 데이터를 부분적으로 나눠서 불러오는 기술을 말합니다.
@@ -42,18 +42,18 @@ comment: true
오프셋 기반 페이지네이션은 페이지를 기준으로 데이터를 잘라서 요청하는 페이지네이션 입니다.
-
+
주로, 페이지 버튼이 있는 UI 에서 사용되며, API 호출시, 원하는 데이터 개수와, 몇 번째 페이지를 가져올지 명시합니다.
-
+
오프셋 기반의 페이지네이션은 커서 기반 페이지네이션보다 비교적 구현이 간단하다는 장점이 있지만,
페이지네이션 도중, 데이터가 추가/삭제 될 경우, 데이터가 누락/중복 될 수 있다는 단점이 있습니다.
### ✏️ Offset Based Pagination 오프셋 기반 페이지네이션의 동작
-
+
10개의 데이터를 4개씩 나눠 오프셋 기반의 페이지네이션으로 가져오는 상황을 가정해 보겠습니다.
@@ -64,20 +64,20 @@ comment: true
### ✏️ Cursor Based Pagination 커서 기반 페이지네이션
-
+
커서 기반의 페이지네이션은 가장 최근에 가져온 데이터를 기준으로, 다음 데이터를 불러옵니다.
주로, 무한 스크롤과 같은 UI 에서 사용되며, API 호출시, 마지막 데이터의 기준값, 원하는 데이터 개수를 명시합니다.
-
+
커서 기반 페이지네이션은 최근 요청된 데이터를 기준으로 쿼리가 작성되기 때문에, 누락되거나 중복될 확률이 적다는 장점이 있지만,
페이지네이션 구현이 비교적 복잡할 수 있다는 단점이 있습니다
### ✏️ Offset Based Pagination 오프셋 기반 페이지네이션의 동작
-
+
이전과 동일한 10개의 데이터를 페이징하는 상황에서,
응답에 들어있는 커서를 다음 요청의 query 로 전송하면, 서버에서는 해당 커서 이후의 데이터를 응답으로 보내줍니다.
@@ -86,7 +86,7 @@ comment: true
### ✏️ 정리
-
+
## 📖 Infinite Scroll 무한 스크롤
@@ -94,7 +94,7 @@ comment: true
무한 스크롤을 구현하기 위한 요구사항을 정리하면 다음과 같습니다.
-
+
다음 페이지에 대한 데이터는 이전 응답에서의 커서를 요청 쿼리 파라미터에 넣으면 되고,
우리는 사용자가 페이지 하단에 도달했을때를 감지할 수 있어야 합니다.
@@ -103,7 +103,7 @@ comment: true
ScrollEventListener 를 사용하면, 사용자가 얼만큼 스크롤을 내렸는지 확인 할 수 있습니다.
-
+
브라우저에서는 스크롤이 가능한 컨테이너에 대해 `scrollTop` , `clientHeight` , `scrollHeight` 프로퍼티를 제공합니다.
@@ -112,7 +112,7 @@ ScrollEventListener 를 사용하면, 사용자가 얼만큼 스크롤을 내렸
### ✏️ Scroll Event 의 단점
-
+
하지만, 스크롤 이벤트 핸들러를 사용하면,
스크롤이 발생 할 때 마다 콜백함수가 Task Queue 에 등록되게 됩니다.
@@ -122,14 +122,14 @@ JS 는 싱글 스레드로 동작하기 때문에, 스크롤 이벤트와 같은
이는 네트워크 요청이나 다른 UI 업데이트가 늦어지거나 멈추는 현상이 발생 할 수 있습니다.
-
+
### ✏️ Intersection Observer
다행이도 DOM API 에서는 Element 의 가시성을 판단해주는
IntersectionObserver API 를 제공합니다
-
+
우리는 단순히 intersectionObserver 인스턴스를 생성하고,
감시할 요소를 intersectionObserver.observe(target) 으로 관찰할 수 있습니다.
@@ -139,7 +139,7 @@ IntersectionObserver API 를 제공합니다
### ✏️ Intersection Observer 로 무한 스크롤 구현하기
-
+
> 1. 먼저 감시할 요소, 스크롤 컨테이너 요소, Intersection Observer 의 인스턴스를 저장할 ref 를 선언합니다
> 2. 이후, observerOptions 와 observerCallback 을 설정해 주고,
diff --git a/contents/posts/React/img/kareer-fit-1/after.gif b/contents/posts/React/kareer-fit-1/img/after.gif
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/after.gif
rename to contents/posts/React/kareer-fit-1/img/after.gif
diff --git a/contents/posts/React/img/kareer-fit-1/before.gif b/contents/posts/React/kareer-fit-1/img/before.gif
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/before.gif
rename to contents/posts/React/kareer-fit-1/img/before.gif
diff --git a/contents/posts/React/img/kareer-fit-1/event-bus-architecture.webp b/contents/posts/React/kareer-fit-1/img/event-bus-architecture.webp
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/event-bus-architecture.webp
rename to contents/posts/React/kareer-fit-1/img/event-bus-architecture.webp
diff --git a/contents/posts/React/img/kareer-fit-1/image-1.jpeg b/contents/posts/React/kareer-fit-1/img/image-1.jpeg
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/image-1.jpeg
rename to contents/posts/React/kareer-fit-1/img/image-1.jpeg
diff --git a/contents/posts/React/img/kareer-fit-1/image-1.png b/contents/posts/React/kareer-fit-1/img/image-1.png
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/image-1.png
rename to contents/posts/React/kareer-fit-1/img/image-1.png
diff --git a/contents/posts/React/img/kareer-fit-1/image-1.webp b/contents/posts/React/kareer-fit-1/img/image-1.webp
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/image-1.webp
rename to contents/posts/React/kareer-fit-1/img/image-1.webp
diff --git a/contents/posts/React/img/kareer-fit-1/image.jpeg b/contents/posts/React/kareer-fit-1/img/image.jpeg
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/image.jpeg
rename to contents/posts/React/kareer-fit-1/img/image.jpeg
diff --git a/contents/posts/React/img/kareer-fit-1/image.png b/contents/posts/React/kareer-fit-1/img/image.png
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/image.png
rename to contents/posts/React/kareer-fit-1/img/image.png
diff --git a/contents/posts/React/img/kareer-fit-1/image.webp b/contents/posts/React/kareer-fit-1/img/image.webp
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/image.webp
rename to contents/posts/React/kareer-fit-1/img/image.webp
diff --git a/contents/posts/React/img/kareer-fit-1/select-state-machine.webp b/contents/posts/React/kareer-fit-1/img/select-state-machine.webp
similarity index 100%
rename from contents/posts/React/img/kareer-fit-1/select-state-machine.webp
rename to contents/posts/React/kareer-fit-1/img/select-state-machine.webp
diff --git a/contents/posts/React/kareer-fit-1.md b/contents/posts/React/kareer-fit-1/index.md
similarity index 96%
rename from contents/posts/React/kareer-fit-1.md
rename to contents/posts/React/kareer-fit-1/index.md
index 5875d66..0957ade 100644
--- a/contents/posts/React/kareer-fit-1.md
+++ b/contents/posts/React/kareer-fit-1/index.md
@@ -19,11 +19,11 @@ React 개발자라면 재렌더링을 위해 `useState`를 사용해 상태를 U
최근 PDF 문서 위에 사용자가 드래그로 영역을 선택해 피드백을 남기는 기능을 개발하게 되었다.
당연하게도 `useState` 로 드래그 영역의 좌표를 관리했다. 잘 동작했지만, 결과는 처참했다.
-
+
마우스를 조금만 빠르게 움직여도 이벤트가 씹히는 현상이 발생했다. `onMouseMove` 이벤트가 발생할 때마다 `setState`가 호출되면서 초당 수십 번의 리렌더링이 일어났기 때문이다. ([PR - Feature#31](https://github.com/kakao-tech-campus-3rd-step3/Team7_FE/pull/38))
-
+
이처럼 간단해 보이는 기능에서, 어떻게 성능과 멋찐 아키텍쳐를 모두 잡을 수 있을까?
@@ -39,7 +39,7 @@ React 개발자라면 재렌더링을 위해 `useState`를 사용해 상태를 U
`useRef`는 컴포넌트가 리렌더링 되더라도 값이 유지되며, 값이 변경되어도 리렌더링을 발생시키지 않는다.
따라서 드래그 중인 좌표를 `useRef`로 관리하면 불필요한 리렌더링을 피할 수 있다.
-
+
또, `useRef`를 사용해 DOM 엘리먼트를 직접 참조하고 `style` 속성을 직접 변경했다.
리렌더링은 0회. 성능 문제는 해결되었따!
@@ -62,7 +62,7 @@ React 개발자라면 재렌더링을 위해 `useState`를 사용해 상태를 U
> Publish-Subscribe 모델의 한 형태로, 시스템의 각 부분을 독립적인 모듈로 만들어 결합도를 낮추는데 도움을 준다.
-
+
쉽게 말해! 인스타 팔로우 라고 생각하면된다!
@@ -163,11 +163,11 @@ const eventBus = new EventBus()
또, 각각의 플러그인은 독립적으로 개발 및 테스트할 수 있어 유지보수도 용이하다.
-
+
SelectionEventController는 단순히 `attach` 로 부터 받은 `eventBus` 를 통해 이벤트를 구독하고, 상태머신을 이용해 고수준 이벤트로 변환해 발행하는 역할만 한다.
-
+
```ts
export type SelectionState = "idle" | "dragging";
diff --git a/contents/posts/React/react-aop-hoc.md b/contents/posts/React/react-aop-hoc/index.md
similarity index 100%
rename from contents/posts/React/react-aop-hoc.md
rename to contents/posts/React/react-aop-hoc/index.md
diff --git a/contents/posts/React/react-create-portal-modal.md b/contents/posts/React/react-create-portal-modal/index.md
similarity index 100%
rename from contents/posts/React/react-create-portal-modal.md
rename to contents/posts/React/react-create-portal-modal/index.md
diff --git a/contents/posts/React/img/react-toastify/toastify-1.jpeg b/contents/posts/React/react-toastify/img/toastify-1.jpeg
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-1.jpeg
rename to contents/posts/React/react-toastify/img/toastify-1.jpeg
diff --git a/contents/posts/React/img/react-toastify/toastify-1.png b/contents/posts/React/react-toastify/img/toastify-1.png
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-1.png
rename to contents/posts/React/react-toastify/img/toastify-1.png
diff --git a/contents/posts/React/img/react-toastify/toastify-1.webp b/contents/posts/React/react-toastify/img/toastify-1.webp
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-1.webp
rename to contents/posts/React/react-toastify/img/toastify-1.webp
diff --git a/contents/posts/React/img/react-toastify/toastify-2.jpeg b/contents/posts/React/react-toastify/img/toastify-2.jpeg
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-2.jpeg
rename to contents/posts/React/react-toastify/img/toastify-2.jpeg
diff --git a/contents/posts/React/img/react-toastify/toastify-2.png b/contents/posts/React/react-toastify/img/toastify-2.png
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-2.png
rename to contents/posts/React/react-toastify/img/toastify-2.png
diff --git a/contents/posts/React/img/react-toastify/toastify-2.webp b/contents/posts/React/react-toastify/img/toastify-2.webp
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-2.webp
rename to contents/posts/React/react-toastify/img/toastify-2.webp
diff --git a/contents/posts/React/img/react-toastify/toastify-3.jpeg b/contents/posts/React/react-toastify/img/toastify-3.jpeg
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-3.jpeg
rename to contents/posts/React/react-toastify/img/toastify-3.jpeg
diff --git a/contents/posts/React/img/react-toastify/toastify-3.png b/contents/posts/React/react-toastify/img/toastify-3.png
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-3.png
rename to contents/posts/React/react-toastify/img/toastify-3.png
diff --git a/contents/posts/React/img/react-toastify/toastify-3.webp b/contents/posts/React/react-toastify/img/toastify-3.webp
similarity index 100%
rename from contents/posts/React/img/react-toastify/toastify-3.webp
rename to contents/posts/React/react-toastify/img/toastify-3.webp
diff --git a/contents/posts/React/react-toastify.md b/contents/posts/React/react-toastify/index.md
similarity index 98%
rename from contents/posts/React/react-toastify.md
rename to contents/posts/React/react-toastify/index.md
index d404098..eeca0cf 100644
--- a/contents/posts/React/react-toastify.md
+++ b/contents/posts/React/react-toastify/index.md
@@ -51,7 +51,7 @@ setTimeout(() => toast("잠깐 후에 다시 알려줌!"), 5000);
`react-toastify` 는 아래와 같은 흐름으로 동작합니다
-
+
옆에 `react-toastify` 코드를 함께 보고 흐름을따라가면 이해하기가 쉽습니다! (https://github.com/fkhadra/react-toastify)
@@ -59,7 +59,7 @@ setTimeout(() => toast("잠깐 후에 다시 알려줌!"), 5000);
### 1. `` 의 마운트 및 subscribe
-
+
`react-toastify` 를 사용하기 위해서는 가장 먼저 `` 를 리액트 앱에 마운트 해야 합니다.
@@ -206,7 +206,7 @@ React 18 의 Concurrent Rendering 과 함께 도입한 [`useSyncExternalStore`](
이제 `toast()` 함수가 호출되는 순간의 흐름을 보면,
-
+
`toast()` 함수는 내부적으로 `dispatchToast()` 를 호출하고,
diff --git a/contents/posts/React/img/react-transition-group/design-exhibition-site.jpeg b/contents/posts/React/react-transition-group/img/design-exhibition-site.jpeg
similarity index 100%
rename from contents/posts/React/img/react-transition-group/design-exhibition-site.jpeg
rename to contents/posts/React/react-transition-group/img/design-exhibition-site.jpeg
diff --git a/contents/posts/React/img/react-transition-group/design-exhibition-site.png b/contents/posts/React/react-transition-group/img/design-exhibition-site.png
similarity index 100%
rename from contents/posts/React/img/react-transition-group/design-exhibition-site.png
rename to contents/posts/React/react-transition-group/img/design-exhibition-site.png
diff --git a/contents/posts/React/img/react-transition-group/design-exhibition-site.webp b/contents/posts/React/react-transition-group/img/design-exhibition-site.webp
similarity index 100%
rename from contents/posts/React/img/react-transition-group/design-exhibition-site.webp
rename to contents/posts/React/react-transition-group/img/design-exhibition-site.webp
diff --git a/contents/posts/React/img/react-transition-group/problem-1.jpeg b/contents/posts/React/react-transition-group/img/problem-1.jpeg
similarity index 100%
rename from contents/posts/React/img/react-transition-group/problem-1.jpeg
rename to contents/posts/React/react-transition-group/img/problem-1.jpeg
diff --git a/contents/posts/React/img/react-transition-group/problem-1.png b/contents/posts/React/react-transition-group/img/problem-1.png
similarity index 100%
rename from contents/posts/React/img/react-transition-group/problem-1.png
rename to contents/posts/React/react-transition-group/img/problem-1.png
diff --git a/contents/posts/React/img/react-transition-group/problem-1.webp b/contents/posts/React/react-transition-group/img/problem-1.webp
similarity index 100%
rename from contents/posts/React/img/react-transition-group/problem-1.webp
rename to contents/posts/React/react-transition-group/img/problem-1.webp
diff --git a/contents/posts/React/img/react-transition-group/problem-2.jpeg b/contents/posts/React/react-transition-group/img/problem-2.jpeg
similarity index 100%
rename from contents/posts/React/img/react-transition-group/problem-2.jpeg
rename to contents/posts/React/react-transition-group/img/problem-2.jpeg
diff --git a/contents/posts/React/img/react-transition-group/problem-2.png b/contents/posts/React/react-transition-group/img/problem-2.png
similarity index 100%
rename from contents/posts/React/img/react-transition-group/problem-2.png
rename to contents/posts/React/react-transition-group/img/problem-2.png
diff --git a/contents/posts/React/img/react-transition-group/problem-2.webp b/contents/posts/React/react-transition-group/img/problem-2.webp
similarity index 100%
rename from contents/posts/React/img/react-transition-group/problem-2.webp
rename to contents/posts/React/react-transition-group/img/problem-2.webp
diff --git a/contents/posts/React/img/react-transition-group/transition.webp b/contents/posts/React/react-transition-group/img/transition.webp
similarity index 100%
rename from contents/posts/React/img/react-transition-group/transition.webp
rename to contents/posts/React/react-transition-group/img/transition.webp
diff --git a/contents/posts/React/react-transition-group.md b/contents/posts/React/react-transition-group/index.md
similarity index 96%
rename from contents/posts/React/react-transition-group.md
rename to contents/posts/React/react-transition-group/index.md
index 5fdc5f9..4c86351 100644
--- a/contents/posts/React/react-transition-group.md
+++ b/contents/posts/React/react-transition-group/index.md
@@ -12,7 +12,7 @@ head:
디자인학과 졸업전시 웹사이트를 만들면서, 전체 페이지에 수평 아코디언 전환 애니메이션이 필요했습니다.
-
+
처음 접근은 단순히 다른 아코디언 애니메이션처럼 단순하게 접근했습니다.
모든 페이지 컴포넌트를 한 번에 전부 마운트해두고, 각 섹션의 `max-width` 만 조절하면서 열리고 닫히는 애니메이션을 구현했습니다.
@@ -22,8 +22,8 @@ head:
그런데 웬걸.. Lighthouse에서 DOM 요소가 3,495개라는 경고가 뜨고, TBT(Total Blocking Time)도 높고 메모리 사용량도 계속 늘어나는 현상이 발생하는게 아니겠습니까?
-
-
+
+
무엇보다 `안 보이는 페이지도 계속 DOM 요소로써 남아있다`는 점이 문제였습니다.
@@ -95,7 +95,7 @@ head:
~~사실 프론트같은거 좋아하는 이유도 이렇게 시각적으로 뭔가 정리하는게 이해가 쉽고 재밌어서 그렇습니다 ㅎㅎ~~
-
+
:::details 🙋♂️ 상태 전이 다이어그램에서 `[]` 는 뭔가요? - Guard
`[]` 표시는 가드(Guard) 조건을 의미합니다.
diff --git a/contents/posts/React/img/redux-flux-architecture/flux.jpeg b/contents/posts/React/redux-flux-architecture/img/flux.jpeg
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/flux.jpeg
rename to contents/posts/React/redux-flux-architecture/img/flux.jpeg
diff --git a/contents/posts/React/img/redux-flux-architecture/flux.png b/contents/posts/React/redux-flux-architecture/img/flux.png
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/flux.png
rename to contents/posts/React/redux-flux-architecture/img/flux.png
diff --git a/contents/posts/React/img/redux-flux-architecture/flux.webp b/contents/posts/React/redux-flux-architecture/img/flux.webp
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/flux.webp
rename to contents/posts/React/redux-flux-architecture/img/flux.webp
diff --git a/contents/posts/React/img/redux-flux-architecture/mvc-limit.jpeg b/contents/posts/React/redux-flux-architecture/img/mvc-limit.jpeg
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/mvc-limit.jpeg
rename to contents/posts/React/redux-flux-architecture/img/mvc-limit.jpeg
diff --git a/contents/posts/React/img/redux-flux-architecture/mvc-limit.png b/contents/posts/React/redux-flux-architecture/img/mvc-limit.png
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/mvc-limit.png
rename to contents/posts/React/redux-flux-architecture/img/mvc-limit.png
diff --git a/contents/posts/React/img/redux-flux-architecture/mvc-limit.webp b/contents/posts/React/redux-flux-architecture/img/mvc-limit.webp
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/mvc-limit.webp
rename to contents/posts/React/redux-flux-architecture/img/mvc-limit.webp
diff --git a/contents/posts/React/img/redux-flux-architecture/mvc.jpeg b/contents/posts/React/redux-flux-architecture/img/mvc.jpeg
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/mvc.jpeg
rename to contents/posts/React/redux-flux-architecture/img/mvc.jpeg
diff --git a/contents/posts/React/img/redux-flux-architecture/mvc.png b/contents/posts/React/redux-flux-architecture/img/mvc.png
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/mvc.png
rename to contents/posts/React/redux-flux-architecture/img/mvc.png
diff --git a/contents/posts/React/img/redux-flux-architecture/mvc.webp b/contents/posts/React/redux-flux-architecture/img/mvc.webp
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/mvc.webp
rename to contents/posts/React/redux-flux-architecture/img/mvc.webp
diff --git a/contents/posts/React/img/redux-flux-architecture/prop-drilling.jpeg b/contents/posts/React/redux-flux-architecture/img/prop-drilling.jpeg
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/prop-drilling.jpeg
rename to contents/posts/React/redux-flux-architecture/img/prop-drilling.jpeg
diff --git a/contents/posts/React/img/redux-flux-architecture/prop-drilling.png b/contents/posts/React/redux-flux-architecture/img/prop-drilling.png
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/prop-drilling.png
rename to contents/posts/React/redux-flux-architecture/img/prop-drilling.png
diff --git a/contents/posts/React/img/redux-flux-architecture/prop-drilling.webp b/contents/posts/React/redux-flux-architecture/img/prop-drilling.webp
similarity index 100%
rename from contents/posts/React/img/redux-flux-architecture/prop-drilling.webp
rename to contents/posts/React/redux-flux-architecture/img/prop-drilling.webp
diff --git a/contents/posts/React/redux-flux-architecture.md b/contents/posts/React/redux-flux-architecture/index.md
similarity index 98%
rename from contents/posts/React/redux-flux-architecture.md
rename to contents/posts/React/redux-flux-architecture/index.md
index ecb4368..f365cec 100644
--- a/contents/posts/React/redux-flux-architecture.md
+++ b/contents/posts/React/redux-flux-architecture/index.md
@@ -29,7 +29,7 @@ PHP 기반의 웹 프레임워크는 기본적으로 MVC (Model - View - Control
> `뷰 (View)` : 사용자에게 보이는 인터페이스로, HTML, CSS 이나 템플릿엔진을 활용해 화면을 구성합니다.
> `컨트롤러 (Controller)` : Model 과 View 사이의 상호작용을 관리합니다. 사용자의 요청 / 입력을 받아 Model 을 업데이트하고, 그에 따른 View 를 갱신하는 작업을 합니다.
-
+
하지만, 애플리케이션의 규모가 커지면서, MVC 구조는 점점 더 복잡해져 갔습니다.
@@ -47,7 +47,7 @@ PHP 기반의 웹 프레임워크는 기본적으로 MVC (Model - View - Control
라는 단점으로 다가왔습니다.
-
+
### ✍️ MVVM 아키텍쳐과 Component 패턴
@@ -69,7 +69,7 @@ PHP 기반의 웹 프레임워크는 기본적으로 MVC (Model - View - Control
하지만, Container-Presenter 패턴을 이용해 만들었을때, 컴포넌트 구조가 복잡해짐에 따라, 하위 컴포넌트에 값을 전달하기 위해, `Props Drilling Problem` 이 발생하게 됩니다.
-
+
### ✍️ Flux 아키텍쳐
@@ -77,7 +77,7 @@ Container-Presenter 패턴에서 발생한 Prop Drilling 을 통해 데이터를
그래서 단방향 데이터 흐름을 활용한 리액트용 애플리케이션 아키텍쳐인 Flux 아키텍쳐가 탄생했습니다.
-
+
데이터를 변화시키려는 동작(Action) 이 발생하면
Dispatcher 는 Action 을 받아 Redux 에 Action 이 발생했음을 알리고,
@@ -134,7 +134,7 @@ Redux 는 다음과 같은 요소로 구성되어 있습니다.
Redux 의 구성요소와 함께 Flux 아키텍쳐가 어떻게 적용되어 Redux 의 상태가 변화하고, View 에 반영되는지 이전에 봤던 그림과 함께 알아보겠습니다.
-
+
실제 Counter 예제를 통해 Redux의 데이터 흐름이 어떻게 동작하는지 단계별로 살펴보겠습니다.
diff --git a/contents/posts/React/redux-normalizing-state-shape.md b/contents/posts/React/redux-normalizing-state-shape/index.md
similarity index 100%
rename from contents/posts/React/redux-normalizing-state-shape.md
rename to contents/posts/React/redux-normalizing-state-shape/index.md
diff --git a/contents/posts/React/redux-vs-context.md b/contents/posts/React/redux-vs-context/index.md
similarity index 100%
rename from contents/posts/React/redux-vs-context.md
rename to contents/posts/React/redux-vs-context/index.md
diff --git a/contents/posts/React/solid-render-props.md b/contents/posts/React/solid-render-props/index.md
similarity index 100%
rename from contents/posts/React/solid-render-props.md
rename to contents/posts/React/solid-render-props/index.md
diff --git a/contents/posts/React/img/storybook-mcp/1.jpeg b/contents/posts/React/storybook-mcp/img/1.jpeg
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/1.jpeg
rename to contents/posts/React/storybook-mcp/img/1.jpeg
diff --git a/contents/posts/React/img/storybook-mcp/1.png b/contents/posts/React/storybook-mcp/img/1.png
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/1.png
rename to contents/posts/React/storybook-mcp/img/1.png
diff --git a/contents/posts/React/img/storybook-mcp/1.webp b/contents/posts/React/storybook-mcp/img/1.webp
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/1.webp
rename to contents/posts/React/storybook-mcp/img/1.webp
diff --git a/contents/posts/React/img/storybook-mcp/2.jpeg b/contents/posts/React/storybook-mcp/img/2.jpeg
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/2.jpeg
rename to contents/posts/React/storybook-mcp/img/2.jpeg
diff --git a/contents/posts/React/img/storybook-mcp/2.png b/contents/posts/React/storybook-mcp/img/2.png
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/2.png
rename to contents/posts/React/storybook-mcp/img/2.png
diff --git a/contents/posts/React/img/storybook-mcp/2.webp b/contents/posts/React/storybook-mcp/img/2.webp
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/2.webp
rename to contents/posts/React/storybook-mcp/img/2.webp
diff --git a/contents/posts/React/img/storybook-mcp/tools.jpeg b/contents/posts/React/storybook-mcp/img/tools.jpeg
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/tools.jpeg
rename to contents/posts/React/storybook-mcp/img/tools.jpeg
diff --git a/contents/posts/React/img/storybook-mcp/tools.png b/contents/posts/React/storybook-mcp/img/tools.png
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/tools.png
rename to contents/posts/React/storybook-mcp/img/tools.png
diff --git a/contents/posts/React/img/storybook-mcp/tools.webp b/contents/posts/React/storybook-mcp/img/tools.webp
similarity index 100%
rename from contents/posts/React/img/storybook-mcp/tools.webp
rename to contents/posts/React/storybook-mcp/img/tools.webp
diff --git a/contents/posts/React/storybook-mcp.md b/contents/posts/React/storybook-mcp/index.md
similarity index 97%
rename from contents/posts/React/storybook-mcp.md
rename to contents/posts/React/storybook-mcp/index.md
index 8996dc5..0b746cd 100644
--- a/contents/posts/React/storybook-mcp.md
+++ b/contents/posts/React/storybook-mcp/index.md
@@ -49,7 +49,7 @@ Storybook MCP를 활성화하면, AI 코딩 도구는 Storybook을 문서 사이
현재 2026년 2월을 기준으로 Storybook MCP 가 제공하는 주요 도구는 다음과 같습니다.
-
+
## 1. 전체 컴포넌트 / 문서 목록 조회 (`list-all-documentation`)
@@ -184,8 +184,8 @@ Storybook을 실행하면 `http://localhost:6006/mcp` 로 MCP 서버가 자동
또는 Antigravity UI 에서 MCP Servers 설정으로 들어가서 `mcp_config.json` 을 찾을수도 있습니다
-
-
+
+
### Claude Code
diff --git a/contents/posts/React/use-imperative-handle.md b/contents/posts/React/use-imperative-handle/index.md
similarity index 100%
rename from contents/posts/React/use-imperative-handle.md
rename to contents/posts/React/use-imperative-handle/index.md
diff --git a/contents/posts/React/img/what-is-isomorphic/warn.jpeg b/contents/posts/React/what-is-isomorphic/img/warn.jpeg
similarity index 100%
rename from contents/posts/React/img/what-is-isomorphic/warn.jpeg
rename to contents/posts/React/what-is-isomorphic/img/warn.jpeg
diff --git a/contents/posts/React/img/what-is-isomorphic/warn.png b/contents/posts/React/what-is-isomorphic/img/warn.png
similarity index 100%
rename from contents/posts/React/img/what-is-isomorphic/warn.png
rename to contents/posts/React/what-is-isomorphic/img/warn.png
diff --git a/contents/posts/React/img/what-is-isomorphic/warn.webp b/contents/posts/React/what-is-isomorphic/img/warn.webp
similarity index 100%
rename from contents/posts/React/img/what-is-isomorphic/warn.webp
rename to contents/posts/React/what-is-isomorphic/img/warn.webp
diff --git a/contents/posts/React/what-is-isomorphic.md b/contents/posts/React/what-is-isomorphic/index.md
similarity index 99%
rename from contents/posts/React/what-is-isomorphic.md
rename to contents/posts/React/what-is-isomorphic/index.md
index f39f76a..fba220d 100644
--- a/contents/posts/React/what-is-isomorphic.md
+++ b/contents/posts/React/what-is-isomorphic/index.md
@@ -141,7 +141,7 @@ export const useIsomorphicEffect = typeof window !== "undefined" ? useLayoutEffe
그래서 "페인트 전에 동기 실행, DOM 조작" 이라는 전제 자체가 성립 안 됨으로, 실행할 타이밍이 없고 다음과 같은 경고가 발생합니다.
-
+
> Warning: useLayoutEffect does nothing on the server, because its effect runs after the DOM is updated...
diff --git a/contents/posts/TypeScript/chain-of-responsibility.md b/contents/posts/TypeScript/chain-of-responsibility/index.md
similarity index 100%
rename from contents/posts/TypeScript/chain-of-responsibility.md
rename to contents/posts/TypeScript/chain-of-responsibility/index.md
diff --git a/contents/posts/Web/img/authentication-authorization/csrf-defend.png b/contents/posts/Web/authentication-authorization/img/csrf-defend.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/csrf-defend.png
rename to contents/posts/Web/authentication-authorization/img/csrf-defend.png
diff --git a/contents/posts/Web/img/authentication-authorization/csrf.png b/contents/posts/Web/authentication-authorization/img/csrf.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/csrf.png
rename to contents/posts/Web/authentication-authorization/img/csrf.png
diff --git a/contents/posts/Web/img/authentication-authorization/jwt-1.png b/contents/posts/Web/authentication-authorization/img/jwt-1.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/jwt-1.png
rename to contents/posts/Web/authentication-authorization/img/jwt-1.png
diff --git a/contents/posts/Web/img/authentication-authorization/jwt-2.png b/contents/posts/Web/authentication-authorization/img/jwt-2.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/jwt-2.png
rename to contents/posts/Web/authentication-authorization/img/jwt-2.png
diff --git a/contents/posts/Web/img/authentication-authorization/jwt-access-refresh.png b/contents/posts/Web/authentication-authorization/img/jwt-access-refresh.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/jwt-access-refresh.png
rename to contents/posts/Web/authentication-authorization/img/jwt-access-refresh.png
diff --git a/contents/posts/Web/img/authentication-authorization/jwt.png b/contents/posts/Web/authentication-authorization/img/jwt.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/jwt.png
rename to contents/posts/Web/authentication-authorization/img/jwt.png
diff --git a/contents/posts/Web/img/authentication-authorization/session-1.png b/contents/posts/Web/authentication-authorization/img/session-1.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/session-1.png
rename to contents/posts/Web/authentication-authorization/img/session-1.png
diff --git a/contents/posts/Web/img/authentication-authorization/session-2.png b/contents/posts/Web/authentication-authorization/img/session-2.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/session-2.png
rename to contents/posts/Web/authentication-authorization/img/session-2.png
diff --git a/contents/posts/Web/img/authentication-authorization/session-3.png b/contents/posts/Web/authentication-authorization/img/session-3.png
similarity index 100%
rename from contents/posts/Web/img/authentication-authorization/session-3.png
rename to contents/posts/Web/authentication-authorization/img/session-3.png
diff --git a/contents/posts/Web/authentication-authorization.md b/contents/posts/Web/authentication-authorization/index.md
similarity index 94%
rename from contents/posts/Web/authentication-authorization.md
rename to contents/posts/Web/authentication-authorization/index.md
index b5afa3c..88d5186 100644
--- a/contents/posts/Web/authentication-authorization.md
+++ b/contents/posts/Web/authentication-authorization/index.md
@@ -46,7 +46,7 @@ Session 은 서버에서 생성되며, 보통 클라이언트에 Cookie 를 통
## Session 방식의 인증인가
-
+
> 사용자가 로그인 (인증) 을 요청하면...
> (1) Client 가 ID , PW 를 이용해 로그인 요청을 보냅니다
@@ -54,7 +54,7 @@ Session 은 서버에서 생성되며, 보통 클라이언트에 Cookie 를 통
> (3) 올바른 사용자가 인증을 요청한 경우, Session 을 생성해 저장합니다
> (4) 마지막으로 서버는 Cookie 에 SessionID 를 담아 클라이언트에 전달합니다 (HTTP Only Cookie)
-
+
> 이후 인증이 필요한 API 를 요청하면...
> (1) 해당요청에는 자동으로 Cookie 가 함께 서버로 전송됍니다
@@ -63,7 +63,7 @@ Session 은 서버에서 생성되며, 보통 클라이언트에 Cookie 를 통
> (4) 인증이 필요한 API 에 필요한 데이터를 가져와
> (5) 응답을 클라이언트에 전송합니다
-
+
> 사용자가 로그아웃을 요청하면...
> (1) 로그아웃 엔드포인트로 API 요청을 날립니다. 이때 쿠키에 세션정보가 함께 전송됩니다.
@@ -92,7 +92,7 @@ Session 은 서버에서 생성되며, 보통 클라이언트에 Cookie 를 통
JWT 는 JSON 객체를 사용해 정보를 안전하게 전달하기 위한 개방형 표준 (RFC 7519) 입니다.
JWT 는 주로 인증과 정보 교환에 사용됩니다.
-
+
JWT 는 Header, Payload, Signature 세 부분으로 구성됍니다.
@@ -109,7 +109,7 @@ JWT 는 Header, Payload, Signature 세 부분으로 구성됍니다.
## JWT 방식의 인증인가
-
+
> 사용자가 로그인 (인증) 을 요청하면...
> (1) Client 가 ID , PW 를 이용해 로그인 요청을 보냅니다
@@ -118,7 +118,7 @@ JWT 는 Header, Payload, Signature 세 부분으로 구성됍니다.
> (4) 마지막으로 서버는 JWT 토큰을 응답으로 전송하고
> (5) 클라이언트는 LocalStorage, SessionStorage, ReduxPersist 등 클라이언트측 Storage 에 저장합니다
-
+
> 이후 인증이 필요한 API 를 요청하면...
> (1) 클라이언트에서 요청시, HTTP Header 의 Authorization 필드에 JWT 토큰을 삽입해 요청합니다.
@@ -143,7 +143,7 @@ Access Token, Refresh Token 을 이용하여 인증 인가를 구현합니다.
두 토큰 모두 JWT 기반의 토큰이지만, Refresh Token 은 Access Token 을 재발급 받는 용도로 사용합니다.
자주 사용되는 Access Token 은 유효기간을 짧게 하여 Token 이 탈취돼도 탈취자가 오래 사용하지 못하도록 방지할 수 있습니다.
-
+
# CSRF (Cross-Site Request Forgery)
@@ -160,7 +160,7 @@ CSRF 공격이 진행되려면 다음 두 조건을 만족해야 합니다.
이해를 돕기위해 사용자가 A 에게 송금하는 상황을 가정해보겠습니다.
-
+
사용자는 로그인 되어있는 상태이기 때문에, Session ID, Token 을 탈취해 조작된 요청을 보낼 수 있습니다.
@@ -171,7 +171,7 @@ CSRF 공격이 진행되려면 다음 두 조건을 만족해야 합니다.
Referer 검증은 Request 를 보내는 Referer 가 일치하는지 검사하는 방법입니다.
Referer 헤더는 HTTP 요청의 일부로 전송되는 헤더로, 요청을 보내는 웹 페이지의 출처를 가지고 있습니다.
-
+
Referer 헤더를 분석하여, 요청이 어디서 왔는지 확인하고, 다른 도메인에서의 요청을 제한하거나 보안을 강화할 수 있습니다.
diff --git a/contents/posts/Web/img/browser-rendering-in-depth/chrome-browser-rendering.svg b/contents/posts/Web/browser-rendering-in-depth/img/chrome-browser-rendering.svg
similarity index 100%
rename from contents/posts/Web/img/browser-rendering-in-depth/chrome-browser-rendering.svg
rename to contents/posts/Web/browser-rendering-in-depth/img/chrome-browser-rendering.svg
diff --git a/contents/posts/Web/browser-rendering-in-depth.md b/contents/posts/Web/browser-rendering-in-depth/index.md
similarity index 96%
rename from contents/posts/Web/browser-rendering-in-depth.md
rename to contents/posts/Web/browser-rendering-in-depth/index.md
index 2d8be3f..7412bf4 100644
--- a/contents/posts/Web/browser-rendering-in-depth.md
+++ b/contents/posts/Web/browser-rendering-in-depth/index.md
@@ -12,7 +12,7 @@ head:
## 🎨 그림으로 한눈에 보는 브라우저 렌더링과정
-
+
## ✍️ 참고자료
diff --git a/contents/posts/Web/css-cascade-algorithm.md b/contents/posts/Web/css-cascade-algorithm/index.md
similarity index 100%
rename from contents/posts/Web/css-cascade-algorithm.md
rename to contents/posts/Web/css-cascade-algorithm/index.md
diff --git a/contents/posts/Web/img/image-format/image-1.jpeg b/contents/posts/Web/image-format/img/image-1.jpeg
similarity index 100%
rename from contents/posts/Web/img/image-format/image-1.jpeg
rename to contents/posts/Web/image-format/img/image-1.jpeg
diff --git a/contents/posts/Web/img/image-format/image-1.png b/contents/posts/Web/image-format/img/image-1.png
similarity index 100%
rename from contents/posts/Web/img/image-format/image-1.png
rename to contents/posts/Web/image-format/img/image-1.png
diff --git a/contents/posts/Web/img/image-format/image-1.webp b/contents/posts/Web/image-format/img/image-1.webp
similarity index 100%
rename from contents/posts/Web/img/image-format/image-1.webp
rename to contents/posts/Web/image-format/img/image-1.webp
diff --git a/contents/posts/Web/img/image-format/image-2.jpeg b/contents/posts/Web/image-format/img/image-2.jpeg
similarity index 100%
rename from contents/posts/Web/img/image-format/image-2.jpeg
rename to contents/posts/Web/image-format/img/image-2.jpeg
diff --git a/contents/posts/Web/img/image-format/image-2.png b/contents/posts/Web/image-format/img/image-2.png
similarity index 100%
rename from contents/posts/Web/img/image-format/image-2.png
rename to contents/posts/Web/image-format/img/image-2.png
diff --git a/contents/posts/Web/img/image-format/image-2.webp b/contents/posts/Web/image-format/img/image-2.webp
similarity index 100%
rename from contents/posts/Web/img/image-format/image-2.webp
rename to contents/posts/Web/image-format/img/image-2.webp
diff --git a/contents/posts/Web/img/image-format/image-3.jpeg b/contents/posts/Web/image-format/img/image-3.jpeg
similarity index 100%
rename from contents/posts/Web/img/image-format/image-3.jpeg
rename to contents/posts/Web/image-format/img/image-3.jpeg
diff --git a/contents/posts/Web/img/image-format/image-3.png b/contents/posts/Web/image-format/img/image-3.png
similarity index 100%
rename from contents/posts/Web/img/image-format/image-3.png
rename to contents/posts/Web/image-format/img/image-3.png
diff --git a/contents/posts/Web/img/image-format/image-3.webp b/contents/posts/Web/image-format/img/image-3.webp
similarity index 100%
rename from contents/posts/Web/img/image-format/image-3.webp
rename to contents/posts/Web/image-format/img/image-3.webp
diff --git a/contents/posts/Web/img/image-format/image-4.gif b/contents/posts/Web/image-format/img/image-4.gif
similarity index 100%
rename from contents/posts/Web/img/image-format/image-4.gif
rename to contents/posts/Web/image-format/img/image-4.gif
diff --git a/contents/posts/Web/img/image-format/image-5.jpeg b/contents/posts/Web/image-format/img/image-5.jpeg
similarity index 100%
rename from contents/posts/Web/img/image-format/image-5.jpeg
rename to contents/posts/Web/image-format/img/image-5.jpeg
diff --git a/contents/posts/Web/img/image-format/image-5.png b/contents/posts/Web/image-format/img/image-5.png
similarity index 100%
rename from contents/posts/Web/img/image-format/image-5.png
rename to contents/posts/Web/image-format/img/image-5.png
diff --git a/contents/posts/Web/img/image-format/image-5.webp b/contents/posts/Web/image-format/img/image-5.webp
similarity index 100%
rename from contents/posts/Web/img/image-format/image-5.webp
rename to contents/posts/Web/image-format/img/image-5.webp
diff --git a/contents/posts/Web/img/image-format/image-6.jpeg b/contents/posts/Web/image-format/img/image-6.jpeg
similarity index 100%
rename from contents/posts/Web/img/image-format/image-6.jpeg
rename to contents/posts/Web/image-format/img/image-6.jpeg
diff --git a/contents/posts/Web/img/image-format/image-6.png b/contents/posts/Web/image-format/img/image-6.png
similarity index 100%
rename from contents/posts/Web/img/image-format/image-6.png
rename to contents/posts/Web/image-format/img/image-6.png
diff --git a/contents/posts/Web/img/image-format/image-6.webp b/contents/posts/Web/image-format/img/image-6.webp
similarity index 100%
rename from contents/posts/Web/img/image-format/image-6.webp
rename to contents/posts/Web/image-format/img/image-6.webp
diff --git a/contents/posts/Web/img/image-format/image-7.jpeg b/contents/posts/Web/image-format/img/image-7.jpeg
similarity index 100%
rename from contents/posts/Web/img/image-format/image-7.jpeg
rename to contents/posts/Web/image-format/img/image-7.jpeg
diff --git a/contents/posts/Web/img/image-format/image-7.png b/contents/posts/Web/image-format/img/image-7.png
similarity index 100%
rename from contents/posts/Web/img/image-format/image-7.png
rename to contents/posts/Web/image-format/img/image-7.png
diff --git a/contents/posts/Web/img/image-format/image-7.webp b/contents/posts/Web/image-format/img/image-7.webp
similarity index 100%
rename from contents/posts/Web/img/image-format/image-7.webp
rename to contents/posts/Web/image-format/img/image-7.webp
diff --git a/contents/posts/Web/image-format.md b/contents/posts/Web/image-format/index.md
similarity index 96%
rename from contents/posts/Web/image-format.md
rename to contents/posts/Web/image-format/index.md
index 056464e..25e5db5 100644
--- a/contents/posts/Web/image-format.md
+++ b/contents/posts/Web/image-format/index.md
@@ -18,7 +18,7 @@ comment: true
그리고 그 결과는?
-
+
웬 삐에로가 나타나서 **_"응~ 이미지 그딴식으로 처리해봐~ 브라우저 뻗으면 그만이야"_** 라고 말하는게 아니겠습니까?
@@ -34,7 +34,7 @@ comment: true
@@ -106,10 +106,10 @@ Progressive JPEG 는 이미지를 여러 번의 Scan (Pass) 를 통해 점진적
#### (1) AWS Lambda (Node.js) + Sharp 로 이미지 업로드 시점에 변환하기
-
+
AWS Lambda 에서 S3 트리거 이벤트를 사용하면 이미지 업로드 시점에 자동으로 Progressive JPEG 로 변환할 수 있습니다
-([관련 글 : AWS Lambda & S3 트리거로 이미지 최적화 자동화하기](../Aws/lambda-image-optimization.md))
+([관련 글 : AWS Lambda & S3 트리거로 이미지 최적화 자동화하기](../../Aws/lambda-image-optimization/index.md))
@@ -221,7 +221,7 @@ JPEG 대비 50% 이상, WebP 대비 20~30% 더 작은 파일 크기로 압축할
특히 Internet Explorer (IE) 는 AVIF/WebP 를 전혀 지원하지 않기 때문에, AVIF/WebP 만 사용하는 것은 위험할 수 있습니다
-
+
그래서, AVIF/WebP 를 사용하되, 브라우저가 WebP 를 지원하지 않는 경우에는 JPEG 나 PNG 같은 대체 포맷을 제공하는 것이 좋습니다
@@ -303,7 +303,7 @@ export const Picture = ({ srcAvif, srcWebp, srcFallback, alt, ...imgProps }: Pic
> "가능하면 단일 포맷에 올인하지 말고, 사용자 환경에 맞는 최적의 조합을 제공하자!" 입니다.
-[다음 편에서는 실제 React 환경에서 이미지 지연로딩과 같은 최적화 기법을 적용하는 방법에 대해 알아보겠습니다](./image-optimization.md)
+[다음 편에서는 실제 React 환경에서 이미지 지연로딩과 같은 최적화 기법을 적용하는 방법에 대해 알아보겠습니다](../image-optimization/index.md)
## 참고 자료
diff --git a/contents/posts/Web/image-optimization.md b/contents/posts/Web/image-optimization/index.md
similarity index 100%
rename from contents/posts/Web/image-optimization.md
rename to contents/posts/Web/image-optimization/index.md
diff --git a/contents/posts/Web/network-rest-api.md b/contents/posts/Web/network-rest-api/index.md
similarity index 100%
rename from contents/posts/Web/network-rest-api.md
rename to contents/posts/Web/network-rest-api/index.md
diff --git a/contents/posts/Web/img/trolley-dilemma-compatibility/trolley.jpeg b/contents/posts/Web/trolley-dilemma-compatibility/img/trolley.jpeg
similarity index 100%
rename from contents/posts/Web/img/trolley-dilemma-compatibility/trolley.jpeg
rename to contents/posts/Web/trolley-dilemma-compatibility/img/trolley.jpeg
diff --git a/contents/posts/Web/img/trolley-dilemma-compatibility/trolley.jpg b/contents/posts/Web/trolley-dilemma-compatibility/img/trolley.jpg
similarity index 100%
rename from contents/posts/Web/img/trolley-dilemma-compatibility/trolley.jpg
rename to contents/posts/Web/trolley-dilemma-compatibility/img/trolley.jpg
diff --git a/contents/posts/Web/img/trolley-dilemma-compatibility/trolley.webp b/contents/posts/Web/trolley-dilemma-compatibility/img/trolley.webp
similarity index 100%
rename from contents/posts/Web/img/trolley-dilemma-compatibility/trolley.webp
rename to contents/posts/Web/trolley-dilemma-compatibility/img/trolley.webp
diff --git a/contents/posts/Web/trolley-dilemma-compatibility.md b/contents/posts/Web/trolley-dilemma-compatibility/index.md
similarity index 97%
rename from contents/posts/Web/trolley-dilemma-compatibility.md
rename to contents/posts/Web/trolley-dilemma-compatibility/index.md
index 48280a9..8bde7fc 100644
--- a/contents/posts/Web/trolley-dilemma-compatibility.md
+++ b/contents/posts/Web/trolley-dilemma-compatibility/index.md
@@ -18,7 +18,7 @@ comment: true
웹 개발도 마찬가지
-
+
[Can I Use](https://caniuse.com/) 같은 사이트를 보면 대부분 브라우저는 최신 기능을 지원하지만, 소수의 **IE나 Safari 구버전**은 지원하지 않는 경우가 많음
diff --git a/data/posts.json b/data/posts.json
index 5b807d0..04f5029 100644
--- a/data/posts.json
+++ b/data/posts.json
@@ -1,4 +1,13 @@
[
+ {
+ "url": "/posts/React/constellation-impl",
+ "frontmatter": {
+ "title": "정적 좌표 지옥에서 탈출한 동적 별자리 노드 시스템 구축기",
+ "createdAt": "2026-03-02",
+ "category": "React",
+ "description": "누비랩 냠냠플러스 \"오늘찰칵\" 서비스의 별자리 맵 시스템을 하드코딩된 좌표 대신 기하학 알고리즘과 Render Props 패턴으로 해결하며 유지보수성과 확장성을 확보한 경험을 공유합니다."
+ }
+ },
{
"url": "/posts/React/storybook-mcp",
"frontmatter": {
@@ -35,15 +44,6 @@
"description": "재귀함수를 활용하여 순열(Permutation) 을 구현하는 방법에 대해 알아봅니다. SWAP 기반 방식과 DFS 기반 방식을 비교해봅니다."
}
},
- {
- "url": "/posts/CS/DataStructure/js-heap",
- "frontmatter": {
- "title": "JavaScript 로 구현하는 Heap 자료구조",
- "createdAt": "2025-12-22T00:00:00.000Z",
- "category": "CS",
- "description": "Heap(힙) 자료구조는 우선순위 큐를 구현하는 데 자주 사용됩니다. 이 글에서는 JavaScript로 최소 힙(Min-Heap)과 최대 힙(Max-Heap)을 구현하는 방법을 단계별로 설명합니다."
- }
- },
{
"url": "/posts/Etc/overcoming-difficult-times",
"frontmatter": {
@@ -80,15 +80,6 @@
"description": "Server Sent Events (SSE) 를 외부에서도 순차적으로 어떻게 다룰수 있을까? 종합설계프로젝트를 진행하면서 LLM으로부터 스트리밍 응답을 깔끔하게 처리하기 위해 Generator 를 활용한 방법을 공유합니다."
}
},
- {
- "url": "/posts/Web/browser-coordinate",
- "frontmatter": {
- "title": "브라우저의 좌표계는 어떻게 계산될까 ? (feat. DOMMatrix, 변환 행렬)",
- "createdAt": "2025-11-22T00:00:00.000Z",
- "category": "Web",
- "description": "브라우저에서 좌표계가 어떻게 계산되는지, DOMMatrix와 변환 행렬을 중심으로 설명합니다. translate, rotate, scale 에 따라 Viewport, Local 좌표계가 어떻게 계산되는지 알아봅니다."
- }
- },
{
"url": "/posts/Etc/kakao-tech-campus-record",
"frontmatter": {
@@ -107,15 +98,6 @@
"description": "이 글은 Mark Erikson의 \"Why React Context is Not a 'State Management' Tool (and Why It Doesn't Replace Redux)\" 을 기반으로 번역 및 보완한 글입니다. 저작권은 원문 저자에게 있습니다. 다소 의역이 포함되어 있을 수 있습니다."
}
},
- {
- "url": "/posts/React/redux-create-entity-adapter",
- "frontmatter": {
- "title": "[ReduxToolkit 공식문서 번역] createEntityAdapter",
- "createdAt": "2025-11-12T00:00:00.000Z",
- "category": "React",
- "description": "Redux Toolkit의 createEntityAdapter는 전역 상태 관리를 위한 효율적인 방법을 제공합니다. 이 포스트에서는 createEntityAdapter의 개념과 사용법, 그리고 이를 활용한 전역 상태 관리 방법에 대해 알아봅니다."
- }
- },
{
"url": "/posts/React/solid-render-props",
"frontmatter": {
@@ -152,15 +134,6 @@
"description": "오픈소스를 보다보면 Isomorphic 이라는 단어를 마주치게 됩니다. Isomorphic 이란 무엇인지, 그리고 어떨때 사용하는 네이밍인지에 대해 알아봅니다. 또 리액트에서 자주 사용되는 useIsomorphicEffect 훅도 함께 살펴봅니다."
}
},
- {
- "url": "/posts/Web/critical-rendering-path",
- "frontmatter": {
- "title": "Web Vitals 과 브라우저의 렌더링 파이프라인 Deep Dive",
- "createdAt": "2025-10-28T00:00:00.000Z",
- "category": "Web",
- "description": "웹 브라우저가 HTML, CSS, JS 파일을 어떻게 처리하여 화면에 렌더링하는지, 그리고 Web Vitals가 무엇인지에 대해 설명합니다. 추가적으로 이미지, 폰트, HTTP 요청은 언제 발생하며 이에 따라 Web Vitals 지표가 어떻게 변화하는지 알아봅니다"
- }
- },
{
"url": "/posts/CS/DataStructure/idempotency-hash-table",
"frontmatter": {
@@ -179,15 +152,6 @@
"description": "불변성(Immutability) 는 개발 공부를 하다 보면 정말 자주 듣는 단어다. 값을 바꾸지 않는다는 말은 이해되지만, 자바스크립트에서 그게 어떻게 동작하는지, 그리고 왜 React 에서는 꼭 지켜야 하는지 알아보자."
}
},
- {
- "url": "/posts/Web/indexed-db",
- "frontmatter": {
- "title": "IndexedDB 를 TypeOrm 처럼 사용하기",
- "createdAt": "2025-10-07T00:00:00.000Z",
- "category": "Web",
- "description": "IndexedDB 는 브라우저 내장 데이터베이스로, 대용량 데이터를 클라이언트에 저장할 수 있습니다. 이 글에서는 TypeOrm 스타일의 추상화를 통해 IndexedDB 를 더 쉽게 사용하는 방법을 소개합니다."
- }
- },
{
"url": "/posts/React/build-react-1",
"frontmatter": {
diff --git a/package.json b/package.json
index 5720863..ee85d9e 100644
--- a/package.json
+++ b/package.json
@@ -18,5 +18,6 @@
"@giscus/vue": "^3.1.1",
"katex": "^0.16.25",
"markdown-it-katex": "^2.0.3"
- }
+ },
+ "version": "0.0.0"
}
diff --git a/scripts/generate-posts.mjs b/scripts/generate-posts.mjs
index 01b33ea..23d3d46 100644
--- a/scripts/generate-posts.mjs
+++ b/scripts/generate-posts.mjs
@@ -60,15 +60,25 @@ function createPostObject(frontmatter, filePath, urlPrefix) {
* @returns {Promise