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

[SCF-66] mock server init #67

Merged
merged 1 commit into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/commerce/app/(main)/book/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import BiViewListIcon from "assets/svg/bi_view_list_icon.svg";
import { Card } from "component/common/card";
import { Pagination } from "component/common/pagination";
import { BiView } from "component/common/biView";
import { MOCK } from "../../../mock/constants";
import { MOCK } from "../../../mocks/json/constants";
import * as S from "./book.styles";
import { ViewMode } from "./book.constants";

Expand Down
7 changes: 7 additions & 0 deletions apps/commerce/instrumentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
console.log("server instrucmenttation");
const { server } = await import("./mocks/server");
server.listen();
}
}
4 changes: 4 additions & 0 deletions apps/commerce/mocks/browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { setupWorker } from "msw/browser";
import { handlers } from "./handlers";

export const worker = setupWorker(...handlers);
3 changes: 3 additions & 0 deletions apps/commerce/mocks/handlers/index.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 모든 mock handler들이 다 모이는거구요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네네 맞습니다. node와 브라우저간 핸들러 다루는 함수(setupWorker)가 달라 이 둘은 나눠집니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import sign from "./sign";

export const handlers = [...sign];
14 changes: 14 additions & 0 deletions apps/commerce/mocks/handlers/sign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { http, HttpResponse } from "msw";

const signIn = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

signIn -> sign으로 바꿔야할 것 같아욥

Copy link
Collaborator Author

@osydoo osydoo Mar 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 로그인 관련 테스트 코드 작업하면서 수정해놓겠습니다. 현재 PR의 중점은 MSW 기본 세팅위주로 잡은지라 수정될 여지가 많아서요.

http.post(`${process.env.NEXT_PUBLIC_API_KEY}/sign-in`, () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

첫번째 매개변수 통해 넘겨온 api를 mock이 탈취해서 HttpResponse.json 형태로 돌려주는 꼴 맞나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 맞습니다. 리턴 방식은 다양하게 바꿔줄 수 있습니다만, 임시로 공식문서에서 제안한 �리턴값을 넣어둔 상태입니다.

return HttpResponse.json({
accessToken: "123",
});
}),
http.post(`${process.env.NEXT_PUBLIC_API_KEY}/sign-up`, () => {
return HttpResponse.json();
}),
];

export default signIn;
File renamed without changes.
4 changes: 4 additions & 0 deletions apps/commerce/mocks/server.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mock handler들을 여기서 다 갖고와서 목업 서버를 셋팅하는거구요

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { setupServer } from "msw/node";
import { handlers } from "./handlers";

export const server = setupServer(...handlers);
19 changes: 18 additions & 1 deletion apps/commerce/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ module.exports = {
compiler: {
styledComponents: true,
},
experimental: {
instrumentationHook: true,
},
// svgr : https://react-svgr.com/docs/next/
webpack(config) {
webpack(config, { isServer }) {
// Grab the existing rule that handles SVG imports
const fileLoaderRule = config.module.rules.find((rule) =>
rule.test?.test?.(".svg"),
Expand All @@ -31,6 +34,20 @@ module.exports = {
// Modify the file loader rule to ignore *.svg, since we have it handled now.
fileLoaderRule.exclude = /\.svg$/i;

if (isServer) {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/browser", alias: false });
} else {
config.resolve.alias["msw/browser"] = false;
}
} else {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/node", alias: false });
} else {
config.resolve.alias["msw/node"] = false;
}
}

return config;
},
};
10 changes: 8 additions & 2 deletions apps/commerce/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"zustand": "^4.5.2"
},
"devDependencies": {
"@sc-config/jest": "workspace:*",
"@next/eslint-plugin-next": "^13.4.19",
"@sc-config/jest": "workspace:*",
"@svgr/webpack": "^8.1.0",
"@tanstack/eslint-plugin-query": "^5.17.7",
"@testing-library/jest-dom": "^6.1.4",
Expand All @@ -43,7 +43,13 @@
"eslint-config-sc": "workspace:*",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.6.4",
"msw": "^2.2.12",
"tsconfig-sc": "workspace:*",
"typescript": "^5.2.2"
},
"msw": {
"workerDirectory": [
"public"
]
}
}
}
13 changes: 8 additions & 5 deletions apps/commerce/providers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import type { ReactNode } from "react";
import { ReactQueryProvider } from "./reactQuery";
import StyledJsxProvider from "./emotion";
import { ThemeProvider } from "./theme";
import { MockProvider } from "./msw";

const Providers = ({ children }: { children: ReactNode }) => {
return (
<ReactQueryProvider>
<StyledJsxProvider>
<ThemeProvider>{children}</ThemeProvider>
</StyledJsxProvider>
</ReactQueryProvider>
<MockProvider>
<ReactQueryProvider>
<StyledJsxProvider>
<ThemeProvider>{children}</ThemeProvider>
</StyledJsxProvider>
</ReactQueryProvider>
</MockProvider>
);
};

Expand Down
25 changes: 25 additions & 0 deletions apps/commerce/providers/msw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use client";
import { useEffect } from "react";

/**
* 참조 링크
* https://github.com/mswjs/msw/issues/1644
* draft pr : https://github.com/mswjs/examples/pull/101
*/

export function MockProvider({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
useEffect(() => {
(async () => {
if (typeof window !== "undefined" && process.env.NEXT_MOCK_SERVER) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 useEffect를 사용해서 mockServer를 클라이언트에서 마운트되고 시작하게 만든거군욥

Copy link
Collaborator Author

@osydoo osydoo Mar 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 검색해서 사람들이 사용한 방식 채용한겁니다. env 값으로 msw를 쓸지말지 정하는 방식은 좋아보이더라고요.

const { worker } = await import("../mocks/browser");
await worker.start();
}
})();
}, []);

return <>{children}</>;
}
Loading