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

[1단계 - 장바구니] 호프(김문희) 미션 제출합니다. #71

Merged
merged 56 commits into from
May 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
6ffd155
docs: 필수요구사항 정리
moonheekim0118 May 10, 2022
9561d4f
chore: 환경 설정 및 불필요한 파일 정리
moonheekim0118 May 10, 2022
8b09d7e
chore: 절대경로 환경 설정
moonheekim0118 May 10, 2022
2ee50db
feat: 헤더 및 메뉴 아이템 컴포넌트 작성
moonheekim0118 May 10, 2022
385d56f
feat: ProductItem 컴포넌트 작성
moonheekim0118 May 10, 2022
264d755
feat: ProductsContainer 컴포넌트 작성
moonheekim0118 May 10, 2022
915c284
feat: ProductListPage 컴포넌트 작성
moonheekim0118 May 10, 2022
154e2ec
chore: 리덕스 설치 및 실행 확인
moonheekim0118 May 10, 2022
8c4beed
feat: redux, redux-thunk, axios 적용하여 비동기 통신 작성
moonheekim0118 May 11, 2022
eb36b1b
refactor: 리듀서, configureStore, thunk 분리
moonheekim0118 May 11, 2022
2046d1d
feat: 화면 로딩 시 스켈레톤 UI 표시 구현
moonheekim0118 May 11, 2022
746e2ba
feat: 예외사항 처리 구현
moonheekim0118 May 11, 2022
57a8022
feat: 라우팅 적용
moonheekim0118 May 11, 2022
d2ae2d9
feat: 상품 상세페이지 UI 컴포넌트 작성
moonheekim0118 May 11, 2022
13494e8
feat: Product 페이지에 대한 Reducer, Routing, 렌더링 구현
moonheekim0118 May 11, 2022
51cc167
feat: 상품 클릭시 해당 상품 상세 페이지로 라우팅 및 렌더링 구현
moonheekim0118 May 11, 2022
eaf99fe
refactor: 공통 컴포넌트 레이아웃 Outlet 으로 리팩토링
moonheekim0118 May 12, 2022
6c6ee1d
refactor: useDispatch, useSelector 사용하는 커스텀훅 작성
moonheekim0118 May 12, 2022
85f540b
fix: 데이터가 있을 시 API 재요청 하지 않도록 수정
moonheekim0118 May 12, 2022
d5c37b3
fix: 스토리북 라우터 설정
moonheekim0118 May 12, 2022
d2df965
feat: NotFound 페이지 작성
moonheekim0118 May 12, 2022
2ca5630
feat: 장바구니 기능 작성
moonheekim0118 May 12, 2022
e01abe4
fix: storybook 문제 해결
moonheekim0118 May 12, 2022
c3f925b
fix: PropTypes 에러 해결
moonheekim0118 May 12, 2022
f024198
feat: 로딩 스피너 추가
moonheekim0118 May 12, 2022
dc9e5ba
chore: package.json 수정
moonheekim0118 May 14, 2022
9d664c5
refactor: route의 exact 옵션 삭제
moonheekim0118 May 14, 2022
5aa858f
refactor: Routes 분리
moonheekim0118 May 14, 2022
c22a7d6
refactor: globalStyle 분리
moonheekim0118 May 14, 2022
c5043bc
refactor: globalStyle 위치 수정
moonheekim0118 May 14, 2022
84612f0
refactor: styled-component css helper 사용하도록 수정 및 Theme 적용
moonheekim0118 May 14, 2022
7267a1d
refactor: media query 사이즈 theme 에 등록하여 사용하도록 수정
moonheekim0118 May 14, 2022
eaa6f40
refactor: style 폴더 분리
moonheekim0118 May 14, 2022
244a48d
refactor: CSS 색상 하드코딩 -> theme 적용으로 수정
moonheekim0118 May 14, 2022
3d81ac0
refactor: keyframes styled-component 로 수정
moonheekim0118 May 14, 2022
7127c0c
style: header 색상 수정
moonheekim0118 May 14, 2022
a9dd89f
refactor: Pages 내부 파일명 수정
moonheekim0118 May 14, 2022
4b362ad
refactor: mock데이터 asset 활용
moonheekim0118 May 14, 2022
3340802
refactor: on-* -> handle-* 로 수정
moonheekim0118 May 14, 2022
ab8218b
refactor: useProduct 훅 작성
moonheekim0118 May 14, 2022
c641576
refactor: useProducts 훅 작성
moonheekim0118 May 14, 2022
915d50a
refactor: 변수명 명시적으로 수정 및 useReduxState 커스텀훅 활용하도록 수정
moonheekim0118 May 14, 2022
e500987
refactor: pathname 상수화
moonheekim0118 May 14, 2022
0c3aef1
style: spinner 수정
moonheekim0118 May 14, 2022
b731b2f
test: storybook ThemeProvider 추가
moonheekim0118 May 14, 2022
3ebbb8b
test: storybook control 수정
moonheekim0118 May 14, 2022
7c50683
test: ImgWrapper 스토리 추가
moonheekim0118 May 14, 2022
26d71ef
refactor: ImgWrapper size prop 추가
moonheekim0118 May 14, 2022
6a94f54
style: font 추가 및 변경
moonheekim0118 May 14, 2022
cbdd6ae
style: 상품리스트 스타일 추가
moonheekim0118 May 14, 2022
b1046be
style: 불필요한 스타일 제거
moonheekim0118 May 14, 2022
3e3f8d6
feat : 가격 파싱 추가
moonheekim0118 May 14, 2022
42de9b0
refactor: 이미지 레이지로딩 추가
moonheekim0118 May 14, 2022
fce8278
deploy: netlify 리다이렉트 설정 추가
moonheekim0118 May 14, 2022
e40d9a3
refactor: apiClient 객체 매번 생성하지 않도록 수정
moonheekim0118 May 14, 2022
137479b
refactor: theme depth 추가
moonheekim0118 May 14, 2022
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
19 changes: 19 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {

Choose a reason for hiding this comment

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

eslintrc.json과 .js. 어떤 차이가 있고 왜 두 가지를 제공하는걸까요?

Copy link
Author

Choose a reason for hiding this comment

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

찾아보니, eslint 파일 설정 포맷은 js , json을 제외하고도 JavaScript (ESM), yaml 도 제공해준다고 합니다. 각각은 아래와 같이 사용됩니다.

  • js : eslintrc.js 로 정의 할 수 있고, eslint 설정이 담긴 객체를 export 합니다.
  • JavaScript (ESM) : eslintrc.cjs 로 정의 할 수 있고, package.json 에서 “type”:”module” 을 지정 할 경우 사용합니다.
    • ESM 은 ECMAScript module 의 약자입니다.
    • ESM 은 ECMAScript에서 지원하는 자바스크립트 공식 모듈 시스템입니다.
    • (추측) 노드에서는 아직 common js 를 지원하기 때문에, import ~export문 을 쓰기 위해서는 .cjs 로 정의해줘야하는 것 같아요!
  • YAML : eslint.yaml or eslint.yml 로 정의 할 수 있습니다.
    • YAML 들어만 봤지 무엇인지 처음찾아봤는데 JSON 처럼 데이터를 쉽게 표현하기 위한 언어라고합니다.
  • JSON : eslintrc.json 으로 정의 할 수 있습니다.

그리고 만약 여러개의 설정 파일이 같은 디렉토리에 있다면 우선순위는,

  1. .eslintrc.js
  2. .eslintrc.cjs
  3. .eslintrc.yaml
  4. .eslintrc.yml
  5. .eslintrc.json
  6. package.json

이라구 합니다.

즉 말씀주신 eslintrc.js 와 eslintrc.json의 차이점은 lint 설정 파일 내에서 사용되는 언어 (javascript / json) 과 우선순위가 있겠네요!

그렇다면 왜 이렇게 eslint 가 여러개의 파일 설정 포맷을 제공하는지 추측해보았는데요..! 다양한 환경을 지원해주기 위해서! 라고 생각합니다.
누군가는 백엔드 서버를 구현하는데 eslint 를 사용하기도 하고, 누군가는 클라이언트를 구현하기 위해서 사용하기도 하니까요? 따라서 js, esm 를 둘다 지원해주는 것 같고, json, yaml 을 지원해주는 것은 자바스크립트 모듈 시스템에 구애받지 않는 포맷을 제공해주기 위함인 것 같다고 추측합니다..!!!

참고자료

Configuration Files - ESLint - Pluggable JavaScript linter

Choose a reason for hiding this comment

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

아주 훌륭합니다... 박사가 되셨군요..

env: {
browser: true,

Choose a reason for hiding this comment

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

browser와 node 옵션 둘 다 주는 이유가 있을까요?

Copy link
Author

@moonheekim0118 moonheekim0118 May 14, 2022

Choose a reason for hiding this comment

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

일단..! 별 생각 없이 린트를 설정한 것 같아서 해당 옵션이 뭘 해주는지 부터 찾아봤습니다.

Env 옵션은,

  • 스크립트 실행 환경을 설정해줍니다.
  • 전역 변수를 미리 정의해줍니다.

browser : true 로 해준 이유

  • browser 를 환경으로 설정해주지 않을 경우, browser 환경에서 제공하는 메서드들을 (window.*) 인식 할 수가 없기에 에러가 납니다.

node : true 로 해준 이유

  • 이 옵션은 원래 주지 않았다가, eslint 파일을 설정 한 후 eslint 설정 파일 내에서 module is not defined 라는 에러가 나서 준 옵션입니다.
  • 즉, node 환경에서 제공하는 메서드 (module) 을 사용하기 위해서 설정한 옵션입니다.

이를 공부하다가 알게 된 사실인데, Env 옵션에 사용자가 직접 전역 변수를 설정할 수 도 있네요!

좋은 질문 감사드립니다 ㅎㅎ

참고자료

Language Options - ESLint - Pluggable JavaScript linter

Copy link

@Vallista Vallista May 15, 2022

Choose a reason for hiding this comment

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

아휴~~ 좋은 답변 감사합니다!

완전 박사가 되신듯..

es2021: true,

Choose a reason for hiding this comment

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

es2021를 true 로 했을때 장점이 무엇일까요?

Copy link
Author

Choose a reason for hiding this comment

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

위의 답변 에 대해 답하고 나니 이는 쉽게 파악이 되네요! 최신 문법(es2021)의 전역 변수들을 eslint가 자동으로 사전에 설정해놓음으로써 최신문법을 사용 할 수 있겠습니다.

node: true,
},
extends: ['eslint:recommended', 'plugin:react/recommended'],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['react'],
rules: {
'react/react-in-jsx-scope': 'off',
},
};
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

