Skip to content

Latest commit

 

History

History
322 lines (254 loc) · 9.87 KB

File metadata and controls

322 lines (254 loc) · 9.87 KB

Minimal Global State Manager

React용 최소 기능 전역 상태 관리 라이브러리

1. 지원자 정보

1.1. 지원자 이름

유효준

1.2. 지원 직무

Frontend 개발자

2. 과제 정보

2.1. 과제 코드

JF002 - Minimal Global State Managment Library 구현

2.2. 과제 수령일

2025.10.24 (금)

2.3. 소요 시간

약 6시간 (순수 작업 시간 기준, 휴식 및 개인 사유 제외)

2.4. 수행 환경

개발 도구:

  • IDE: IntelliJ IDEA
  • AI Agent: Claude Code (Sonnet 4.5), ChatGPT (GPT-4)
  • Package Manager: pnpm 10
  • Node.js: v22.15.1

참조 문서:

2.5. 결과 요약

구현 완료

핵심 기능:

  • Atom 생성 및 관리 (createAtom, get, set)
  • 구독 시스템 (subscribe/unsubscribe)
  • React 통합 (useAtom with useSyncExternalStore)
  • 값 비교 (Object.is 사용)
  • 메모리 관리 (GC-friendly cleanup - listeners null 처리)
  • 자동 배치 업데이트 (React 18 자동 배칭 활용)

선택 기능:

  • 파생 Atom (createDerivedAtom, getDerived)
  • 비동기 Atom (createAsyncAtom, getAsync, useAsyncAtomValue)
  • 배치 업데이트 (React 18 자동 배칭 활용)
  • 메모리 최적화 (listeners null 처리)
  • Frameworkless 사용 (예 - vue.js ) 에서도 get, set, subscribe만으로 상태 관리 가능

3. 과제 산출물 정보

3.1. 디렉토리/파일 구조

minimal-global-state/
├── packages/
│   ├── lib/                      # 핵심 라이브러리
│   │   ├── src/
│   │   │   ├── core/            # 핵심 로직
│   │   │   │   ├── atom.ts
│   │   │   │   ├── atom.test.ts
│   │   │   │   ├── subscribe.ts
│   │   │   │   ├── subscribe.test.ts
│   │   │   │   ├── derived.ts
│   │   │   │   ├── derived.test.ts
│   │   │   │   ├── async.ts
│   │   │   │   └── async.test.ts
│   │   │   ├── react/           # React 통합
│   │   │   │   ├── useAtom.ts
│   │   │   │   ├── useAtom.test.tsx
│   │   │   │   └── useAsyncAtomValue.ts
│   │   │   ├── vue/             # Vue 통합
│   │   │   │   ├── useAtom.ts
│   │   │   │   ├── useAtom.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── types/           # 타입 정의
│   │   │   │   └── index.ts
│   │   │   ├── index.ts         # 공개 API
│   │   │   └── test-setup.ts    # 테스트 설정
│   │   ├── dist/                # 빌드 결과물
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   ├── vite.config.ts
│   │   └── vitest.config.ts
│   ├── react/                    # React 데모 앱
│   │   ├── src/
│   │   │   ├── examples/        # 예제 컴포넌트
│   │   │   │   ├── basic/       # 기본 사용 예제
│   │   │   │   │   ├── display-1.tsx
│   │   │   │   │   ├── display-2.tsx
│   │   │   │   │   ├── display-3.tsx
│   │   │   │   │   ├── display-4.tsx
│   │   │   │   │   └── editor.tsx
│   │   │   │   ├── async/       # 비동기 Atom 예제
│   │   │   │   │   └── async-data.tsx
│   │   │   │   ├── create-derived/ # 파생 Atom 예제
│   │   │   │   │   └── derived-state.tsx
│   │   │   │   ├── batch/ # 배치 업데이트 예제
│   │   │   │   │   └── batch-update.tsx
│   │   │   │   ├── multi-component.tsx # 멀티 컴포넌트 예제 (기본 예제)
│   │   │   │   └── shared.ts           # 공유 Atom 정의
│   │   │   ├── app.tsx
│   │   │   ├── index.tsx
│   │   │   └── vite-env.d.ts
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   └── vue/                      # Vue 데모 앱
│       ├── src/
│       │   ├── components/      # Vue 컴포넌트
│       │   │   ├── counter-display.vue
│       │   │   ├── counter-buttons.vue
│       │   │   └── counter-reset.vue
│       │   ├── store/           # 전역 상태
│       │   │   └── atoms.ts
│       │   ├── app.vue
│       │   ├── main.ts
│       │   └── vite-env.d.ts
│       ├── index.html
│       ├── package.json
│       ├── tsconfig.json
│       └── vite.config.ts
├── docs/
│   └── DESIGN.md                 # 설계 문서
├── detail-plan.md                # 상세 구현 계획
├── advanced-detail-plan.md       # 고급 기능 구현 계획
├── .claude/                      # Claude Code 설정
├── .eslintrc.json               # ESLint 설정
├── .prettierrc                  # Prettier 설정
├── package.json                 # 워크스페이스 설정
├── pnpm-workspace.yaml          # Monorepo 설정
├── tsconfig.json                # 공통 TypeScript 설정
└── README.md                    # 본 문서

