$ 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μ μ¬μ©ν΄μ£ΌμΈμ.