Choose a reason for hiding this comment

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

pnp.js 는 무엇일까요?

Copy link
Author

@moonheekim0118 moonheekim0118 May 14, 2022

Choose a reason for hiding this comment

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

먼저 결론부터 말하면 pnp 는 yarn 환경에서 쓰이는 것이고, 일종의 패키지들의 룩업테이블 역할을 하는 것 같아요! pnp는 plugNplay 의 약자입니다. Cra 에서 create-react-app —use-pnp Yarn 과 함께 실행하면 pnp 를 사용하는 프로젝트를 생성할 수 있다구 하네요!

그러면 왜 pnp 가 필요할까요 ?! 먼저 yarn 이 해결하려는 문제와 함께 살펴볼게요.

node_modules 문제점

이전에 yarn install 을 실행하면, yarn 은 node_modules 폴더를 생성했습니다. 이 때 Node 는 특정 패키지에 대해서 바로 알지는 못하고, 계속해서 상위 node_modules 파일을 찾아보는 식으로 패키지를 찾았습니다. 그런데 이는 아래와 같은 이유로 매우 비효율적이었어요

  • node_modules에는..정말 정말 엄청난 양의 파일이 들어있습니다. 그래서 애초에 yarn install 후 node_modules를 생성하는 것에 시간 소모가 큽니다.
  • 그 외에도 node_modules 생성은 I/O 부하가 높은 작업이기도 하고, package.json 에 디펜던시를 까먹고 넣지 않으면..! 코드에서 런타임에서 에러가 날 수도 있습니다.
  • 그리고 무엇보다, node_modules 폴더 설계는 패키지 매니저가 적절하게 패키지 중복 제거를 허용하지 않기에 비효율적입니다! 따라서 중복된 패키지가 여러번 존재하게 되는 문제도 있어요.