3.2. 빌드 및 실행 방법

# 설치 및 빌드
pnpm install
pnpm build

# React 데모 실행
pnpm dev:react

# Vue 데모 실행
pnpm dev:vue

# 테스트
pnpm test

3.3. 기타 의존성

3.3.1. 핵심 라이브러리 (packages/lib)

런타임 의존성:

  • React 18.0.0+ (peer dependency): React 프레임워크 지원

개발 의존성:

  • TypeScript 5.3.3: 정적 타입 검사
  • Vite 5.0.12: 빌드 도구 - 빠른 빌드 속도와 ESM 지원
  • vite-plugin-dts 4.5.4: TypeScript 선언 파일 자동 생성
  • Vitest 1.2.2: 테스트 프레임워크 - Vite 기반의 빠른 테스트 실행
  • @testing-library/react 14.1.2: React 컴포넌트 테스트 - 사용자 중심 테스트 작성
  • @vitest/coverage-v8 1.2.2: 코드 커버리지 측정
  • jsdom 24.0.0: DOM 환경 시뮬레이션 - 브라우저 없이 테스트 실행

3.3.2. React 데모 앱 (packages/react)

런타임 의존성:

  • @minimal-state/lib: workspace 내부 라이브러리
  • React 18.2.0: UI 라이브러리
  • React-DOM 18.2.0: React DOM 렌더러

개발 의존성:

  • Vite 5.0.12: 개발 서버 및 빌드 도구
  • @vitejs/plugin-react 4.2.1: React 플러그인 - Fast Refresh 지원

3.3.3. Workspace 공통

코드 품질 도구:

  • ESLint 8.57.0: 코드 린팅 - 코드 품질 검사
  • @typescript-eslint/eslint-plugin 6.21.0: TypeScript ESLint 플러그인
  • @typescript-eslint/parser 6.21.0: TypeScript 파서
  • eslint-plugin-react 7.33.2: React ESLint 규칙
  • eslint-plugin-react-hooks 4.6.0: React Hooks 규칙
  • Prettier 3.2.4: 코드 포맷팅 - 일관된 코드 스타일

4. 기타 과제 피드백

4.1. 과제 난이도

  • 난이도: 적절함
  • 소요 시간: 적절함
  • 평가: 상태 관리 라이브러리의 내부 구현 원리를 생각 해볼 수 있는 좋은 학습 기회였다고 생각합니다

4.2. 제출은 하지 않았지만

시간이 충분했다면 다음 기능들을 추가로 구현해볼 수 있었을 것 같습니다:

  1. Atom Family

    • 동적으로 여러 atom을 생성하고 관리하는 패턴
    • 예: atomFamily((id) => createAtom(...))
  2. Atom with Storage

    • localStorage/sessionStorage와 자동 동기화
    • 페이지 새로고침 시 상태 복원
  3. DevTools

    • 브라우저 확장 프로그램으로 atom 상태 시각화
    • Time-travel debugging 지원

API 사용 예제

기본 사용

import { createAtom, useAtom } from '@minimal-state/lib';

// 1. Atom 생성
const countAtom = createAtom(0);

// 2. React 컴포넌트에서 사용
function Counter() {
  const [count, setCount] = useAtom(countAtom);

  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}

프레임워크 독립적 사용

import { createAtom, get, set, subscribe } from '@minimal-state/lib';

const atom = createAtom(0);

// 값 읽기
console.log(get(atom)); // 0

// 값 쓰기
set(atom, 1);

// 구독
const unsubscribe = subscribe(atom, (value) => {
  console.log('Value changed:', value);
});

// 구독 해제
unsubscribe();

파생 Atom

import { createAtom, createDerivedAtom, useAtom } from '@minimal-state/lib';

const firstNameAtom = createAtom('John');
const lastNameAtom = createAtom('Doe');

// 파생 atom 생성
const fullNameAtom = createDerivedAtom((get) => {
  return `${get(firstNameAtom)} ${get(lastNameAtom)}`;
});

function FullName() {
  const [fullName] = useAtom(fullNameAtom);
  return <p>{fullName}</p>; // "John Doe"
}

비동기 Atom

import { createAsyncAtom, useAsyncAtomValue } from '@minimal-state/lib';
import { Suspense } from 'react';

// 비동기 atom 생성
const userAtom = createAsyncAtom(async () => {
  const response = await fetch('/api/user');
  return response.json();
});

function UserProfile() {
  const user = useAsyncAtomValue(userAtom);
  return <div>Name: {user.name}</div>;
}

// Suspense로 감싸서 사용
function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <UserProfile />
    </Suspense>
  );
}

문서

라이선스

MIT