$ git clone https://github.com/PI304/PI_WEB.git
$ cd PI_WEB
$ yarn install$ yarn devโโโ @types
โย ย โโโ base.d.ts
โย ย โโโ index.d.ts
โย ย โโโ main.d.ts
โย ย โโโ seo.d.ts
โย ย โโโ shared.d.ts
โย ย โโโ styled.d.ts
โย ย โโโ team.d.ts
โย ย โโโ value.d.ts
โย ย โโโ work.d.ts
โโโ components
โย ย โโโ layouts
โย ย โโโ pages
โย ย โย ย โโโ main
โย ย โย ย โโโ team
โย ย โย ย โโโ value
โย ย โย ย โโโ work
โย ย โโโ seo
โย ย โโโ shared
โโโ constants
โย ย โโโ index.ts
โย ย โโโ paths.ts
โย ย โโโ seo.ts
โโโ hooks
โโโ modules
โโโ pages
โย ย โโโ _app.tsx
โย ย โโโ _document.tsx
โย ย โโโ index.tsx
โย ย โโโ main.tsx
โย ย โโโ team.tsx
โย ย โโโ value.tsx
โย ย โโโ work.tsx
โโโ public
โโโ styles
โย ย โโโ colors.ts
โย ย โโโ devices.ts
โย ย โโโ fonts.ts
โย ย โโโ global.ts
โย ย โโโ index.ts
โย ย โโโ reset.ts
โย ย โโโ sizes.ts
โย ย โโโ styled.ts
โย ย โโโ svgs.tsx
โโโ next-env.d.ts
โโโ next.config.js
โโโ tsconfig.json
โโโ README.md
โโโ package.json
โโโ yarn.lock
- ๋ชจ๋ type ์ ์ธ์ ์ด๊ณณ์์ ํด์ฃผ์ธ์.
- ํ์ผ ์ด๋ฆ์ *.d.ts ํ์์ ์ง์ผ์ฃผ์ธ์.
- import๊ฐ ํ์ํ ํ์ ์ ์ธ ์์๋ @types/index.d.ts ํ์ผ์ ์ ์ธํด์ฃผ์ธ์.
PLEASE DO NOT - ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ํ์ผ์์ ํ์ ์ ์ธ
- components/layouts - ๋ ์ด์์ ์ปดํฌ๋ํธ
- components/pages - ๊ฐ page์ ์ต์์ ์ปดํฌ๋ํธ ๋ฐ ํด๋น page์์ ์ฌ์ฉ๋๋ ํ์ ์ปดํฌ๋ํธ
- components/seo - CustomHead ๋ฑ SEO์ ์ฌ์ฉ๋๋ ์ปดํฌ๋ํธ
- components/shared - ๊ธฐํ ๊ณต์ฉ ์ปดํฌ๋ํธ
- components/... - ์ถํ ์ถ๊ฐ๋ ์ ์์ต๋๋ค.
- ์ค์ํ ์์๋ ์ด๊ณณ์์ ๊ด๋ฆฌํด์ฃผ์ธ์. (์: paths, seo...)
- ์ค์ํจ์ ๊ธฐ์ค (1๊ฐ ์ด์ ์ถฉ์กฑ ์ ์ค์ํ๋ค๊ณ ํ๋จ)
- 2๋ฒ ์ด์ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ (์ฌ์ฌ์ฉ)
- ์ถํ ๋ ผ์์ ์ํด ๋ณ๊ฒฝ๋ ์ ์๋ ๊ฒฝ์ฐ (์ถ์ ์ฉ์ด)
- ๊ธฐํ ์ฌ์ ๋ก ์ค์ํ๋ค๊ณ ํ๋จํ๋ ๊ฒฝ์ฐ
custom hook์ ์ด๊ณณ์ ์์ฑํด์ฃผ์ธ์.
์ถํ Redux ๊ด๋ จ ํ์ผ๋ค์ด ๋ค์ด๊ฐ๋๋ค.
๋ผ์ฐํฐ ์ค์ ์ ์ํ Next.js ์์ฝ ๋๋ ํ ๋ฆฌ์ ๋๋ค.
์ด๋ฏธ์ง ๋ฑ asset์ public/assets ์ ์ ์ฅํด์ฃผ์ธ์.
์ฐธ๊ณ - SVG๋ ํ์ผ๋ก ์ ์ฅํ์ง ์๊ณ , styles/svgs.tsx์ ์์๋ก ์ ์ํ์ฌ ๊ด๋ฆฌํฉ๋๋ค.
- styles/colors.ts - ๋์์ธ ์ปฌ๋ฌ
- styles/devices.ts - ๋ฐ์ํ ์คํ์ผ์ ์ํ ๋๋ฐ์ด์ค ๊ตฌ๋ถ ๊ธฐ์ค ๋ฑ
- styles/fonts.ts - ๋์์ธ ํ์ดํฌ๊ทธ๋ํผ
- styles/global.ts - ์ ์ญ ์คํ์ผ
- styles/reset.ts - ๋ฆฌ์ ์คํ์ผ
- styles/styled.ts - ์ค์ํ Styled-components (1๋ฒ ์ด์ ์ฌ์ฌ์ฉ OR ์ถ์ ์ฉ์ด)
- styles/svgs.tsx - SVG ์ ์
๊ฐ ๋๋ ํ ๋ฆฌ์๋ index.ts๊ฐ ์์ต๋๋ค.
// components/shared/index.ts
export * from './ContactWidget';
export * from './Navigator';
export * from './SpaceBackground';๋๋ ํ ๋ฆฌ ๋ด๋ถ์ ํ์ผ๋ค์ ํ๊บผ๋ฒ์ ๋ชจ์ ๋ค์๊ธ Re-Export ํ์ฌ,
๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ํ์ผ์์ ์๋์ ๊ฐ์ด ๋๋ ํ ๋ฆฌ๋ช
๋ง์ผ๋ก Import ํ๊ธฐ ์ํจ์
๋๋ค.
// components/layouts/WithNavigatorLayout.tsx
import { Navigator, ContactWidget } from '../shared';์ปดํฌ๋ํธ๋ฅผ ๊ฐ๊ฐ Importํ๋ ๊ฒ์ ๋นํ์ฌ Import ๋ฌธ์ ์งง๊ฒ ๊ด๋ฆฌํ ์ ์๊ณ ,
์ถํ ์ปดํฌ๋ํธ ํ์ผ ์ด๋ฆ์ด ๋ฐ๋๋ ๊ฒฝ์ฐ์ ๋์ํ๊ธฐ ์ฉ์ดํ๋ค๋ ์ด์ ์ด ์์ต๋๋ค.
export * from './์ปดํฌ๋ํธ๊ฒฝ๋ก' ํ์์ผ๋ก ํ์ผ์ Re-Export ํ๊ธฐ ์ํด์๋,
์ปดํฌ๋ํธ ํ์ผ์์ ์ปดํฌ๋ํธ๋ฅผ Default Export๊ฐ ์๋ Named Export๋ก ๋ด๋ณด๋ด์ฃผ์ด์ผ ํฉ๋๋ค.
๋ฐ๋ผ์ ์ปดํฌ๋ํธ๋ ํญ์ Named Export ํ์์ผ๋ก ๋ด๋ณด๋ด์ฃผ์๊ณ , ํด๋น ๋๋ ํ ๋ฆฌ์ index.ts์์ ์์ ๊ฐ์ด Re-Export ํด์ฃผ์ธ์.
์๋๋ ์๋ชป๋ ์์์ ์ฌ๋ฐ๋ฅธ ์์์ ๋น๊ต์ ๋๋ค.
// ์๋ชป๋ ์์ (Default Export)
export default function Component() {
return <></>;
}
// ์๋ชป๋ ์์ (Default Export)
const Component = () => {
return <></>;
};
export default Component;
// ์๋ชป๋ ์์ (Named Export + ์ผ๋ฐ ํจ์)
export function Component() {
return <></>;
};// ์ฌ๋ฐ๋ฅธ ์์ (Named Export + ํ์ดํ ํจ์)
export const Component = () => {
return <></>;
};PR์ ํตํด Feature ๋ธ๋์น๋ค์ Develop์ ๋จธ์งํ๊ณ ,
์ต์ข
๋ฐฐํฌํ ์๊ธฐ๊ฐ ๋๋ฉด Admin ๊ด๋ฆฌ์๊ฐ Develop ๋ธ๋์น๋ฅผ Production ๋ธ๋์น์ ๋จธ์งํ์ฌ ๋ฐฐํฌํ๋ ๋จ์ํ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฆ
๋๋ค.
- ๋ก์ปฌ์ Cloneํ ๋ ํฌ์์ Feature ๋ธ๋์น๋ฅผ ์์ฑํ์ฌ ์์ ํฉ๋๋ค.
- ๊ฐ๋ฐ์ด ๋๋ฌ๋ค๋ฉด ๋ค์ ํ๋ฒ ์๊ฒฉ ๋ ํฌ์ ์ต์ ์ปค๋ฐ์ ๋ฐ์์์ค๋๋ค.
// ์ฒดํฌ์์ ํ๊ธฐ ์ , Feature ๋ธ๋์น์์์ ์์
๋ด์ฉ์ ์ปค๋ฐํด์ผ ํฉ๋๋ค.
$ git checkout develop
$ git pull origin develop- ์ถ๊ฐ๋ ์ต์ ์ปค๋ฐ์ด ์๋ค๋ฉด ๋ด๊ฐ ์์ ํ Feature ๋ธ๋์น๋ฅผ, ์๋ก์ด ์ปค๋ฐ์ด ์ถ๊ฐ๋ Develop ๋ธ๋์น์ ๋ง์ง๋ง ์ปค๋ฐ์ผ๋ก Rebase ํฉ๋๋ค. (๋ง๊ทธ๋๋ก base๋ฅผ ๋ฐ๊พผ๋ค๋ ๋ป์ ๋๋ค)
$ git checkout Feature/[๋ธ๋์น๋ช
]
$ git rebase develop- ์ถฉ๋์ด ๋ฐ์ํ๋ค๋ฉด, ์๋ํฐ์์ ์ถฉ๋์ ํด๊ฒฐํ ๋ค ์๋ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํฉ๋๋ค.
$ git add .
$ git rebase --continue- ์ด์์ด ์๋ค๋ฉด Feature ๋ธ๋์น๋ฅผ push ํฉ๋๋ค.
$ git push origin Feature/[๋ธ๋์น๋ช
]- Github์์ PR์ ์์ฑํฉ๋๋ค. PR ์ ๋ํ๋๋ ํ ํ๋ฆฟ์ ์ฑ์์ฃผ์ธ์.
## Feature Description
- ์ด๋ฐ ์ด๋ฐ ๊ธฐ๋ฅ์
๋๋ค
## To Reviewers
- ์ด๋ฐ ์ด๋ฐ ์ ์ ์ ์ํด์ฃผ์ธ์-
Review ๊ณผ์ ์ ๊ฑฐ์นฉ๋๋ค.
-
Self Merge ํด์ฃผ์ธ์.
-
Squash Merge๋๋ฉฐ, Merge๋ Feature Branch๋ ์๋ ์ญ์ ๋ฉ๋๋ค.
-
๋ก์ปฌ์์ Develop ๋ธ๋์น๋ก ์ฒดํฌ์์ํ ๋ค Pullํ๊ณ , ์๋ก์ด Feature ๋ธ๋์น๋ก ๋ถ๊ธฐํ์ฌ ๋ค์ ์์ ์ ์งํํด์ฃผ์ธ์.
- PR ์ sookyeongyeom์ Reviewer๋ก ์ง์ ํฉ๋๋ค.
- ์์ ์ด ํ์ํ๋ฉด Request Changes๋ก ์ฝ๋ ์์ ์ ์์ฒญ๋๋ฆฝ๋๋ค.
- ์ด์์ด ์์ผ๋ฉด Approve ํฉ๋๋ค.
- Approve๋ PR์ ์ฝ๋์์ฑ์๊ฐ Self Merge ํฉ๋๋ค.
Feature/[๊ธฐ๋ฅ์์ฝ]
- ๋งจ ์ฒซ๊ธ์ F๋ง ๋๋ฌธ์๋ก, ๊ธฐ๋ฅ์์ฝ์ ์๋ฌธ์๋ก ์์ฑํด์ฃผ์ธ์
- ๊ธฐ๋ฅ์์ฝ์ ์์ด๋ก ์์ฑํด์ฃผ์ธ์
ex) Feature/modal-publishing
<ํ๊ทธ>: <์ ๋ชฉ>
- : ๋ค์๋ง ๋์ด์ฐ๊ธฐ๊ฐ ์์ต๋๋ค
- ์ ๋ชฉ์ ํ์ ํผ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค (๊ฐ๊ธ์ ์์ด๋ก)
- ํ๊ทธ์ ์ฒซ๊ธ์๋ ๋๋ฌธ์๋ก ์์ฑํด์ฃผ์ธ์
- ํ๊ทธ๋ ์๋์ ์ ํ ๊ฒ๋ค๋ง ์ฌ์ฉํด์ฃผ์ธ์
Feat: ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ, ๊ธฐ๋ฅ ๋ก์ง ๋ณ๊ฒฝ
Fix: ๋ฒ๊ทธ ์์
Refactor: ์ฝ๋ ๋ฆฌํฉํ ๋ง (๊ธฐ๋ฅ ๋ณํ X)
Style: ์ฝ๋ ํฌ๋งทํ
, ์ฝ๋ ๋ณ๊ฒฝ์ด ์๋ ๊ฒฝ์ฐ
Chore: ๋น๋ ์
๋ฌด ์์ , ํจํค์ง ๋งค๋์ ์์
Docs: ๋ฌธ์ ์์ , ์ฃผ์
EsLint Rule์ ์์๋ก ํด์ ํ์ง ๋ง์์ฃผ์ธ์.
- Props Type ์ ์ธ ์ Type์ ์ฌ์ฉํด์ฃผ์ธ์. (Interface X)
- Props Type์ ์ด๋ฆ์ [์ปดํฌ๋ํธ์ด๋ฆ]+Props ์ ํ์์ผ๋ก ์ง์ด์ฃผ์ธ์.
type HeaderProps = {
onOpenDrawer: (e: React.MouseEvent) => void;
};
type PublicationBoxElementProps = {
title: string;
writer: string;
img: string;
pdf: string;
};- Interface ์ ์ธ ์, ํด๋์ค์ ์ธํฐํ์ด์ค๋ก ์ฌ์ฉํ ๋ชฉ์ ์ด ์๋๋ผ๋ฉด ์ ๋์ฌ I๋ฅผ ์ฌ์ฉํ์ง ๋ง์์ฃผ์ธ์.
๊ฐ์ฒด๋ก ์ ์ํ๋, as const ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ read-only ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ฃผ์ธ์.
export const Paths = {
new: '/new',
newComplete: '/new/complete',
main: '/main',
reply: '/reply',
replyComplete: '/reply/complete',
view: '/view',
} as const;styled-components ๋ฅผ ์ํ Props Type ์ ์ธ ์ ์ผ๋ฐ ์ปดํฌ๋ํธ์ Props Type์ฒ๋ผ ๋ณ๊ฐ๋ก ์ ์ธํ์ง ์๊ณ , ์๋์ ๊ฐ์ด ์ ์ธํฉ๋๋ค. (์ถํ ์ฌ์ฌ์ฉ ์ฉ์ด)
// ์๋ชป๋ ์์
// @types/styled.d.ts
type FAQBoxProps = {
isOpen: boolean;
};
// components/FAQBox.tsx
export const FAQBox = styled.div<FAQBoxProps>`
opacity: ${(props) => (props.isOpen ? 1 : 0)};
`;// ์ฌ๋ฐ๋ฅธ ์์
// @types/styled.d.ts
type IsOpenType = {
isOpen: boolean;
};
// components/FAQBox.tsx
export const FAQBox = styled.div<IsOpenType>`
opacity: ${(props) => (props.isOpen ? 1 : 0)};
`;// Type ์กฐํฉ ์์
// @types/styled.d.ts
type IsOpenType = {
isOpen: boolean;
};
type IsFixedType = {
isFixed: boolean;
};
// components/FAQBox.tsx
export const FAQBox = styled.div<IsOpenType & IsFixedType>`
opacity: ${(props) => (props.isOpen ? 1 : 0)};
opacity: ${(props) => props.isFixed && 1};
`;styled-components๋ ์ฌ์ฉ๋๋ ์ปดํฌ๋ํธ ํ์ผ ๋ด๋ถ์ ์์ฑํ๋, namespace S ์์ ์ ์ํ์ฌ ์ฃผ์ธ์. ์ผ๋ฐ ์ปดํฌ๋ํธ์ ์ฝ๊ฒ ๊ตฌ๋ถํ๊ธฐ ์ํจ์ ๋๋ค.
// ์ปดํฌ๋ํธ ํ์ผ
return (
<S.Container>
<S.Wrapper isFocus={isFocus} isError={false}>
<input
placeholder={placeHolder}
onFocus={onFocus}
onBlur={onBlur}
value={value}
onChange={onChange}
/>
</S.Wrapper>
<IconButton svgIcon={svgCircleX} onClick={onClickRemove} />
</S.Container>
);
}
namespace S {
export const Container = styled.div`
display: flex;
align-items: center;
gap: 1.15rem;
padding-right: 0.75rem;
flex-grow: 1;
`;
export const Wrapper = styled.div`
display: flex;
align-items: center;
gap: 1.15rem;
padding-right: 0.75rem;
flex-grow: 1;
`;
}์ด์ ์ ์ฌํ๊ฒ, ์ฌ์ฌ์ฉํ styled-components๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํฉ๋๋ค.
// styles/styled.ts
export namespace SC {
export const HeaderContainer = styled.header`
background: ${Colors.white};
border-bottom: 0.1rem solid ${Colors.gray200};
height: ${Styles.headerHeight};
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 2.4rem;
`;
export const HeaderLogo = styled.h1``;
export const NewMainContainer = styled.div`
background-color: ${Colors.white};
border-radius: 0.8rem;
border: 0.1rem solid ${Colors.gray200};
padding: 4rem;
`;
}1rem = 10px๋ก ์ค์ ํด๋ ์ํ์
๋๋ค.
px์ด ์๋ rem์ ์ฌ์ฉํด์ฃผ์ธ์.