그런데! Yarn 은 이미 디펜던시 트리에 대해 다~~~ 알고 있습니다. 따라서 패키지가 어디있는지 찾는 역할을 Node 에게 맡기지 않아도 되는거죠! 대신 패키지 매니저로서 패키지의 위치를 인터프리터에 알리고, 패키지 매니저 yarn 은 패키지 및 패키지 버전간의 디펜던시를 관리를 합니다. 이를 위해서 ‘plug(연결)Nplay’ 가 만들어졌어요 (인터프리터와 패키지를 연결한다는 것..이겠죠?)

따라서 yarn 은 2.0 버전부터 node_modules 대신 .pnp.js 파일을 생성합니다.
pnp.cjs 파일은 여러개의 맵들이 포함되어있는데요,

  1. 패키지 이름과 버전을 디스크에서의 위치와 연결해줍니다.
  2. 패키지 이름과 버전을 디펜던시 리스트와 연결해줍니다.

이러한 룩업테이블을 통해서 yarn 은 Node 에게 쉽게 ‘해당 패키지를 찾으려면 어디로가!’ 를 말해줄 수 있어요. 이전에 Node 가 일일이 node_modules 파일을 탐색해야했던 것에 비하면..엄청난 발전입니다.

참고자료

Plug’n’Play | Yarn - Package Manager

