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

충남대 FE_강병현_1주차_과제 Step1 #18

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
3a896a3
docs(README.md): add a list of features
kang-kibong Jun 25, 2024
586a145
feat(kakao-gift): create TypeScript project using CRA
kang-kibong Jun 25, 2024
9a6f829
chore: remove unnecessary code and files
kang-kibong Jun 25, 2024
f22f89e
chore: configure absolute paths using craco
kang-kibong Jun 25, 2024
dc76831
chore: set up Prettier formatting rules
kang-kibong Jun 26, 2024
45a3b22
chore: configure ESLint rules according
kang-kibong Jun 26, 2024
de2ffcc
chore: add emotion styling library
kang-kibong Jun 26, 2024
2ae3ea8
feat: add Button component
kang-kibong Jun 26, 2024
b5fcaed
feat: Apply reset CSS globally
kang-kibong Jun 26, 2024
5ef0d54
feat: Initialize folder structure
kang-kibong Jun 26, 2024
f558c4e
chore: Moved files to new directory structure
kang-kibong Jun 26, 2024
2317065
feat: feat: Add lint-staged and husky
kang-kibong Jun 26, 2024
4840d6a
docs: Add feature list for Storybook components in README
kang-kibong Jun 27, 2024
ddc3fff
chore: install and configure Storybook
kang-kibong Jun 27, 2024
f9747a7
refactor(components): update Button component
kang-kibong Jun 27, 2024
bc5c112
design(Button): Implement button styling based on size props
kang-kibong Jun 27, 2024
c7e61b0
design(Button): Implement button styling based on theme props
kang-kibong Jun 27, 2024
c7b8991
feat(storybook): add Button component story
kang-kibong Jun 27, 2024
af20619
feat: add Input component
kang-kibong Jun 28, 2024
6dd2c28
feat: add disabled prop styling to Input component
kang-kibong Jun 28, 2024
76fcdd0
feat: add invalid prop styling to Input component
kang-kibong Jun 28, 2024
df88036
feat: implement size prop styling for Input component
kang-kibong Jun 28, 2024
4621a85
feat: add Storybook stories for Input component
kang-kibong Jun 28, 2024
0213fc5
feat: add Image component
kang-kibong Jun 28, 2024
41eede0
feat: add ratio prop to set image aspect ratio in Image component
kang-kibong Jun 28, 2024
74bec12
feat: add radius prop to set border radius in Image component
kang-kibong Jun 28, 2024
563337a
feat: add width and height props to Image component
kang-kibong Jun 28, 2024
166a65e
feat: add Storybook stories for RatioSquare, RadiusCircle, and Radius…
kang-kibong Jun 28, 2024
e0158a9
docs(README): add README documentation
kang-kibong Jun 28, 2024
3f8b081
feat: implement GoodsItem component with common props
kang-kibong Jun 28, 2024
4f57ac9
feat: add GoodsItem component
kang-kibong Jun 28, 2024
bcb5659
feat: add Ranking component
kang-kibong Jun 28, 2024
0a1ea6d
feat: add Storybook stories for GoodsItem Default and Ranking components
kang-kibong Jun 28, 2024
dfdaebe
feat: add Container component
kang-kibong Jun 28, 2024
5ef7785
feat: add Storybook stories for Container component
kang-kibong Jun 28, 2024
3058f54
feat: add FullScreen story for Container component
kang-kibong Jun 28, 2024
dcaeca4
feat: add Grid component
kang-kibong Jun 28, 2024
daf0158
feat: add NumberColumns story for Grid component
kang-kibong Jun 28, 2024
b38ee04
feat: add ResponsiveColumns story for Grid component
kang-kibong Jun 28, 2024
571bacf
chore: move Button component file to common folder
kang-kibong Jun 28, 2024
3872a5c
chore: move files
kang-kibong Jun 28, 2024
e524f7d
docs: update README
kang-kibong Jun 28, 2024
69d09a4
feat: add autodocs tags to all Storybook files
kang-kibong Jun 28, 2024
997a79a
fix: add babel-preset-react-app to package.json
kang-kibong Jun 28, 2024
a9c4096
docs: add requirements from code review to README
kang-kibong Jun 28, 2024
65a4214
chore: remove eslintConfig from package.json
kang-kibong Jun 28, 2024
def5518
chore: move testing and types dependencies to devDependencies
kang-kibong Jun 28, 2024
ce11642
docs: add initial folder structure explanation to README
kang-kibong Jun 28, 2024
9abf298
chore: update lint script target
kang-kibong Jun 28, 2024
43c723b
docs: create QUESTIONS.md
kang-kibong Jun 28, 2024
02fd425
feat(button): update responsive height styles
kang-kibong Jun 29, 2024
ab9c04c
refactor(ranking): remove magic number by defining a constant
kang-kibong Jun 29, 2024
60a07c4
refactor(props): refactor all files to spread props for cleaner code
kang-kibong Jun 29, 2024
3d13ff9
refactor(goods-item): replace magic numbers with constants
kang-kibong Jun 29, 2024
2c9105b
chore: move styles folder to assets folder
kang-kibong Jun 29, 2024
ab6680f
fix(dependencies): add @babel/plugin-proposal-private-property-in-obj…
kang-kibong Jun 29, 2024
a06d91e
refactor(GoodsItem): separate renderRanking method for better readabi…
kang-kibong Jun 29, 2024
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
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["@emotion"]
}
57 changes: 57 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["react-app", "eslint:recommended", "plugin:import/typescript", "airbnb", "prettier"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-var": "error",
"no-multiple-empty-lines": "error",
"no-console": ["error", { "allow": ["warn", "error", "info"] }],
"eqeqeq": "error",
"dot-notation": "error",
"no-unused-vars": "error",
"import/extensions": ["error", "ignorePackages", {
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}],
"react/jsx-props-no-spreading": "off",
"import/prefer-default-export": "off",
"react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }],
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
"import/no-unresolved": "off",
"react/require-default-props": "off",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": ["error", { "variables": false , "functions": false,"classes": false}],
"react/prop-types": "off",
"import/no-cycle": "off"
},
"settings": {
"import/resolver": {
"alias": {
"map": [
["@", "./src"],
["@components", "./src/components"],
["@styles", "./src/styles"],
["@apis", "./src/apis"],
["@assets", "./src/assets"],
["@hooks", "./src/hooks"],
["@pages", "./src/pages"],
["@store", "./src/store"],
["@utils", "./src/utils"]
],
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
}
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# 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*

.eslintcache
*storybook.log
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npx lint-staged
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"singleQuote": true,
"parser": "typescript",
"semi": true,
"useTabs": false,
"tabWidth": 2,
"printWidth": 120,
"arrowParens": "always"
}
31 changes: 31 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { StorybookConfig } from '@storybook/react-webpack5';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/preset-create-react-app',
'@storybook/addon-onboarding',
'@storybook/addon-links',
'@storybook/addon-essentials',
'@chromatic-com/storybook',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-webpack5',
options: {},
},
staticDirs: ['../public'],
webpackFinal: async (config) => {
if (config.resolve) {
config.resolve.plugins = [
...(config.resolve.plugins || []),
new TsconfigPathsPlugin({
extensions: config.resolve.extensions,
}),
];
}
return config;
},
};
export default config;
14 changes: 14 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Preview } from '@storybook/react';

