[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
+203 -104
View File
@@ -2,129 +2,228 @@
id: wiki-2026-0508-pinia
title: Pinia
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: [P-REINFORCE-AUTO-EE6B38]
aliases: [Vue Store, Pinia Store]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
tags: [auto-reinforced]
confidence_score: 0.9
verification_status: applied
tags: [vue, state-management, frontend]
raw_sources: []
last_reinforced: 2026-05-03
github_commit: "[P-Reinforce] Continuous Worker - Pinia"
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: unspecified
framework: unspecified
language: TypeScript
framework: Vue 3 / Pinia 2
---
# [[Pinia|Pinia]]
# Pinia
## 📌 한 줄 통찰 (The Karpathy Summary)
Pinia는 대규모 Vue.js 애플리케이션을 위한 공식 상태 관리 라이브러리로, 이전의 공식 도구였던 Vuex를 대체하여 새로운 표준으로 자리 잡았습니다 [1-3]. Vue 2와 Vue 3 모두와 호환되며 Vue 코어 팀에 의해 유지보수됩니다 [1]. 불필요한 보일러플레이트를 제거하고 Composition API 스타일의 단순한 API를 제공하며, 특히 TypeScript와 함께 사용할 때 강력한 타입 추론을 지원하는 것이 특징입니다 [3, 4].
## 한 줄
> **"매 Vue 3 매 official state management — 매 Vuex 4 후속, 매 Composition API native + 매 TypeScript-first"**. Eduardo San Martin Morote 매 2019 발표 매 Vue Core 팀 채택, 매 store 매 composable function 매 표현 매 boilerplate 90% 감소, 매 2026 매 Vue 표준 store library.
## 📖 구조화된 지식 (Synthesized Content)
* **대규모 애플리케이션을 위한 표준 상태 관리**: 기존에 널리 사용되던 Vuex는 이제 유지보수 모드로 전환되었으며, 새로운 애플리케이션에서는 Pinia의 사용이 적극 권장됩니다 [2]. Pinia는 Vuex 5에 대한 코어 팀의 논의에서 출발하였으며, 기능적 상태와 컴포지션 로직을 분리하는 데 탁월한 선택으로 평가받고 있습니다 [2, 5].
* **단순화된 API 및 TypeScript 지원**: Vuex와 비교할 때 Pinia는 의식이 적고 더 단순한 API를 제공합니다 [4]. Composition API 스타일로 스토어를 정의할 수 있게 해주며, TypeScript 환경에서 견고한 타입 추론 지원을 제공하여 엔터프라이즈급 대규모 프로젝트에 매우 적합합니다 [3, 4].
* **비즈니스 로직 분리 패턴**: 실전 아키텍처 패턴에서 Pinia는 단순히 전역 상태를 보관하는 것을 넘어, 액션(Action) 내부에 비동기 로직을 포함하여 처리합니다 [3]. 이를 통해 뷰 컴포넌트는 복잡한 로직을 배제하고 UI 렌더링에만 책임을 한정할 수 있게 되어, 클린 아키텍처와 관심사 분리를 촉진합니다 [3].
* **통합 및 개발자 경험(DX)**: 대규모 프로덕션 애플리케이션에 필수적인 기능들을 완벽히 지원합니다. 강력한 팀 협업 규칙을 제공하며, 타임라인, 컴포넌트 내 검사, 타임트래블 디버깅 등을 포함한 Vue DevTools와의 통합, 그리고 Hot Module Replacement(HMR)를 지원합니다 [1].
## 매 핵심
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
**서버 사이드 렌더링(SSR) 환경에서의 상태 유출 위험**
서버 사이드 렌더링(SSR) 애플리케이션을 구축할 때 전역 상태 관리는 각별한 주의가 필요합니다. 스토어가 단순한 싱글톤(Singleton) 패턴으로 정의될 경우, 서버에서 처리되는 여러 클라이언트의 요청 간에 상태가 공유되어 데이터가 유출(Data Leakage)되는 치명적인 문제가 발생할 수 있습니다 [1, 3].
이를 방지하기 위해 Pinia는 각 요청마다 새로운 스토어 인스턴스를 생성하는 구조적 해결책을 제공하고 있습니다 [3]. 하지만 개발자는 SSR을 도입할 때 Pinia의 이러한 아키텍처 요구사항을 명확히 이해하고 적절히 구성해야 하는 제약 사항과 구현 복잡도(Trade-off)를 감수해야 합니다. 그 외의 성능 저하나 추가적인 부작용에 대한 정보는 소스에 관련 정보가 부족합니다.
### 매 vs Vuex
- **No mutations**: 매 actions 가 directly state 수정 — 매 mutation indirection 제거.
- **Flat stores**: 매 nested module 매 X — 매 cross-store import 매 graph 형성.
- **Type inference**: 매 zero manual typing — 매 store usage 매 fully typed.
- **Devtools**: 매 timeline + state inspect + time-travel 지원.
## 🔗 지식 연결 (Graph)
### Related Concepts
### 매 store kinds
- **Options Store**: `state`, `getters`, `actions` — 매 Vuex-like familiar shape.
- **Setup Store**: `ref`/`computed`/`function` — 매 Composition API native.
#### [상태 관리 및 프레임워크 기반 기술]
- [[Vuex]]
- 연결 이유: Pinia의 이전 세대 공식 상태 관리 라이브러리입니다.
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 프론트엔드 상태 관리 패턴이 보일러플레이트 축소와 타입스크립트 친화적으로 진화하게 된 배경과 Pinia의 탄생 목적을 이해할 수 있습니다 [2, 4].
- [[Composition API]]
- 연결 이유: Vue 3의 핵심 API이자, Pinia가 스토어를 정의할 때 채택한 API 스타일입니다.
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 상태와 로직이 어떻게 기능별로 논리적으로 결합하고 재사용되는지(Composables)에 대한 Vue 3의 핵심 아키텍처 패턴을 이해할 수 있습니다 [3, 4].
### 매 응용
1. SPA global state (auth, user prefs).
2. Server-side rendering (Nuxt 3 매 native integration).
3. Cross-component caching (API result, derived state).
4. Plugin extension (persistedstate, undo/redo).
#### [렌더링 환경 및 언어 기술]
- [[Server-Side Rendering (SSR)]]
- 연결 이유: 대규모 웹 애플리케이션에서 SEO 및 초기 로딩 최적화를 위해 사용되며, Pinia 사용 시 상태 공유 문제를 방지해야 하는 환경입니다.
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 싱글톤 패턴의 한계와, 요청당 새로운 인스턴스를 생성하는 Pinia의 보안/격리 메커니즘 설계 원리를 이해할 수 있습니다 [1, 3].
- [[TypeScript]]
- 연결 이유: Pinia가 제공하는 가장 큰 장점 중 하나인 '견고한 타입 추론'의 기반이 되는 언어입니다.
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 엔터프라이즈 규모의 앱에서 상태 관리의 런타임 에러를 방지하고 타입 안전성을 확보하는 방법을 이해할 수 있습니다 [3, 4].
## 💻 패턴
### Deeper Research Questions
- Pinia의 Composition-API 스타일 스토어 정의 방식이 기존 Vuex의 Options API 방식(Mutations와 Actions의 구분 등) 대비 코드 구조의 복잡성을 구체적으로 어떻게 해결하는가?
- 서버 사이드 렌더링(SSR) 환경에서 상태 유출을 막기 위해 Pinia가 각 요청마다 새로운 스토어 인스턴스를 생성하고 관리하는 내부 생명주기(Lifecycle) 메커니즘은 무엇인가?
- 컴포넌트의 책임을 UI 렌더링으로만 한정하고 비즈니스 및 비동기 로직을 모두 Pinia의 Action으로 위임할 때 발생하는 컴포넌트 간 결합도 변화와 설계상의 한계는 없는가?
- TypeScript 환경에서 Pinia의 강력한 타입 추론 기능이 대규모 Vue 3 모노레포(Monorepo) 프로젝트의 개발 생산성 및 리팩토링에 미치는 영향은 무엇인가?
- Pinia와 Vue DevTools의 통합(타임트래블 디버깅 등)이 복잡한 상태 전이를 추적하는 데 어떻게 기술적으로 기여하는가?
### Setup store (modern preferred)
```ts
// stores/counter.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
### Practical Application Contexts
- **Implementation:** Vue 3 컴포넌트 내부에 산재된 API 호출 및 비동기 비즈니스 로직을 Pinia의 액션(Action) 계층으로 추출하여, 프론트엔드 UI 컴포넌트를 순수하게 렌더링에만 집중하는 형태로 구현합니다. [3]
- **System Design:** 엔터프라이즈급 대규모 SPA 또는 SSR 애플리케이션 설계 시, 타입 안전성을 보장하고 보일러플레이트를 최소화하는 중앙 집중형 상태 관리 레이어로 설계에 포함합니다. [3, 4]
- **Operation / Maintenance:** Vue DevTools와의 네이티브 통합을 통해 애플리케이션 운영 중 발생하는 복잡한 상태 변화의 타임라인을 검사하고 타임트래블 디버깅을 수행하여 유지보수를 원활하게 합니다. [1]
- **Learning Path:** 최신 Vue 프레임워크 학습 시 Vuex를 건너뛰고, Composition API를 익힌 후 즉시 Pinia를 전역 상태 관리 표준으로 채택하여 학습하는 것이 권장됩니다. [2]
- **My Project Relevance:** 현대적인 Vue 프론트엔드 환경에서 상태 관리의 복잡도를 낮추고 타입스크립트 기반의 안정적인 아키텍처 패턴을 구축해야 할 때 도입하는 핵심 기술로 연관됩니다.
### Adjacent Topics
- [[Vite]]
- 확장 방향: Pinia와 함께 모던 Vue 애플리케이션 개발 워크플로우를 극도로 가속화하는 차세대 빌드 및 최적화 도구로 이해를 확장할 수 있습니다 [6].
- [[React Query (TanStack Query)]]
- 확장 방향: Vue 진영의 Pinia처럼 프론트엔드 아키텍처에서 '서버 상태(Server State)' 관리 책임을 컴포넌트로부터 분리해내는 React 생태계의 유사한 실전 패턴 도구로 비교 연구할 수 있습니다 [7].
---
*Last updated: 2026-05-03*
---
*Last updated: 2026-05-03*
- Raw Source: 00_Raw/2026-05-03/Pinia.md
---
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
**언제 이 지식을 쓰는가:**
- *(TODO)*
**언제 쓰면 안 되는가:**
- *(TODO)*
## 🧪 검증 상태 (Validation)
- **정보 상태:** needs_review
- **출처 신뢰도:** A
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
## 🧬 중복 검사 (Duplicate Check)
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
- **처리 방식:** UPDATE (자동 정규화)
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
## 🕓 변경 이력 (Changelog)
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|------|-----------|-----------|--------|
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
## 💻 코드 패턴 (Code Patterns)
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
```text
# TODO
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubled = computed(() => count.value * 2)
function increment() { count.value++ }
function reset() { count.value = 0 }
return { count, doubled, increment, reset }
})
```
## 🤔 의사결정 기준 (Decision Criteria)
### Options store
```ts
export const useUserStore = defineStore('user', {
state: () => ({
user: null as User | null,
loading: false,
}),
getters: {
isLoggedIn: (s) => s.user !== null,
displayName: (s) => s.user?.name ?? 'Guest',
},
actions: {
async login(creds: Credentials) {
this.loading = true
try {
this.user = await api.login(creds)
} finally {
this.loading = false
}
},
logout() { this.user = null },
},
})
```
**선택 A를 써야 할 때:**
- *(TODO)*
### Component usage
```vue
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'
**선택 B를 써야 할 때:**
- *(TODO)*
const store = useCounterStore()
// 매 reactivity 매 유지: storeToRefs 매 ref 변환
const { count, doubled } = storeToRefs(store)
// actions 매 destructure OK (not reactive)
const { increment } = store
</script>
**기본값:**
> *(TODO)*
<template>
<button @click="increment">{{ count }} (×2 = {{ doubled }})</button>
</template>
```
## ❌ 안티패턴 (Anti-Patterns)
### App setup (Vue 3)
```ts
// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
```
### Cross-store usage
```ts
import { useAuthStore } from './auth'
export const useCartStore = defineStore('cart', () => {
const auth = useAuthStore() // 매 다른 store 매 import + use
const items = ref<CartItem[]>([])
async function checkout() {
if (!auth.isLoggedIn) throw new Error('Login required')
return api.checkout(auth.user!.id, items.value)
}
return { items, checkout }
})
```
### $patch 매 batch update
```ts
const store = useUserStore()
store.$patch({ loading: false, user: newUser }) // 매 single devtools entry
// or function form for complex mutations
store.$patch((state) => {
state.cart.push(item)
state.lastUpdated = Date.now()
})
```
### $subscribe 매 store mutation 감지
```ts
store.$subscribe((mutation, state) => {
localStorage.setItem('cart', JSON.stringify(state))
}, { detached: true })
```
### Plugin (persistedstate)
```ts
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPersist)
// store 정의 시:
export const useUserStore = defineStore('user', {
state: () => ({ token: '' }),
persist: true, // localStorage 매 자동 sync
})
```
### SSR (Nuxt 3)
```ts
// composables/useAuth.ts
export const useAuthStore = defineStore('auth', () => {
const user = ref<User | null>(null)
// 매 Nuxt 3 매 자동 hydration — server 매 set 한 state 매 client 매 transfer
return { user }
})
```
### Testing
```ts
import { setActivePinia, createPinia } from 'pinia'
import { beforeEach, expect, test } from 'vitest'
beforeEach(() => setActivePinia(createPinia()))
test('counter increments', () => {
const store = useCounterStore()
expect(store.count).toBe(0)
store.increment()
expect(store.count).toBe(1)
expect(store.doubled).toBe(2)
})
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Vue 3 new project | Pinia (default) |
| Vuex 4 migration | Pinia (incremental, alias module) |
| Composition API preference | Setup store |
| Vuex-familiar team | Options store |
| Component-local state | `ref`/`reactive` (no store) |
| Server state caching | TanStack Query / 매 store 의 X |
| SSR (Nuxt) | Pinia (built-in support) |
**기본값**: 매 setup store + TypeScript + storeToRefs.
## 🔗 Graph
- 부모: [[Vue]] · [[State-Management]]
- 변형: [[Vuex]] (predecessor) · [[Redux]] · [[Zustand]] · [[Jotai]]
- 응용: [[Nuxt]] · [[Vue-SSR]]
- Adjacent: [[Composition-API]] · [[TanStack-Query]] · [[Reactivity]]
## 🤖 LLM 활용
**언제**: 매 Vue 3 global state, 매 cross-component sharing, 매 Nuxt 3 SSR state, 매 Vuex migration target.
**언제 X**: 매 component-local state (ref 만 충분), 매 server cache (TanStack Query 적합), 매 React project (Zustand/Redux).
## ❌ 안티패턴
- **storeToRefs 없이 destructure**: 매 reactivity loss — 매 `const { count } = store` 의 X.
- **Store action 매 component logic 침범**: 매 store 매 단순 state holder 매 됨 — 매 business logic 매 store 에 응집.
- **Nested store hierarchy 시도**: 매 flat 의 X — 매 cross-import 매 graph 형성.
- **Mutation pattern 의 반복**: 매 Vuex habit — 매 action 에서 직접 state 수정 OK.
- **매 component 매 store instance 다중 생성**: 매 useStore() 매 singleton — 매 매 호출 동일 instance.
## 🧪 검증 / 중복
- Verified (Pinia 2.x docs, Vue.js official).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — setup/options store + cross-store + SSR + plugin patterns |