[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
@@ -0,0 +1,325 @@
---
id: frontend-storybook-modern
title: Storybook 9 — component dev / test / docs
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [frontend, storybook, vibe-coding]
tech_stack: { language: "TS", applicable_to: ["Frontend"] }
applied_in: []
aliases: [Storybook 9, CSF 3, MDX, Chromatic, visual test, component library, design system]
---
# Storybook Modern (9)
> Component 의 isolated dev + test + docs. **CSF 3 (component story format), MDX, Chromatic visual test**.
## 📖 핵심 개념
- 매 component 가 isolated story.
- Variant (default, error, loading) 가 visible.
- Visual test (Chromatic).
- Design system 친화.
## 💻 코드 패턴
### Setup
```bash
npx storybook@latest init
```
### CSF 3 (modern)
```tsx
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
args: { children: 'Click me' },
argTypes: {
variant: { control: 'select', options: ['primary', 'secondary'] },
},
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: { variant: 'primary' },
};
export const Secondary: Story = {
args: { variant: 'secondary' },
};
export const Disabled: Story = {
args: { disabled: true },
};
```
→ Args + render = story.
### Interaction (play function)
```tsx
import { userEvent, within, expect } from '@storybook/test';
export const ClickAction: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const btn = canvas.getByRole('button');
await userEvent.click(btn);
await expect(btn).toHaveTextContent('Clicked');
},
};
```
→ Story 가 test 도. Storybook UI 에서 step replay.
### MDX (docs + story)
```mdx
import { Meta, Story } from '@storybook/blocks';
import { Button } from './Button';
<Meta title='Button' component={Button} />
# Button
A primary button component.
## Variants
<Canvas>
<Story name='Primary'>
<Button variant='primary'>Primary</Button>
</Story>
</Canvas>
## API
<ArgTypes />
```
→ Markdown + component embed.
### Chromatic (visual regression)
```bash
npm i -D chromatic
npx chromatic --project-token=...
```
→ 매 PR 이 visual diff. Approve / reject.
### Test runner
```bash
npm i -D @storybook/test-runner
npx test-storybook
```
→ 매 story 의 play 가 test.
Headless run.
### Mock (MSW)
```tsx
import { http, HttpResponse } from 'msw';
export const Loaded: Story = {
parameters: {
msw: {
handlers: [
http.get('/api/users', () => HttpResponse.json([{ name: 'Alice' }])),
],
},
},
};
```
→ Real-like data.
### Theme / decorator
```tsx
const meta: Meta = {
decorators: [
(Story) => (
<ThemeProvider theme={theme}>
<Story />
</ThemeProvider>
),
],
};
```
### Args + controls
```tsx
const meta: Meta<typeof Avatar> = {
argTypes: {
src: { control: 'text' },
size: { control: { type: 'range', min: 16, max: 128, step: 8 } },
variant: { control: 'select', options: ['circle', 'square'] },
},
};
```
→ Storybook UI 에서 live tweak.
### Auto-docs
```tsx
const meta: Meta = {
tags: ['autodocs'],
};
```
`Docs` tab 자동 생성 (props + variant).
### Vite
```js
// .storybook/main.ts
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(ts|tsx|mdx)'],
framework: { name: '@storybook/react-vite', options: {} },
addons: ['@storybook/addon-essentials', '@storybook/addon-a11y'],
};
```
→ Vite 친화 (빠른).
### a11y addon
```bash
npm i -D @storybook/addon-a11y
```
→ 매 story 가 axe 검증.
### Build (deploy)
```bash
npm run build-storybook
# → static-storybook/ 에 deploy.
```
→ Vercel / Netlify / GitHub Pages.
### Use case
```
- Design system (Bento, Radix UI examples).
- Component library showcase.
- Cross-team review.
- QA reproduction.
- Visual regression.
- Onboarding (이 component 가 무엇).
```
### vs Histoire / Ladle / React Cosmos
```
Histoire: Vue 친화.
Ladle: lighter, faster.
React Cosmos: legacy.
Storybook: 가장 mature.
→ Storybook 가 default.
```
### Performance
```
Storybook 9: 빠름 (Vite default).
큰 codebase: 1000+ story 가 OK.
→ 매 story file 가 lazy load.
```
### Production tips
```
- 매 component 의 매 variant.
- Edge case (loading, error, empty).
- Long content (truncation).
- Different size / theme.
- A11y test 항상.
- Visual diff CI gate.
```
### CI integration
```yaml
- run: npm run build-storybook
- run: npx test-storybook --url http://localhost:6006
- run: npx chromatic
```
### Composition (multi-storybook)
```ts
// .storybook/main.ts
const config = {
refs: {
'design-system': { url: 'https://design.example.com' },
'component-library': { url: 'https://components.example.com' },
},
};
```
→ 다른 storybook 가 1 navigation.
### Args from URL
```
?args=variant:primary;size:lg
```
→ Bookmark / share.
### Custom addon
```ts
// addon-my-feature/manager.ts
import { addons, types } from '@storybook/manager-api';
addons.register('my-addon', () => {
addons.add('my-addon/panel', {
type: types.PANEL,
title: 'My Panel',
render: ({ active }) => <div>Custom UI</div>,
});
});
```
### LLM 도움
```
- Story generation (component → variant).
- Visual diff explanation.
- A11y violation fix.
```
### 함정
```
- 모든 story 가 매 변경 = Chromatic cost.
- Story 가 stale (component 변경 후 안 update).
- Decorator 가 prod 가 다른 (theme).
- Args 가 너무 많음 = noisy.
- Build 가 slow (큰 codebase).
```
## 🤔 의사결정 기준
| 작업 | 추천 |
|---|---|
| Component dev | Storybook |
| Visual test | Chromatic + Storybook |
| Design system | Storybook + composition |
| Vue | Histoire / Storybook |
| 작은 / 빠름 | Ladle |
| Documentation | MDX + autodocs |
## ❌ 안티패턴
- **Story 안 maintain**: stale.
- **No edge case**: production 가 first 진실.
- **Storybook + Cypress 둘 다 component test**: redundant.
- **No visual diff**: silent regression.
- **No a11y test**: accessibility 깨짐.
## 🤖 LLM 활용 힌트
- CSF 3 가 modern.
- Chromatic + Storybook 가 visual test.
- Play function 가 interaction test.
- a11y addon 항상.
## 🔗 관련 문서
- [[Testing_Visual_Regression]]
- [[Frontend_Design_Tokens]]
- [[Frontend_shadcn_Radix_Patterns]]