const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
112 changes: 112 additions & 0 deletions QUESTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
## 1주차 [질문](https://kibong.notion.site/db60b098e56e4333ae78e8c44edd09f5)

### 1. reportWebVital?
이번 프로젝트를 세팅하면서 불필요한 파일을 탐색하던중 reportWeVital이라는 것을 알게되었는데요.
찾아보니 웹 성능 측정을 통해서 사용자 경험과 성능 평가를 가능하게 해주는 도구임을 알게되었습니다.
초기 React프로젝트를 reportWebVitals로 console로 간단하게 찍어보니 console탭에서 성능에 대한 결과를 객체 형태로 확인할 수 있었습니다.
결과로 FCP, TTFB, LCP, FID, CLS와 같이 다양한 방면으로 성능 측정이 가능하다는 것을 확인할 수 있었습니다.
이러한 웹 성능 측정을 회사에서 실제로 많이 고민하고 코드를 짜는지 궁금하고, 한번도 이런 성능 측정을 해본 경험이 없기에 이 부분에 대해서 더 자세히 알려면 어떤식으로, 어떻게 공부하고 경험할 수 있는지 궁금합니다.

Choose a reason for hiding this comment

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

이러한 웹 성능 측정을 회사에서 실제로 많이 고민하고 코드를 짜는지 궁금하고