Choose a reason for hiding this comment

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

좋아용! 그런데, 지금 프로젝트에 pnp를 쓰고 있고, 사용하는 것일까요!?

Copy link
Author

Choose a reason for hiding this comment

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

아앗 답변만하고 ㅋㅋㅋ적용은 안했네요!! 😆 .. 현재 프로젝트에서 사용되지 않는 것들 다 gitignore에서 걷어내겠습니다..!!


# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

.env
6 changes: 6 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
singleQuote: true, // 작은 따옴표 사용
trailingComma: 'all', // 꼬리 콤마 사용

Choose a reason for hiding this comment

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

trailingComma: 'all' 는 꼬리 콤마를 어떻게 사용한다는 걸까요? 어떤 옵션이 있고, 왜 all 을 사용하셨을까요?

Copy link
Author

@moonheekim0118 moonheekim0118 May 14, 2022

Choose a reason for hiding this comment

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

꼬리콤마란 무엇이고, 어떤 옵션이 있고, 왜 사용했는지 순으로 답변해보겠습니다!!!

꼬리콤마란

Trailing commas 옵션은 여러 줄의 콤마로 구분되었을 경우 아래와 같이 꼬리 콤마를 붙여줍니다.

// 포맷 전 
const obj = {
  key1: 1,
  key2: 2
};

// 포맷 후 
const obj = {
  key1: 1,
  key2: 2,
};

꼬리콤마 옵션 종류

옵션 종류는 아래와 같아요.

  1. es5 (default) : ES5에서 꼬리콤마가 유효한 경우 콤마를 붙여줍니다. (객체,배열 등등) 하지만 타입스크립트의 타입 파라미터에서는 꼬리콤마를 붙여주지 않습니다.
  2. none : 그 어떤 경우에도 꼬리콤마를 붙여주지 않습니다.
  3. all : 꼬리콤마가 가능한 경우(함수 파라미터 포함) 모두 꼬리콤마를 붙여줍니다. 타입스크립트의 타입 파라미터에서도 꼬리콤마를 붙여줍니다.

