diff --git "a/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/hyun2/\353\246\264\353\246\254\354\246\210 \353\205\270\355\212\270 \353\266\204\354\204\235 \355\233\210\353\240\250/fix(reactivity): \352\263\204\354\202\260\353\220\234 \352\262\214\355\204\260\354\227\220\354\204\234 \353\254\264\355\225\234 \354\236\254\352\267\200 \353\260\251\354\247\200 .md" "b/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/hyun2/\353\246\264\353\246\254\354\246\210 \353\205\270\355\212\270 \353\266\204\354\204\235 \355\233\210\353\240\250/fix(reactivity): \352\263\204\354\202\260\353\220\234 \352\262\214\355\204\260\354\227\220\354\204\234 \353\254\264\355\225\234 \354\236\254\352\267\200 \353\260\251\354\247\200 .md"
new file mode 100644
index 0000000..b41e2b8
--- /dev/null
+++ "b/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/hyun2/\353\246\264\353\246\254\354\246\210 \353\205\270\355\212\270 \353\266\204\354\204\235 \355\233\210\353\240\250/fix(reactivity): \352\263\204\354\202\260\353\220\234 \352\262\214\355\204\260\354\227\220\354\204\234 \353\254\264\355\225\234 \354\236\254\352\267\200 \353\260\251\354\247\200 .md"
@@ -0,0 +1,145 @@
+# Vue 3.5 RC1 - Reactivity 무한 재귀 버그 수정
+
+## 개요
+
+Vue 3.5 RC1에서는 중요한 반응성 관련 버그가 수정되었다.
+기존에는 정상적으로 작동하던 `ref`와 `reactive` 조합이
+Vue 3.5에서 **무한 재귀 호출**로 인해 `Maximum call stack size exceeded` 에러를 유발하게 되었다.
+이 글에서는 그 원인과 해결 과정을 Vue 내부 동작과 함께 분석한다.
+
+---
+
+## 문제 상황
+
+Vue 공식 CHANGELOG에서도 해당 문제는 다음과 같이 명시되어 있다.
+
+> [reactivity: avoid infinite recursion when mutating ref wrapped in reactive](https://github.com/vuejs/core/blob/main/CHANGELOG.md#350-rc1-2024-08-29)
+> [commit 313e4bf](https://github.com/vuejs/core/commit/313e4bf))
+> Closes [#11696](https://github.com/vuejs/core/issues/11696)
+
+---
+
+## 재현 코드
+
+```vue
+
+
+
+
+
+```
+
+---
+
+## 내부 동작 설명
+
+Vue에서 `reactive()`는 내부적으로 `Proxy`를 생성하고, 이를 조작할 수 있는 **핸들러 클래스**를 지정한다.
+가장 일반적인 경우, Vue는 `BaseReactiveHandler`를 기반으로 한 `MutableReactiveHandler` 를 사용한다.
+
+`MutableReactiveHandler`는 `Proxy`의 `set()` 을 다음과 같이 오버라이드한다:
+
+### set 메서드 구조
+
+```ts
+set(
+ target: Record,
+ key: string | symbol,
+ value: unknown,
+ receiver: object
+): boolean
+```
+
+### 기존 구현 방식
+
+```ts
+const result = Reflect.set(target, key, value, receiver);
+```
+
+여기서 중요하게 볼 인자는 4번째 `receiver`이다. 해당 인자는 setter가 실행될 때 this로 사용할 값을 전달한다.
+
+이때 문제는 `receiver`가 `ref` 객체일 경우, 내부 `setter`에서 `this`가 Proxy로 바뀌어버린다는 점이다.
+`ref`는 내부적으로 다음과 같은 getter/setter 구조를 가진다:
+
+```ts
+{
+ get value() {
+ track()
+ return _value
+ },
+ set value(newVal) {
+ _value = newVal
+ trigger()
+ }
+}
+```
+
+만약 `this`가 `ref`가 아닌 Proxy라면 → `this._value`가 정의되지 않아 동작이 꼬이게 된다.
+그리고 내부에서 다시 reactive 처리가 일어나면서 **무한 재귀**가 발생하는 것이다.
+
+---
+
+## 문제가 되는 케이스 예시
+
+```ts
+import { reactive, ref, effect } from 'vue';
+
+const a = reactive(ref(1));
+
+effect(() => {
+ console.log(a.value); // 이걸 반응형으로 감시함
+});
+
+a.value++;
+```
+
+`Maximum call stack size exceeded`이 발생하게 된다.
+
+1. effect(() => console.log(a.value)) 실행
+ -> a.value에 의존성을 등록하여 a.value가 바뀌면 effect가 다시 실행되어야함
+2. a.value++ 실행
+ -> set a.value = 2 가 실행됨 이제 proxy의 set()트랩이 실행되고, vue 내부에서 trigger()가 호출됨
+3. trigger()가 종속된 effect 재실행
+4. effect안에 a.value가 있음
+ -> 다시 getter 부르고 끝나야하지만, vue 내부 로직이 깨졌기 때문에 setter를 또 트리거
+
+> Q. 왜 setter를 또 트리거 하나?
+> this가 ref가 아니라 Proxy가 돼서, trigger()가 ref가 아닌걸 트리거하거나, 값 비교가 꺠져서 항상 바뀌었다고 인식됨.
+> getter가 내부에서 Proxy객체의 .value를 다시 평가하게되고, 이 과정에서 proxy set트랩에 걸려서 setter가 또 호출되는 형식
+
+---
+
+## 해결 방법
+
+Vue 팀은 `MutableReactiveHandler` 내부에서 `Reflect.set()` 호출 시
+다음처럼 **receiver의 정확한 컨텍스트**를 보장하도록 수정했다:
+
+```ts
+const result = Reflect.set(target, key, value, isRef(target) ? target : receiver);
+```
+
+즉, `target`이 `ref`라면 → `receiver`로 `target` 자체를 넘겨서
+ref 내부의 setter에서 `this === ref`가 되도록 보장해준다.
+
+---
+
+## 핵심 요약
+
+| 항목 | 설명 |
+| --------- | ------------------------------------------------------------------------- |
+| 문제 버전 | Vue 3.5 RC 이전 |
+| 증상 | `ref`를 `reactive`로 감쌌을 때 값 변경 시 무한 루프 |
+| 원인 | Proxy의 `set` 내부에서 ref의 `this` 컨텍스트가 깨짐 |
+| 해결 | `Reflect.set()`에서 `receiver`를 `isRef(target)`인 경우 `target`으로 지정 |
+| 상태 | Vue 3.5 RC1에서 패치 완료 |
+
+---
diff --git "a/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/hyun2/\353\246\264\353\246\254\354\246\210 \353\205\270\355\212\270 \353\266\204\354\204\235 \355\233\210\353\240\250/vue-ref.md" "b/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/hyun2/\353\246\264\353\246\254\354\246\210 \353\205\270\355\212\270 \353\266\204\354\204\235 \355\233\210\353\240\250/vue-ref.md"
new file mode 100644
index 0000000..b76dfa4
--- /dev/null
+++ "b/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/hyun2/\353\246\264\353\246\254\354\246\210 \353\205\270\355\212\270 \353\266\204\354\204\235 \355\233\210\353\240\250/vue-ref.md"
@@ -0,0 +1,597 @@
+# Vue Ref 구현 상세 분석
+
+## 개요
+
+Vue의 `ref`는 반응성 시스템의 핵심 기능 중 하나다.
+이 글에서는 `ref`의 내부 구현과 동작 원리를 자세히 살펴본다.
+
+## 1. Ref 생성 과정
+
+```typescript
+// 1. ref 호출
+export function ref(value: T): Ref {
+ return createRef(value, false);
+}
+
+// 2. createRef 실행
+function createRef(rawValue: T, shallow: boolean): Ref {
+ if (isRef(rawValue)) {
+ return rawValue;
+ }
+ return new RefImpl(rawValue, shallow);
+}
+```
+
+여기서 중요한 점은:
+
+- `ref()` 호출 시 `createRef()`로 전달
+- 이미 ref인 경우 그대로 반환 (중복 래핑 방지)
+- 아닌 경우 `RefImpl` 인스턴스 생성
+
+### 예시
+
+```typescript
+const count = ref(1); // RefImpl 인스턴스 생성
+const count2 = ref(count); // 이미 ref이므로 그대로 반환
+```
+
+## 2. RefImpl 클래스
+
+```typescript
+class RefImpl {
+ _value: T;
+ private _rawValue: T;
+ dep: Dep = new Dep();
+ public readonly [ReactiveFlags.IS_REF] = true;
+ public readonly [ReactiveFlags.IS_SHALLOW]: boolean = false;
+
+ constructor(value: T, isShallow: boolean) {
+ this._rawValue = isShallow ? value : toRaw(value);
+ this._value = isShallow ? value : toReactive(value);
+ this[ReactiveFlags.IS_SHALLOW] = isShallow;
+ }
+
+ get value() {
+ if (__DEV__) {
+ this.dep.track({
+ target: this,
+ type: TrackOpTypes.GET,
+ key: 'value',
+ });
+ } else {
+ this.dep.track();
+ }
+ return this._value;
+ }
+
+ set value(newValue) {
+ const oldValue = this._rawValue;
+ const useDirectValue = this[ReactiveFlags.IS_SHALLOW] || isShallow(newValue) || isReadonly(newValue);
+ newValue = useDirectValue ? newValue : toRaw(newValue);
+ if (hasChanged(newValue, oldValue)) {
+ this._rawValue = newValue;
+ this._value = useDirectValue ? newValue : toReactive(newValue);
+ if (__DEV__) {
+ this.dep.trigger({
+ target: this,
+ type: TriggerOpTypes.SET,
+ key: 'value',
+ newValue,
+ oldValue,
+ });
+ } else {
+ this.dep.trigger();
+ }
+ }
+ }
+}
+```
+
+### Getter/Setter 동작
+
+1. **Getter**
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ effect(() => {
+ console.log(count.value); // getter 호출
+ });
+ ```
+
+ - `value` 접근 시 `dep.track()` 호출
+ - 개발 환경에서는 상세 정보 포함 (디버깅 용이)
+ - 프로덕션 환경에서는 단순화된 추적 (성능 최적화)
+
+2. **Setter**
+
+ ```typescript
+ // 예시
+ count.value = 2; // setter 호출
+ ```
+
+ - 값 변경 시 `hasChanged`로 변경 여부 확인
+ - 변경된 경우 `_rawValue`와 `_value` 업데이트
+ - `dep.trigger()`로 의존성 실행
+
+## 3. Dep 클래스
+
+```typescript
+export class Dep {
+ version = 0;
+ activeLink?: Link = undefined;
+ subs?: Link = undefined;
+ subsHead?: Link;
+ map?: KeyToDepMap = undefined;
+ key?: unknown = undefined;
+ sc: number = 0;
+
+ constructor(public computed?: ComputedRefImpl | undefined) {
+ if (__DEV__) {
+ this.subsHead = undefined;
+ }
+ }
+
+ track(debugInfo?: DebuggerEventExtraInfo): Link | undefined {
+ if (!activeSub || !shouldTrack || activeSub === this.computed) {
+ return;
+ }
+
+ let link = this.activeLink;
+ if (link === undefined || link.sub !== activeSub) {
+ link = this.activeLink = new Link(activeSub, this);
+
+ // 이중 연결 리스트로 의존성 관리
+ if (!activeSub.deps) {
+ activeSub.deps = activeSub.depsTail = link;
+ } else {
+ link.prevDep = activeSub.depsTail;
+ activeSub.depsTail!.nextDep = link;
+ activeSub.depsTail = link;
+ }
+
+ addSub(link);
+ } else if (link.version === -1) {
+ // 이전 실행에서 재사용 - 버전만 동기화
+ link.version = this.version;
+
+ // tail로 이동 처리
+ if (link.nextDep) {
+ const next = link.nextDep;
+ next.prevDep = link.prevDep;
+ if (link.prevDep) {
+ link.prevDep.nextDep = next;
+ }
+
+ link.prevDep = activeSub.depsTail;
+ link.nextDep = undefined;
+ activeSub.depsTail!.nextDep = link;
+ activeSub.depsTail = link;
+
+ // head였다면 새로운 head 지정
+ if (activeSub.deps === link) {
+ activeSub.deps = next;
+ }
+ }
+ }
+
+ if (__DEV__ && activeSub.onTrack) {
+ activeSub.onTrack(
+ extend(
+ {
+ effect: activeSub,
+ },
+ debugInfo
+ )
+ );
+ }
+
+ return link;
+ }
+
+ trigger(debugInfo?: DebuggerEventExtraInfo): void {
+ this.version++;
+ globalVersion++;
+ this.notify(debugInfo);
+ }
+
+ notify(debugInfo?: DebuggerEventExtraInfo): void {
+ startBatch();
+ try {
+ if (__DEV__) {
+ // 개발 환경에서 onTrigger 훅 실행
+ for (let head = this.subsHead; head; head = head.nextSub) {
+ if (head.sub.onTrigger && !(head.sub.flags & EffectFlags.NOTIFIED)) {
+ head.sub.onTrigger(
+ extend(
+ {
+ effect: head.sub,
+ },
+ debugInfo
+ )
+ );
+ }
+ }
+ }
+ // 실제 의존성 실행 (역순)
+ for (let link = this.subs; link; link = link.prevSub) {
+ if (link.sub.notify()) {
+ (link.sub as ComputedRefImpl).dep.notify();
+ }
+ }
+ } finally {
+ endBatch();
+ }
+ }
+}
+```
+
+### Dep 클래스의 핵심 역할
+
+1. **의존성 추적 (track)**
+
+ ```typescript
+ // Dep 클래스의 track 메서드
+ track(debugInfo?: DebuggerEventExtraInfo): Link | undefined {
+ // 1. 현재 실행 중인 effect 확인
+ if (!activeSub || !shouldTrack || activeSub === this.computed) {
+ return;
+ }
+
+ // 2. 새로운 링크 생성 또는 재사용
+ let link = this.activeLink;
+ if (link === undefined || link.sub !== activeSub) {
+ link = this.activeLink = new Link(activeSub, this);
+
+ // 3. 이중 연결 리스트로 의존성 관리
+ if (!activeSub.deps) {
+ activeSub.deps = activeSub.depsTail = link;
+ } else {
+ link.prevDep = activeSub.depsTail;
+ activeSub.depsTail!.nextDep = link;
+ activeSub.depsTail = link;
+ }
+
+ // 4. 의존성 등록
+ addSub(link);
+ }
+ }
+ ```
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ const doubled = computed(() => count.value * 2);
+ const quadrupled = computed(() => doubled.value * 2);
+
+ // 의존성 추적 과정
+ // 1. count.value 접근 시
+ effect(() => {
+ console.log(count.value); // track 호출
+ // activeSub = 현재 effect
+ // link = 새로운 Link(현재 effect, count의 dep)
+ // activeSub.deps = link
+ });
+
+ // 2. doubled.value 접근 시
+ effect(() => {
+ console.log(doubled.value); // track 호출
+ // activeSub = 현재 effect
+ // link = 새로운 Link(현재 effect, doubled의 dep)
+ // activeSub.deps = link
+ });
+ ```
+
+2. **의존성 실행 (trigger/notify)**
+
+ ```typescript
+ // Dep 클래스의 trigger 메서드
+ trigger(debugInfo?: DebuggerEventExtraInfo): void {
+ // 1. 버전 증가
+ this.version++;
+ globalVersion++;
+ // 2. 의존성 실행
+ this.notify(debugInfo);
+ }
+
+ // Dep 클래스의 notify 메서드
+ notify(debugInfo?: DebuggerEventExtraInfo): void {
+ startBatch();
+ try {
+ // 1. 개발 환경에서 onTrigger 훅 실행
+ if (__DEV__) {
+ for (let head = this.subsHead; head; head = head.nextSub) {
+ if (head.sub.onTrigger && !(head.sub.flags & EffectFlags.NOTIFIED)) {
+ head.sub.onTrigger(
+ extend(
+ {
+ effect: head.sub,
+ },
+ debugInfo
+ )
+ );
+ }
+ }
+ }
+ // 2. 실제 의존성 실행 (역순)
+ for (let link = this.subs; link; link = link.prevSub) {
+ if (link.sub.notify()) {
+ (link.sub as ComputedRefImpl).dep.notify();
+ }
+ }
+ } finally {
+ endBatch();
+ }
+ }
+ ```
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ const doubled = computed(() => count.value * 2);
+ const quadrupled = computed(() => doubled.value * 2);
+
+ // 의존성 실행 과정
+ count.value = 2; // trigger 호출
+
+ // 1. count의 dep.trigger() 호출
+ // - version 증가
+ // - notify 호출
+
+ // 2. notify 메서드에서
+ // - startBatch() 호출
+ // - computed 값 처리 (doubled, quadrupled)
+ // - effect 처리
+ // - endBatch() 호출
+ ```
+
+### 의존성 추적과 실행의 전체 흐름
+
+1. **의존성 추적 (track)**
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ effect(() => {
+ console.log(count.value); // 1. getter 호출
+ });
+
+ // track 메서드에서
+ if (!activeSub || !shouldTrack || activeSub === this.computed) {
+ return; // 2. 현재 실행 중인 effect 확인
+ }
+
+ let link = this.activeLink;
+ if (link === undefined || link.sub !== activeSub) {
+ link = this.activeLink = new Link(activeSub, this); // 3. 새로운 링크 생성
+
+ if (!activeSub.deps) {
+ activeSub.deps = activeSub.depsTail = link; // 4. 첫 번째 의존성
+ } else {
+ link.prevDep = activeSub.depsTail; // 5. 기존 의존성에 추가
+ activeSub.depsTail!.nextDep = link;
+ activeSub.depsTail = link;
+ }
+
+ addSub(link); // 6. 의존성 등록
+ }
+ ```
+
+2. **의존성 실행 (trigger/notify)**
+
+ ```typescript
+ // 예시
+ count.value = 2; // 1. setter 호출
+
+ // trigger 메서드에서
+ this.version++; // 2. 버전 증가
+ globalVersion++;
+ this.notify(debugInfo); // 3. 의존성 실행
+
+ // notify 메서드에서
+ startBatch(); // 4. 배치 시작
+ try {
+ // 5. 개발 환경에서 onTrigger 훅 실행
+ if (__DEV__) {
+ for (let head = this.subsHead; head; head = head.nextSub) {
+ // ... onTrigger 훅 실행
+ }
+ }
+
+ // 6. 실제 의존성 실행 (역순)
+ for (let link = this.subs; link; link = link.prevSub) {
+ if (link.sub.notify()) {
+ (link.sub as ComputedRefImpl).dep.notify();
+ }
+ }
+ } finally {
+ endBatch(); // 7. 배치 종료
+ }
+ ```
+
+이렇게 의존성 추적과 실행을 통해:
+
+1. 효율적인 의존성 관리
+2. 안정적인 업데이트 순서
+3. 불필요한 재실행 방지
+4. 메모리 최적화
+ 를 달성할 수 있다.
+
+### 의존성 등록 (addSub)
+
+```typescript
+// Dep 클래스의 addSub 메서드
+function addSub(link: Link): void {
+ // 1. Dep의 subs 리스트에 추가
+ if (!link.dep.subs) {
+ link.dep.subs = link;
+ } else {
+ link.prevSub = link.dep.subs;
+ link.dep.subs = link;
+ }
+
+ // 2. 개발 환경에서 subsHead 관리
+ if (__DEV__) {
+ if (!link.dep.subsHead) {
+ link.dep.subsHead = link;
+ } else {
+ link.nextSub = link.dep.subsHead;
+ link.dep.subsHead = link;
+ }
+ }
+}
+```
+
+이 코드에서 중요한 점은:
+
+1. **Dep의 subs 리스트 관리**
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ effect(() => {
+ console.log(count.value); // 첫 번째 의존성
+ });
+
+ // addSub 호출 시
+ if (!link.dep.subs) {
+ link.dep.subs = link; // 첫 번째 의존성
+ } else {
+ link.prevSub = link.dep.subs; // 기존 의존성 앞에 추가
+ link.dep.subs = link;
+ }
+ ```
+
+ - 첫 번째 의존성은 `subs`에 직접 할당
+ - 이후 의존성은 `prevSub`로 연결하여 리스트 구성
+ - `notify` 메서드에서 `prevSub`로 역순 실행 가능
+
+2. **의존성 실행 순서**
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ const doubled = computed(() => count.value * 2);
+ effect(() => {
+ console.log(doubled.value);
+ });
+
+ // 의존성 등록 순서
+ count -> doubled -> effect
+
+ // notify 메서드에서
+ for (let link = this.subs; link; link = link.prevSub) {
+ // effect -> doubled -> count 순서로 실행
+ }
+ ```
+
+ - `addSub`으로 의존성 등록 시 순서 유지
+ - `notify` 메서드에서 역순으로 실행하여 최신 값 사용
+
+이렇게 `addSub`을 통해:
+
+1. 의존성의 효율적인 관리
+2. 개발 환경에서의 디버깅 지원
+3. 안정적인 실행 순서 보장
+ 을 달성할 수 있다.
+
+## 4. Effect와 배치 시스템
+
+```typescript
+export function startBatch(): void {
+ batchDepth++;
+}
+
+export function endBatch(): void {
+ if (--batchDepth > 0) return;
+
+ // computed 값 처리
+ if (batchedComputed) {
+ let e: Subscriber | undefined = batchedComputed;
+ batchedComputed = undefined;
+ while (e) {
+ e = e.next;
+ }
+ }
+
+ // 일반 effect 처리
+ while (batchedSub) {
+ let e: Subscriber | undefined = batchedSub;
+ batchedSub = undefined;
+ while (e) {
+ if (e.flags & EffectFlags.ACTIVE) {
+ (e as ReactiveEffect).trigger();
+ }
+ e = e.next;
+ }
+ }
+}
+```
+
+### 배치 시스템의 역할
+
+1. **중첩 업데이트 처리**
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ effect(() => {
+ count.value = 2; // 첫 번째 업데이트
+ count.value = 3; // 두 번째 업데이트
+ });
+ // 한 번의 배치로 처리
+ ```
+
+ - 여러 업데이트를 하나의 배치로 묶음
+ - 중첩된 업데이트를 올바르게 처리
+
+2. **순서 보장**
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ const doubled = computed(() => count.value * 2);
+ effect(() => {
+ console.log(doubled.value);
+ });
+ count.value = 2;
+ // 1. computed 값 처리
+ // 2. effect 처리
+ ```
+
+ - computed 값 먼저 처리
+ - 일반 effect 나중 처리
+ - 역순으로 실행하여 의존성 순서 보장
+
+3. **에러 처리**
+
+ ```typescript
+ // 예시
+ const count = ref(1);
+ effect(() => {
+ try {
+ count.value = 2;
+ } catch (err) {
+ console.error(err);
+ }
+ });
+ ```
+
+ - try-catch로 안전한 실행
+ - 에러 발생 시 적절한 처리
+
+## 🧠 핵심 요약
+
+| 구분 | 설명 | 목적 |
+| ------------- | -------------- | ----------------- |
+| Ref | 반응성 값 관리 | 값의 반응성 처리 |
+| Dep | 의존성 관리 | 의존성 추적/실행 |
+| Track/Trigger | 변경 감지 | 의존성 등록/실행 |
+| 배치 | 업데이트 관리 | 효율적인 업데이트 |
+
+이런 구조를 통해 Vue는:
+
+1. 효율적인 반응성 처리
+2. 안정적인 상태 관리
+3. 예측 가능한 동작
+ 을 달성하고 있다.
diff --git "a/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/\352\266\214\355\230\204\354\247\200/readme.md" "b/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/\352\266\214\355\230\204\354\247\200/readme.md"
new file mode 100644
index 0000000..19dff00
--- /dev/null
+++ "b/1. \353\271\214\353\223\234 \354\213\234\354\212\244\355\205\234/\352\266\214\355\230\204\354\247\200/readme.md"
@@ -0,0 +1,115 @@
+라이브러리가 제공할 수 있는 세 가지 주요 자바스크립트 파일 유형 (ES 모듈, “클래식” 전역 변수 유형, CommonJS)
+- [제가 최근에 쓴 블로그 글이에요 .](https://velog.io/@khjbest/%EC%8B%9C%EB%82%98%EB%B8%8C%EB%A1%9C-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-3%EC%A3%BC%EC%B0%A8-%EA%B0%80%EC%83%81-%EB%8F%94%EA%B3%BC-%EC%9B%B9-%EC%84%9C%EB%B2%84-%EA%B8%B0%EC%B4%88Express-%EC%84%9C%EB%B2%84%EB%A6%AC%EC%8A%A4#-commonjs%EC%99%80-es-modules%EC%9D%98-%EC%B0%A8%EC%9D%B4)
+
+```json
+// 패키지를 CommonJS 방식(예: Node.js의 require())으로 불러올 때 기본으로 사용하는 파일
+ "main": "./dist/mini-query.umd.cjs",
+// ES 모듈(ESM)을 지원하는 환경에서 import 문으로 불러올 때 사용할 파일을 지정
+ "module": "./dist/mini-query.js",
+// 엔트리 포인트를 보다 명시적으로 제어
+ "exports": {
+ ".": {
+// ES 모듈(import)로 불러올 경우: "./dist/mini-query.js" 파일을 사용
+ "import": "./dist/mini-query.js",
+// CommonJS(require)로 불러올 경우: "./dist/mini-query.umd.cjs" 파일을 사용
+ "require": "./dist/mini-query.umd.cjs"
+ }
+```
+
+> Q . 그러면 exports를 선언했을 때, main이나 module옵션은 뺴도 되지않아 ?
+>
+> A . 일부 구 버전 Node.js나 exports를 지원하지 않는 도구에서는 여전히 main이나 module 필드를 참고할 수 있으므로, 호환성을 고려한다면 함께 선언해주는 것이 좋다.
+
+---
+Import Maps는 웹 브라우저에서 ES 모듈을 로드할 때, 모듈 이름과 URL 간의 매핑을 명시적으로 지정할 수 있는 기능입니다.
+이를 통해 코드 내에서 사용하는 모듈의 "별칭"을 실제 파일 경로나 CDN 주소로 연결할 수 있습니다.
+
+예를 들어, 다음과 같이 HTML 파일에 `
+```
+
+위와 같이 설정하면, JavaScript 코드에서
+
+```javascript
+import _ from 'lodash';
+```
+
+라고 작성했을 때 브라우저는 `'lodash'`라는 모듈명을 설정된 URL(`https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js`)로 해석하여 해당 파일을 로드합니다.
+
+---
+
+#### “클래식” JS 파일
+> 아에 그냥 파일이 프로젝트에 포함되어있구나@@근데이제 umd.js확장자
+>
+> "클래식"파일? 별도의 빌드 도구나 모듈 시스템 없이, 브라우저가 기본적으로 이해하는 전통적인 방식의 자바스크립트 파일과 동일. UMD 형식은 이러한 클래식 파일처럼 바로 사용할 수 있으면서도, 현대의 모듈 시스템과도 호환되도록 함.
+>
+> 빌드 시스템 없이도 자바스크립트 라이브러리를 로드하려면, 라이브러리가 전역 변수로 정의되어야 하는데, UMD 파일은 이 점을 보장하면서도, 모듈 시스템을 사용하는 환경에서는 해당 시스템에 맞춰 올바르게 동작할 수 있게 설계되어 있음.
+
+✔️ 사용 방법:
+```html
+
+```
+
+✔️ 식별 방법
+- 웹사이트에 “CDN으로 사용하세요!”와 같은 큰 친절한 배너가 있는 경우
+- .umd.js 확장자
+- `
+ ```
+ 이렇게 하면, 코드에서는 "my-module"이라는 별칭만 사용해도, 브라우저가 import map을 참고하여 실제 모듈의 위치(예를 들어 외부 라이브러리나 의존성이 있는 모듈)를 찾아서 로드합니다.
+
+esbuild나 다른 ES 모듈 번들러 사용
+package.json의 "type": "module" (정확히 어떤 파일을 가리키는지는 명확하지 않음)
+
+>요놈이 이제 표준화
+
+#### CommonJS 모듈
+✔️식별 방법:
+- 코드에서 require()나 module.exports = ... 찾기
+- .cjs 확장자
+- package.json의 "type": "commonjs"