요건 회사에 속한 팀 문화마다 다를 거 같아요. Web Vitals에 있는 수치를 중요시 여긴다면 CI 과정에서 특정 점수 이하로 내려가지 않도록 추적해서 내려간다면 CI를 깨뜨린다거나 PR 병합을 하지 못하게 한다거나 강하게 규칙을 적용할 수도 있을 거 같구요. 제가 속한 조직에서는 강한 규칙보다는 도구를 활용해서 각 수치가 얼만큼 변화하고 있는지 추적해서 대응하는 방향으로 처리하고 있어요. datadog 또는 sentry 와 같은 도구의 피처가 그 예시입니다.

한번도 이런 성능 측정을 해본 경험이 없기에 이 부분에 대해서 더 자세히 알려면 어떤식으로, 어떻게 공부하고 경험할 수 있는지 궁금합니다.

제가 느끼기에는 일반적으로 아래처럼 3가지 단계를 반복적으로 진행하게 되는데요, 이를 위해 수치적 분석을 위한 개념을 이해하고 분석 및 개선 후 수치 변화 추적을 위해 Web Vitals, Lighthouse, Chrome DevTools의 Performance 탭 사용 방식을 익히는 것 정도가 생각나네요.

  1. 문제 식별
  2. 진단을 통한 원인 파악 (병목 지점 파악 포함)
  3. 개선 후 변화 분석

아래 3가지를 읽고 이해하는게 시작점이 될 수 있지 않나 싶습니다.

  1. Core Web Vitals
  2. Metrics
  3. Fast load times

### 2. 절대경로 ESLint 에러 이슈 어떻게 해결해야할까요?
<img width="606" alt="스크린샷 2024-06-26 오후 5 44 42" src="https://github.com/kang-kibong/kang-kibong/assets/33623123/2acbd044-1698-4ffe-bc1b-bc4e0b9c2ae3">

ESLint가 `@components/Button.tsx` 모듈의 경로를 찾지 못하고 있었습니다.
그 이유는 **alias reslover**가 제대로 설정되지 않아 생긴 문제였다고 판단하였습니다.
때문에 두가지의 플러그인인 `eslint-plugin-import`와 `eslint-import-resolver-alias`가 필요하다고 생각되어 설치를 진행했습니다.
설치가 완료된 후 `.eslintrc`에서 **import/resolver/alias** 부분에 각 절대경로에 해당하는 aslias를 따로 지정해주어야 인식할 수 있기에 다음과 같이 작성해보았습니다.

```json
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["react-app", "eslint:recommended", "plugin:import/typescript", "airbnb", "prettier"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-var": "error",
"no-multiple-empty-lines": "error",
"no-console": ["error", { "allow": ["warn", "error", "info"] }],
"eqeqeq": "error",
"dot-notation": "error",
"no-unused-vars": "error",
"react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }],
"import/extensions": ["error", "ignorePackages"]
},
"settings": {
**"import/resolver": {
"alias": {
"map": [
["@components", "./src/components"]
],
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}**
}
}
```
<img width="391" alt="스크린샷 2024-06-26 오후 5 47 23" src="https://github.com/kang-kibong/kang-kibong/assets/33623123/0af50065-124e-41d0-87e9-0d5302688883">

