Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#18] Chore: storybook 에 msw 적용 #19

Merged
merged 11 commits into from
Apr 26, 2024
1 change: 1 addition & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ const config: StorybookConfig = {
autodocs: 'tag',
},
staticDirs: ['../public'],
features: { experimentalRSC: true },
};
export default config;
3 changes: 3 additions & 0 deletions .storybook/preview.ts → .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Preview } from '@storybook/react';
import { initialize, mswLoader } from 'msw-storybook-addon';

initialize({ onUnhandledRequest: 'bypass' });
const preview: Preview = {
parameters: {
controls: {
Expand All @@ -9,6 +11,7 @@ const preview: Preview = {
},
},
},
loaders: [mswLoader],
};

export default preview;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"msw": "^2.2.14",
"msw-storybook-addon": "^2.0.0",
"postcss": "^8",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.14",
Expand All @@ -63,4 +64,4 @@
"public"
]
}
}
}
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion postcss.config.mjs → postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ const config = {
},
};

export default config;
module.exports = config;
36 changes: 22 additions & 14 deletions src/mocks/handlers/post.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { HttpResponse, http } from 'msw';

const getPostList = http.get(`${process.env.NEXT_PUBLIC_URL}/posts`, () => {
return HttpResponse.json({
content: [
{
postId: '1',
nickname: 'testAccount',
title: '제목일세',
createAt: '2024-03-01T18:55:48.884Z',
viewCount: 30,
likeCount: 1,
hashtags: ['#해시태그'],
},
],
});
interface Post {
postId: string;
nickname: string;
title: string;
createAt: string;
viewCount: number;
likeCount: number;
hashtags: string[];
}

const getPostList = http.get(`posts`, () => {
return HttpResponse.json<Post[]>([
{
postId: '1',
nickname: 'testAccount',
title: '제목일세',
createAt: '2024-03-01T18:55:48.884Z',
viewCount: 30,
likeCount: 1,
hashtags: ['#해시태그'],
},
]);
});

export const handlers = [getPostList];
9 changes: 9 additions & 0 deletions src/stories/decorator.tsx
HoberMin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { type Decorator } from '@storybook/react';

import '../style/globals.css';

export const PageLayoutDecorator: Decorator = Story => (
<div className='relative flex h-[600px] w-[350px] shrink-0 flex-col'>
<Story />
</div>
);
96 changes: 96 additions & 0 deletions src/stories/msw-exmple/msw.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Canvas, Meta } from '@storybook/blocks';

import * as MswStories from './msw.stories';

<Meta of={MswStories} />

# msw 기본 예제

## story 에서 msw 로 데이터 모킹하여 tsx 파일에서 출력하는 예제입니다.

```ts
// msw.tsx
'use client';

import { useEffect, useState } from 'react';

const Msw = () => {
const [data, setData] = useState();

useEffect(() => {
fetch('posts')
.then(res => res.json())
.then(json => setData(json));
}, []);

return <div>{JSON.stringify(data)}</div>;
};

export default Msw;

```

```ts
// msw.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';

import { handlers } from '@/src/mocks/handlers';
import { PageLayoutDecorator } from '@/src/stories/decorator';

import Msw from './msw';

export default {
title: 'mocks/msw',
component: Msw, // 원하는 페이지 컴포넌트
decorators: PageLayoutDecorator, // 모바일 뷰 레이아웃 적용
} satisfies Meta<typeof Msw>;

type Story = StoryObj<typeof Msw>;

export const Default: Story = {
parameters: {
msw: {
handlers, // handers 설정
},
},
};
```

## handlers 는 따로 정의 해주셔야합니다.

### [handlers 정의 하는법](https://mswjs.io/docs/api/http)

```ts
// src/mocks/handlers/post.ts
import { HttpResponse, http } from 'msw';

interface Post {
postId: string;
nickname: string;
title: string;
createAt: string;
viewCount: number;
likeCount: number;
hashtags: string[];
}

const getPostList = http.get(`posts`, () => {
return HttpResponse.json<Post[]>([
{
postId: '1',
nickname: 'testAccount',
title: '제목일세',
createAt: '2024-03-01T18:55:48.884Z',
viewCount: 30,
likeCount: 1,
hashtags: ['#해시태그'],
},
]);
});

export const handlers = [getPostList];
```

## 결과

<Canvas />
22 changes: 22 additions & 0 deletions src/stories/msw-exmple/msw.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Meta, StoryObj } from '@storybook/react';

import { handlers } from '@/src/mocks/handlers';
import { PageLayoutDecorator } from '@/src/stories/decorator';

import Msw from './msw';

export default {
title: 'mocks/msw',
component: Msw, // 원하는 페이지 컴포넌트
decorators: PageLayoutDecorator, // 모바일 뷰 레이아웃 적용
} satisfies Meta<typeof Msw>;

type Story = StoryObj<typeof Msw>;

export const Default: Story = {
parameters: {
msw: {
handlers, // handers 설정
},
},
};
17 changes: 17 additions & 0 deletions src/stories/msw-exmple/msw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import { useEffect, useState } from 'react';

const Msw = () => {
const [data, setData] = useState();

useEffect(() => {
fetch('posts')
.then(res => res.json())
.then(json => setData(json));
}, []);

return <div>{JSON.stringify(data)}</div>;
};

export default Msw;
Loading