왜 all 로 설정했는지?

  • 사실 프리티어 설정할 때 페어와 각자의 이전 프리티어 설정 옵션을 보고 한거라..솔직히 말하면 딱히 큰 이유는 없습니다…ㅎㅎ! 그런데, 저는 None 옵션은 거의 사용하지 않는 이유가 객체나 배열이 길어지면 추후에 요소가 추가될 가능성이 높기 때문에 꼬리콤마를 프리티어에서 알아서 붙여주는 것을 선호해요! 함수 파라미터도 마찬가지이구요..~! 그래서 함수 파라미터 꼬리콤마를 지원하지 않는 es5보다는 all 을 사용하는 게 더 편할 것 같아요 :)

참고자료

Options · Prettier

Choose a reason for hiding this comment

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

아주 훌륭합니다!

proseWrap: 'never', // 마크다운 포매팅 제외
endOfLine: 'auto', // 개행문자 유지 (혼합일 경우, 첫 줄 개행문자로 통일)
};
16 changes: 16 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"

Choose a reason for hiding this comment

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

"../src/**/*.stories.@(js|jsx|ts|tsx)" 에서 @는 무얼나타낼까요?

Copy link
Author

@moonheekim0118 moonheekim0118 May 14, 2022

Choose a reason for hiding this comment

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

괄호 안에 있는 확장자를 허용하겠다는 표시(?)입니다.

이해하기 쉽게 *와 비교하자면, *는 모든 폴더명이나 파일명을 허용하기 위함이고
@는 괄호 안에 적혀있는 확장자만..! 허용하기 위함입니다. :)

],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/preset-create-react-app"
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
}
}
19 changes: 19 additions & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { addDecorator } from '@storybook/react';
import { MemoryRouter } from 'react-router-dom';
import StyleTheme from '../src/style/theme';

export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};

addDecorator((story) => (
<MemoryRouter>
<StyleTheme>{story()}</StyleTheme>
</MemoryRouter>
));
Empty file removed REQUIREMENTS.md
Empty file.
35 changes: 35 additions & 0 deletions REQUIRENMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 장바구니

- [x] CDD - 컴포넌트 개발
- [x] Header 컴포넌트 만들기
- [x] MenuItem 컴포넌트 만들기
- [x] ProductItem 컴포넌트 만들기
- [x] ProductsContainer 컴포넌트 만들기
- [x] ProductList Page 컴포넌트 만들기
- [x] Mock Data 만들기

- [x] redux 적용

- [x] redux-thunk 적용
- [x] axios 적용

- [x] 데이터 로딩 시 스켈레톤 UI를 보여준다.
- [x] 데이터가 비어 있을 시 비어있음 이미지를 보여준다.
- [x] API 에러 발생 시 에러 이미지를 보여준다.

- [x] 라우팅(상품목록, 상품상세, 장바구니)
- [x] 상품 상세 페이지

- [x] UI 컴포넌트 작성
- [x] 상품 목록에서 상품 클릭 시 id를 받아서 해당 상품 상세 페이지로 라우팅 및 렌더링
- [x] product 리듀서 만들기

- [x] 공통컴포넌트 레이아웃 Outlet으로 리팩토링
- [x] 커스텀 훅 (dispatch, useSelector) 만들기
- [x] 상품상세 페이지를 보고 뒤로가기하면 불필요하게 다시 API 요청하지 않도록 만들기
- [x] 스토리북 정상 작동하게 만들기
- [x] Not Found Page 작성

- [x] cart 리듀서 만들기
- [x] 장바구니 넣기 기능(같은 아이템을 중복으로 장바구니에 넣을 경우 수량을 1개씩 증가한다)
- [ ] 장바구니 페이지
6 changes: 6 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
Loading