절대경로를 통해 발생한 ESLint가 사라진 것을 확인할 수 있었지만, 에디터를 닫고 다시 열어보니 같은 이슈가 발생하였습니다.

솔직히 이유를 잘 모르겠습니다.

구글링해본 결과 일단 `rules`에 `"import/no-unresolved": "off”`하면 해결할 수 있다고 하여 작성해놓은 상태입니다.

이 이슈를 해결할 수 있는 방안은 무엇일까요?

Choose a reason for hiding this comment

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

2번 문제는 import/no-unresolved": "off” 제거하더라도 에러는 발생안하고 있어서 해결된 거 같기도 한데 맞을까요?


### 3. Emotion의 styled 작성은 어떤것을 선호하시나요?

css-in-js인 만큼 자바스크립트 안에 스타일 코드를 작성할 수 있다는 점에서 장점이있다고 생각합니다.

하지만 책임분리를 생각해보면 스타일만 책임을 갖는 파일로 분리하는 것이 좋을지 아니면 컴포넌트 하단에 스타일 코드를 작성해야하는지 궁금합니다.

개인적으로 저는 컴포넌트 코드를 확인하면서 스타일링 작업을 해야되서 위, 아래로 자주 스크롤하는 것이, 생각보다 개발 효율이 안좋아서 책임 분리라는 이유로? 다음과 같이 스타일 코드 파일을 분리하여 작업하고 있습니다.
```json
Button
├── Button.styled.ts
└── Button.tsx
```

보통 어떤식으로 하는지 궁금합니다! 정답이란게 있을까요?

Choose a reason for hiding this comment

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

책임 분리를 통해 얻는 이점이 무엇인지 명확히 할 필요가 있겠습니다. 어떤 이점이 있을까요?


### 4. Emotion의 babel-plugin을 사용하는 이유는 무엇인가요?

스타일을 압축 및 호이스팅하여 최적화하고 souce map및 label로 더나은 개발 경험을 생성하는 플러그인을 원하면 권장한다고 합니다.

해당 내용에 대해서 잘 이해가 가지 않아 고민입니다!

Choose a reason for hiding this comment

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

혹시 https://emotion.sh/docs/@emotion/babel-plugin 내용 읽어보셨을까요?


### 5. tailwindcss와 css-in-js에서의 고민

요즘 채용공고를 보면 이전과는 다르게 심심치않게 tailwindcss를 요구하는 회사가 많아지고 있다는 것을 느꼈습니다.

이러한 동향이 발생된 멘토님의 개인적인 이유를 들어보고 싶습니다.

개인적으로 tailwindcss는 inline css와 같이 클래스명 내에서 스타일링할 수 있다는 점에서 유지보수하기 힘들 것 같다는 생각에 평소 css-in-js를 많이 사용하는 것 같습니다.

성능 차이에서일까요? 아니면 편의성때문일까요? 두 라이브러리에 대한 차이에 대해서도 궁금합니다.
Copy link

@taehwanno taehwanno Jun 30, 2024

Choose a reason for hiding this comment

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

혹시 Utility-First Fundamentals 읽어보셨을까요? 읽어보신 뒤의 병현 님 생각도 궁금합니다. 추가로 CSS-in-JS, 무엇이 다른가요? 글도 추천드립니다.

Copy link
Author

Choose a reason for hiding this comment

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

tailwindcss와 css-in-js 의 선택은 프로젝트의 요구사항팀의 선호도에 따라 달라질 수 있다는 생각이 들었습니다.

tailwindcss의 장점은 클래스명에 대해 고민할 필요가 없고, 제공하는 유틸리티 클래스를 사용하여 반응형 디자인과 이벤트 처리를 더욱 간결하게 작성할 수 있다는 점인 것 같습니다. 때문에 기존 CSS를 사용하면 길어지는 코드를 획기적으로 줄일 수 있는점과 css-in-js와는 다르게 모든 클래스를 빌드시간에 생성하기 때문에 성능면에서 좋다는 생각이 들었습니다. 그러나 러닝 커브가 존재하기 때문에 팀원 모두가 사용법에 대해 숙지해야 한다는 점이 있는 것 같습니다.

