
프로젝트를 진행하면서 미리 만들어둔 템플릿 덕분에
커밋 컨벤션과브랜치 컨벤션은 비교적 잘 지키면서 작업할 수 있었다.
하지만코드 컨벤션에 대해서는 템플릿에서 언급하지 않았고, 별도로 정하지 않다 보니 개인적인 코드에서는 일관성이 유지되었지만, 전체 코드를 모아보면 통일성이 부족하고 혼란스러운 구조가 될 가능성이 있었다.
이런 문제를 방지하려면코드 컨벤션을 명확하게 정의하고, 이를 프로젝트에서 지속적으로 적용하는 것이 중요하다.
코드 컨벤션을 지키면서 개발하면 팀원들 간의 가독성이 높아지고, 다른 사람이 코드를 볼 때도 직관적으로 이해하기 쉬운 코드가 될 것이다.
• Airbnb JavaScript 스타일 가이드 (JavaScript/TypeScript)
• Google JavaScript 스타일 가이드
• Microsoft TypeScript 스타일 가이드
처음 세팅 작업을 할 때 해야할 목록들을 살펴보자.
- 프로젝트 구축
- 브랜치 전략
- 코드 컨벤션
- 브랜치 컨벤션
- 커밋 컨벤션
프로젝트 구축
프로젝트 세팅에 있어서 해야할 것 들을 아래로 정리할 수 있다.
폴더 생성 (
components, assets, hooks, pages, styles, api)
components: 공동 컴포넌트(재사용 컴포넌트)에 대한 폴더이다.assets: 아이콘, 이미지파일에 대한 폴더이다.hooks:hook에 관련된 폴더이다.pages: 페이지 컴포넌트에 대한 폴더이다.styles:styled-components를 사용한다면styled-components에 대한 폴더 / CSS를 사용한다면 CSS에 대한 폴더가 된다.api:api 리퀘스트 함수및데이터 통신에 대한 코드들이 모여있는 폴더이다.
위 폴더들은src 폴더안에 생기는 폴더이다.
reset.css
reset.css부분은 사실 부족한 면이 없지 않아있다. 버튼을 만드는데 CSS가 초기화 되어 있지 않아 CSS 코드를 추가해야하는 일이 생겼고 이런 부분에 있어서는reset.css도 만들지만
Custom.css를 추가해주는 게 좋을 것 같다.
Custom.css에 대해서는 밑에서 자세히 살펴보자
GlobalStyle (
styled-components를 사용하려면 생성해야한다.)팀원분께서
GlobalStyle을 훌륭하게 개발해주셨지만, 몇 가지 보완할 점이 있어 문서화하였다.
1. font-size 설정에 대한 설명 부족
• 현재font-size: 62.5%가 설정되어 있어1rem = 10px로 계산된다.
2. 색상 사용 예시 부족
• 프로젝트에서 색상을 일관되게 사용하기 위해GlobalStyle에서 정의된 색상 값을 활용해야 한다.
3.reset.css import위치 개선
• 현재reset.css가App 컴포넌트에서import되고 있다.
• 하지만GlobalStyle에서import하는 것이 더 적절한 것 같다..
• 이렇게 하면스타일 초기화가GlobalStyle 내부에서 한 번에 적용되어유지보수가 용이해진다.
위 문제점들과GlobalStyle에 대한 코드설명들을 문서화 해봤다.
프로젝트 세팅 문서화
초기에
브랜치 전략을 정할 때 명확한 방향이 없었고, 팀원들의 의견이 나오지 않아 다소 모호한 상태였다.이후 멘토님의 조언으로
Git Flow 전략을 적용하는 것이 적절하다는 결론이 나왔다.
다행히 나는 이전에Git Flow 전략을 사용한 경험이 있었고, 관련 템플릿도 보유하고 있어 이를 기반으로 팀원들에게 설명했다.
덕분에 멤버들이 쉽게 이해하고 적용할 수 있었다.하지만, 초기에 브랜치 전략을 확실히 정하지 못해 프로젝트 진행 중 일부 혼선이 발생한 점이 아쉬웠다.
앞으로는 프로젝트 시작 단계에서 브랜치 전략을 명확히 수립하고, 팀원들과 논의하는 과정을 더욱 강조해야겠다.
Git Flow 전략
이후 멘토님의 조언으로
Git Flow 전략은 이렇게 진행되었다. (살짝 변형됨)
1. 메인 브랜치
- main (배포용)
- develop (개발용)
- 기능 브랜치 (Feature Branches)
Feature/이름/기능명(각자 기능 개발)- 개인 브랜치에서 기능별 브랜치를 생성 후 개발
- Pull Request & Merge 과정
- 기능 개발이 끝나면
develop 브랜치로PR→ 코드 리뷰 후병합- 최종 개발이 완료되면
develop 브랜치에서main 브랜치로 병합
그림으로브랜치 흐름으르 보자면 아래와 같을 것 같다.
문제점
PR을 생성할 때 어떤 기능을 만들었는지 리뷰어에게 유의할 점을 무엇인지 템플릿을 생성할 수 있는 파일이 있다.
해당 파일을 어떻게 생성하는지 알고 싶다면 아래사이트를 참고하자
Github PR 템플릿 생성 방법
PR생성 파일을main 브랜치에서develop 브랜치로 분기하기 전에main 브랜치에 템플릿을 적용시켜놨어야 했는데
develop 브랜치에서부터 적용시켜놓아 제대로 기능을 하지 못했다.
만약 기능이 잘되었다면 아래와 같은PR 템플릿이 나올 것이다.
프로젝트 마지막 폴더 구조는 아래와 같다.
현재 폴더 구조가 다소 세분화되어 난잡한 느낌이 있다.1. 폴더 세분화 문제
• 폴더가 지나치게 세분화되어 관리가 어렵다.
• 예를 들어, 이미지 폴더 내에 아이콘 파일들이 별도로 분리되어 있어 구조가 복잡해졌다.
2. 공동 컴포넌트 관리
• 개발 팀원별 개별 폴더를 만들어 공동 컴포넌트를 정리하면 더 체계적으로 관리할 수 있다.
3. 폴더명 변경 제안
• 서비스 폴더 → api 폴더 (더 직관적인 이름)
• 스타일 폴더 내에GlobalStyle 파일포함 (스타일 관련 파일은 한곳에서 관리)
4. 폴더 구조 개선 방향
• 너무 세분화하기보다는 적당한 수준에서 정리하여 가독성과 유지보수를 고려하는 것이 중요하다.
➡️ 적절한 폴더 구조를 유지하면서도 직관적이고 효율적인 관리가 필요하다. ✅
현재
reset.css에 다소 부족한 코드들이 있어, 여러 컴포넌트를 만들 때 불필요한 CSS 코드가 추가되는 문제가 발생했다.
개선 방향
1. Custom CSS를 생성하여 reset.css를 보완
•
Custom CSS 파일을 생성하고 부족한 초기화 스타일을Custom CSS에 작성
•reset.css에Custom CSS를import하여 적용
2. 이점
•
reset.css가 더욱 강화되어 스타일 초기화가 제대로 이루어짐
• 불필요한 CSS 코드가 줄어들어 컴포넌트 스타일의 일관성 유지
프로필카드 기능설명부분에서
subjects 프로필 데이터를 리스폰스 받아서 각프로퍼티 값에 맞게 렌더링을 시켜줄려고 했는데
위 코드처럼
옵셔널 체이닝을 사용하지 않으면 콘솔로는null 값을 받게 되고,TypeError 오류가 발생한다.
분명 콘솔로subjects 프로필 데이터를 잘 리스폰스 받은 것을 확인했는데 왜null 값을 받게되는 걸까?
null 값과 런타임오류가 발생한이유
콘솔에
null 값이 찍힌 정확한 이유는 모르지만props 명이 틀렸을 가능성이 높다.
이럴 때는
- 네이밍 잘 맞는지 체크 해보기
axios내부에서res로 한번 감싸고 있는데. 이 부분도 체크 해보기
이렇게 체크를 통해서 어떤 것이 문제인지 파악하는게 중요하다.
런타임 오류가 발생한 이유는ProfileCard 컴포넌트에서null 상태인객체에서results를 읽으려고 했기 때문에 발생했다.
위와 같은 문제를 해결하기 위해 옵셔널 체이닝을 사용하였다.
옵셔널 체이닝을 사용하는이유
subjects 프로필 데이터즉profiles가객체,배열, 또는undefined나null일때런타임 에러를 방지할 목적이다.const data = null; data.abc // 에러발생! Uncaught TypeError: Cannot read properties of null // data?.abc // undefined. 에러 발생하지 않음const data = null; data[0] // 에러발생! Cannot read properties of null (reading '0') // data?.[0] // undefined. 에러 발생하지 않음
현재 내가 작성한
Styled-component의 코드를 보면 모두 각각미디어 쿼리를 지정해주고 있다.
만약 디바이스 기준이 변경되면 모든 미디어 쿼리를 개별적으로 수정해야 하는 비효율적인 상황이 발생한다.
그렇게 된다면유지보수면에 비효율적인 상황이 생긴다.
멘토님의 코드 리뷰에 따르면, Styled-Components에서는 theme을 제공하며 이를 활용하면 중앙에서 미디어 쿼리를 관리할 수 있다.
🎯 theme 사용의 장점
•
미디어 쿼리를 한곳에서 정의하여 일관된 반응형 스타일 적용 가능
•코드 중복을 줄이고유지보수가 용이
• 디바이스 기준 변경이 필요할 때,theme에서 한 번만 수정하면 전체 적용
🛠 적용 방법 예시
1️⃣ theme.js를 생성해서
미디어 쿼리설정const theme = { breakpoints: { mobile: "max-width: 768px", tablet: "max-width: 1024px", }, }; export default theme;2️⃣
ThemeProvider 컴포넌트로전역 적용import { ThemeProvider } from "styled-components"; import theme from "./theme"; // function App() { return ( <ThemeProvider theme={theme}> {/* 전체 컴포넌트 */} </ThemeProvider> ); } export default App;3️⃣
Styled-Component에서theme활용import styled from "styled-components"; const Container = styled.div` width: 100%; @media (${(props) => props.theme.breakpoints.mobile}) { width: 90%; } `;.
적용하지 못한이유
이
반응형 디자인을 적용시키려면App 컴포넌트부터 다른 모든Styled-component를 갈아엎어야하는 상황이 나와서
이 부분은 처음 세팅할 때 미리 적용시켜놓는다면 좋을 것 같다!
현재 프로젝트에서는
styled-components외 등등은 JS 파일,
컴포넌트는 JSX 파일을 사용하고 있다.
이로 인해 JS 파일과 JSX 파일을 언제 사용하는지에 대한 궁금증이 생겼다.
✅ JS 파일 (.js)
📌 사용 목적
• 일반적인 JavaScript 코드 작성
•styled-components같은 스타일 관련 코드 정의
•유틸리티 함수, `API 호출 모듈 등 로직만 포함하는 파일예시 - ButtonStyle.js (
styled-components스타일 정의용)import styled from "styled-components"; // export const StyledButton = styled.button` background-color: blue; color: white; padding: 10px 20px; border-radius: 5px; // &:hover { background-color: darkblue; } `;.
✅ JSX 파일 (.jsx)
📌 사용 목적
• React 컴포넌트를 만들 때 사용
• JSX 문법을 포함하는 파일 (즉,HTML-like 문법을 사용)
• UI를 구성하는 컴포넌트가 포함되는 경우 JSX 사용
예시 - Button.jsx (JSX 코드 포함된 React 컴포넌트)
import React from "react"; import { StyledButton } from "./ButtonStyle"; // const Button = ({ text }) => { return <StyledButton>{text}</StyledButton>; }; export default Button;.
JS와 JSX 파일의 차이점 정리
구분 JS 파일 ( .js)JSX 파일 ( .jsx)사용 목적 스타일 정의, 로직 처리 React 컴포넌트 작성 JSX 문법 사용 ❌ 없음 ✅ 있음 파일 예시 theme.js,ButtonStyle.jsButton.jsx,Header.jsx포함 내용 styled-components, 유틸 함수, API 모듈 등HTML-like JSX 코드 포함