css-in-js, 특히 styled-components는 동적으로 스타일링하기에 최적화되어 있있는 것 같고 낮은 러닝 커브가 장점인 것 같습니다.
그러나 런타임에서 스타일을 생성하기 때문에 성능 저하가 발생할 수 있다는 점이 단점인 것 같습니다.
최근에는 이를 해결하기 위해 zero-runtime css-in-js 라이브러리가 등장하고 있다는 점을 알게되었습니다.


### 6. lint-staged, husky 현업에서 많이 사용하고있나요?

eslint와 prettier를 공부하던 중 lint-staged와 huksy에 대해서 알게되었습니다.

이번 과제에서도 적용해보았지만, 이를 고려하면 git hook을 통해 포맷팅와 린팅을 자동화 시킬 수 있다는 점이 장점이라 생각되어 다른 프로젝트에서도 평소 사용하고 있는 편입니다.

현업에서도 많이 쓰이는 기술일까요? 아니면 이것도 필요에 따라 설치하는 편인가요?

Choose a reason for hiding this comment

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

보통 많이 씁니다. 커밋할 때 eslint, prettier 적용하고 CI에서 잘 적용됐는지 eslint, prettier 실행해서 체크하는 과정을 거치게 되는데 적용하지 않으면 CI에서 깨질 수 있으니까요.


### 7. 폴더 구조에는 정답이란게 있을까요?

코드를 작성하다보면 분리를 할 수 있는 상황이 되는데요. 이럴때마다 어떤 폴더로 관리해야되는지 감이 잘 안오는 것 같습니다.

그 이유를 생각해보니 React가 라이브러리라는 특성을 가진 만큼 규격이 딱히 정해져 있지 않다보니 사람마다 천차만별로 관리하는 것 같다고 생각해서인 것 같습니다.

이번 과제에서는 기능에 따라 패턴을 잡아봤습니다.

혹시 정답이란게 있을까요? 혹은 최근 많이 사용되어지고 있는 패턴이 있을까요?

Choose a reason for hiding this comment

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

아래 글들 읽어보시고 한번 병현님 생각 전달해봐주시겠어요?

  1. 파일 구조
  2. Colocation

Copy link
Author

Choose a reason for hiding this comment

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

일단 “폴더 구조에 대한 정답은 없다.”인 것 같습니다.

그러나 도움이 되는 방법 중 하나는 colocation을 적용하는 것인 것 같습니다.

처음에는 관련된 기능을 하나의 폴더에 모아 작업을 진행하다가, 점차 프로젝트가 커지면 관련된 파일들을 가능한 한 가까운 곳에 배치하는 것이 좋다는 것으로 이해했습니다.

이후에는 특정 기능을 수정할 때 수정해야 할 파일이 어디에 있는지 명확하게 예측할 수 있기 때문에 시간이 단축되고 작업 용이성이 향상될 수 있다는 생각이 들었습니다!

93 changes: 91 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,91 @@
# react-gift-react-foundation
FE 카카오 선물하기 1주차 과제: React 기초
# 1️⃣ 1주차 프로젝트 세팅 & 컴포넌트 - React 입문
## ⚙️ 1단계 - 프로젝트 세팅
### 📄 기능 목록
- [x] CRA 기반 TypeScript 프로젝트 생성
- [x] 절대 경로 설정
- [x] prettier 설치 및 룰 설정
- [x] eslint 설치 및 eslint-config-airbnb 룰 설정
- [x] lint-staged, husky 설치 및 자동화 설정
- [x] emotion 스타일 라이브러리 설치
- [x] reset css 적용
- [x] .gitignore 추가
- [x] 불필요한 코드 및 파일 정리
- [x] 폴더 구조 생성
- apis: Axios 인스턴스 설정 파일 등 API 관련 설정 파일을 관리합니다.
- assets: 이미지, 폰트, 아이콘 등의 정적 파일을 관리합니다.
- styles: 글로벌 스타일 설정 파일입니다. 기본 스타일을 재설정하거나 공통 스타일을 정의합니다.
- components: 컴포넌트를 모아놓은 디렉토리입니다.
- common: 공통 컴포넌트를 모아놓은 디렉토리입니다.
- hooks: 커스텀 훅을 모아놓은 디렉토리입니다.
- pages: 페이지 컴포넌트를 모아놓은 디렉토리입니다. 각 페이지는 일반적으로 라우팅의 엔드포인트가 됩니다.
- store: 애플리케이션의 전체 상태 관리를 위한 스토어 파일입니다.
- utils: 유틸리티 함수들을 모아놓은 파일입니다.
- constants: 애플리케이션 전반에서 사용되는 상수들을 정의합니다.

## 📕 2단계 - Storybook을 사용하여 재사용 가능한 컴포넌트 구현
### 📄 기능 목록
- [x] Stroybook 설치
- [x] Button 컴포넌트 구현
- [x] theme props에 따른 버튼 컬러와 디자인이 다르게 구현
- [x] size props에 따른 버튼의 크기를 다르게 구현(value가 responsive인 경우 미디어 쿼리에 따라 사이즈가 다르게 구현)
- [x] Button 기본 속성들을 모두 사용할 수 있게 Storybook 구현
- [x] Input 컴포넌트 구현
- [x] disabled props에 따른 비활성화 및 디자인 구현
- [x] invalid props에 따른 값이 잘못되었음을 디자인하도록 구현
- [x] size props에 따라 버튼의 크기를 다르게 구현(value가 responsive인 경우 미디어 쿼리에 따라 사이즈가 다르게 구현)
- [x] Input 기본 속성들을 모두 사용할 수 있게 구현
- [x] Image 컴포넌트 구현
- [x] ratio props에 따른 이미지 비율을 설정할 수 있도록 구현(value가 number로 16/9로 넘겨진 경우 16:9비율로 보여짐, square을 설정한 경우 정사각형으로 보여짐)
- [x] raduis props에 따른 모서리를 둥글게 구현(value가 number인 경우 number만큼 모서리가 둥글게 적용, circle인 경우 원형으로 보여짐)
- [x] Img 기본 속성들을 모두 사용할 수 있게 구현
- [x] GoodsItem 컴포넌트 구현
- [x] Default 형태와 Ranking 형태의 컴포넌트를 각각 구현 (자세한 디자인은 스토리북 참고)
- [x] 공통으로 imageSrc, subtitle, title, amount Props를 넘겨 받음
- [x] Ranking 컴포넌트의 경우 rankingIndex Props를 추가로 넘겨 받음. 1~3까지는 분홍색, 나머지 숫자에는 회색의 랭킹 뱃지가 보여짐
- [x] Container 컴포넌트 구현
- [x] Container 스토리북 구현
- [x] FullScreen 스토리북 구현
- [x] Grid 컴포넌트를 구현
- [x] NumberColumns 스토리북 구현
- [x] ResponsiveColumns 스토리북 구현


## 🤔 3단계 - 질문의 답변을 README에 작성
### 질문 1: Webpack은 무엇이고 어떤 역할을 하고 있나요?

Webpack은 모듈 번들러로, 여러 개의 파일과 그 파일들 간의 종속성을 하나의 파일이나 여러 개의 파일로 묶어서 웹 애플리케이션에 필요한 리소스를 효율적으로 제공합니다.

### Webpack의 주요 역할:

1. **번들링:** 여러 자바스크립트 파일을 하나 또는 여러 개의 번들로 결합하여 최적화합니다. 이를 통해 네트워크 요청 수를 줄이고 로딩 시간을 단축할 수 있습니다.
2. **모듈 의존성 관리:** 파일 간의 종속성을 분석하고 올바른 순서로 결합하여 코드를 모듈화하고 관리하기 쉽게 만듭니다.
3. **로드 및 변환:** 로더를 사용해 다양한 파일 형식을 처리합니다. 예를 들어, Babel 로더를 사용해 최신 자바스크립트 코드를 브라우저가 이해할 수 있는 코드로 변환합니다.
4. **플러그인 시스템:** 플러그인을 통해 번들링 과정 중 파일 크기 압축, 코드 스플리팅, 핫 모듈 교체(HMR) 등의 작업을 수행할 수 있습니다.

### 질문 2: 브라우저는 어떻게 JSX 파일을 읽을 수 있나요?

브라우저는 기본적으로 JSX 파일을 직접 읽을 수 없습니다. JSX는 JavaScript의 확장 문법으로, 이를 일반 JavaScript 코드로 변환해야 합니다.

### 변환 과정:

1. **Babel:** JSX를 JavaScript 코드로 변환합니다. Babel은 JSX 문법을 React.createElement() 함수 호출로 변환하여 브라우저가 이해할 수 있는 순수 JavaScript 코드로 바꿉니다.
2. **Webpack과 Babel 통합:** Webpack의 Babel 로더를 사용해 프로젝트의 모든 JSX 파일을 JavaScript로 변환합니다. Webpack은 종속성을 분석하고, Babel을 사용해 JSX 파일을 변환한 후 번들링합니다.
3. **번들된 JavaScript 파일:** 최종적으로 변환된 JavaScript 코드는 하나의 번들 파일로 묶여 브라우저에서 실행됩니다.

### 질문 3: React에서 상태 변화가 생겼을 때 어떻게 변화를 알아챌 수 있나요?

React는 상태 변화(state change)를 감지하고, 이에 따라 컴포넌트를 업데이트합니다. 상태 변화가 발생했을 때 변화를 알아채는 메커니즘은 다음과 같습니다:

1. **setState 또는 useState:** 클래스 컴포넌트에서는 `this.setState`를, 함수형 컴포넌트에서는 `useState`를 사용해 상태를 업데이트합니다.
2. **상태 변화 감지:** `setState` 또는 `useState`를 호출하면 React는 상태 변경을 감지합니다. 이전 상태와 새로운 상태를 비교하여 실제로 변경이 발생했는지 확인합니다.
3. **리렌더링:** 상태 변화가 감지되면 해당 컴포넌트와 자식 컴포넌트가 다시 렌더링됩니다. React는 가상 DOM을 사용해 새로운 상태를 반영한 가상 DOM 트리를 생성하고, 이전 가상 DOM과 비교하여 실제 DOM에서 변경이 필요한 부분만 업데이트합니다.
4. **최적화 기법:** React는 불필요한 리렌더링을 방지하기 위해 `shouldComponentUpdate`, `React.memo`, `useMemo`, `useCallback` 등을 사용하여 변경된 부분만 효율적으로 업데이트합니다.

## 🛠️ 코드 리뷰 반영
### 📄 요구 사항
- [x] babel-preset-react-app 설치
- [x] package.json의 eslintConfig 제거
- [x] testing library와 typescript 패키지 devdependencies로 변경
- [x] README에 초기 폴더 구조에 대한 설명 기재
- [x] lint 대상 변경
- [x] QUESTION.md 추가
17 changes: 17 additions & 0 deletions craco.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const path = require('path');

module.exports = {
webpack: {
alias: {
'@': path.resolve(__dirname, 'src/'),
'@components': path.resolve(__dirname, 'src/components'),
'@styles': path.resolve(__dirname, 'src/styles'),
'@apis': path.resolve(__dirname, 'src/apis'),
'@assets': path.resolve(__dirname, 'src/assets'),
'@hooks': path.resolve(__dirname, 'src/hooks'),
'@pages': path.resolve(__dirname, 'src/pages'),
'@store': path.resolve(__dirname, 'src/store'),
'@utils': path.resolve(__dirname, 'src/utils'),
},
},
};
Loading