<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yj_y.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 09 Apr 2026 10:32:41 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>yj_y.log</title>
            <url>https://velog.velcdn.com/images/yj_y/profile/04da8e9d-a652-4c6e-bdf2-e06860d9152f/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. yj_y.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yj_y" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[TAVE 17기] Spring Boot 백엔드 스터디 4주차]]></title>
            <link>https://velog.io/@yj_y/TAVE-17%EA%B8%B0-Spring-Boot-%EC%8A%A4%ED%84%B0%EB%94%94-4%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@yj_y/TAVE-17%EA%B8%B0-Spring-Boot-%EC%8A%A4%ED%84%B0%EB%94%94-4%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Thu, 09 Apr 2026 10:32:41 GMT</pubDate>
            <description><![CDATA[<p>우리 팀은 한조각님의 강의를 듣고 각자 맡은 부분을 좀 더 집중적으로 공부해오는 시간을 가졌다! </p>
<p>강의는 아래 참고 ,, 
<a href="https://www.inflearn.com/course/%EB%B0%B1%EC%97%94%EB%93%9C-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%82%AC%EC%9D%B4%ED%81%B4/dashboard?cid=336802">Spring Boot, AWS로 백엔드 서비스 한 사이클 완성하기</a></p>
<hr>
<p>드디어 마지막 파트!! <strong>[지속적 코드 관리와 배포, CI/CD]</strong>
내가 담당한 파트는 보안 파트였다. 
우선 강의를 보면서 실습하기 바빠 내용은 나중에 이해하게 되는 ,,<br>정리해볼게요 레츠고 </p>
<h1 id="보안-강화하기">보안 강화하기</h1>
<h2 id="aws-ssm--우리가-이걸-왜-하냐면요">AWS SSM : 우리가 이걸 왜 하냐면요</h2>
<blockquote>
<p>우선, AWS SSM은 GitHub Actions가 EC2 서버에 직접 SSH로 들어가지 않고, <strong>AWS를 통해 더 안전하게 명령을 대신 실행시키는 방식</strong></p>
</blockquote>
<p>결론적으로는 개발자가 코드를 <code>main</code>에 push하면, 사람이 EC2에 접속해서 일일이 <code>docker pull</code>, <code>docker run</code> 같은 걸 치지 않아도 <strong>자동으로 새 버전이 배포되게 하는 과정!</strong> </p>
<p>그래서 우리는 서버에 실제로 반영되게 만들어봐요.</p>
<ul>
<li><p><strong>간단한 흐름</strong></p>
<p>  <strong>1단계:</strong> 개발자가 코드를 GitHub에 올림</p>
<p>  <strong>2단계:</strong> GitHub Actions가 자동으로 빌드함</p>
<p>  <strong>3단계:</strong> Docker 이미지로 만듦</p>
<p>  <strong>4단계:</strong> 그 이미지를 Docker Hub에 올림</p>
<p>  <strong>5단계:</strong> AWS 쪽에 “이 최신 이미지 받아서 서버 다시 실행해”라고 시킴</p>
<p>  <strong>6단계:</strong> EC2 서버에서 새 컨테이너가 뜸 = 배포 완료</p>
</li>
</ul>
<p>&amp;nbsp</p>
<h3 id="ssh와-ssm">SSH와 SSM</h3>
<ul>
<li><strong>SSH</strong> = 어떻게 원격 접속할까?에 대한 <strong>일반 기술/프로토콜</strong></li>
<li><strong>SSM</strong> = AWS가 제공하는 <strong>서버 관리 서비스</strong> = SSH 없이도 명령 실행, 접속, 세션 관리 등을 하게 해주는 <strong>AWS 도구</strong></li>
</ul>
<p>쉽게 비유하면,</p>
<ul>
<li>SSH는 <strong>“문 여는 방식”</strong></li>
<li>SSM은 AWS가 만든 <strong>“관리 시스템”</strong></li>
</ul>
<p>&amp;nbsp</p>
<h2 id="ssh-말고-왜-ssm을-써요">SSH 말고 왜 SSM을 써요?</h2>
<p>우선, 우리는 SSH 방식을 쓰는 실습도 해보았어요. (EC2를 <code>0.0.0.0.</code>으로 설정해봤어요.)</p>
<p>GitHub Actions가 EC2에 직접 SSH 접속해서:</p>
<ul>
<li>기존 컨테이너 stop/rm</li>
<li>최신 Docker 이미지 pull</li>
<li>docker run</li>
</ul>
<p>히지만, 이 방식은</p>
<ol>
<li><strong>GitHub Actions가 EC2에 직접 들어가야 하고</strong></li>
<li>보안그룹에서 22번 포트를 열어야 하고</li>
<li><strong>모든 IP에 대해 22번 포트를 허용</strong></li>
</ol>
<p>⇒ <strong>위험해서 운영 서버에 권장하지 않는다!</strong> </p>
<p>비유를 해보자면,</p>
<ul>
<li><strong>SSH 방식</strong>: 배달원이 우리 집 비밀번호를 가지고 직접 집 안에 들어가서 물건 놓고 감</li>
<li><strong>SSM 방식</strong>: 배달원이 관리사무소(AWS)에 맡기면, 관리사무소가 내부 직원(SSM Agent) 통해 집 안에 전달
&amp;nbsp
&amp;nbsp</li>
</ul>
<h2 id="aws-ssm">AWS SSM?</h2>
<blockquote>
<p>AWS가 서버를 원격 관리하게 해주는 서비스</p>
</blockquote>
<p>: <code>aws ssm send-command</code>가 <strong>SSM 에이전트를 통해 EC2 인스턴스에서 명령을 실행</strong>
= ⭐ EC2 안에 <strong>SSM Agent</strong>가 있어야 함⭐</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/7a810b8f-01fe-4d21-9d4f-a9aab71946e1/image.png" alt=""></p>
<p><strong>흐름도: GitHub Actions → AWS 인증 → AWS SSM → EC2 명령 실행</strong></p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/13286d5b-4a44-442c-a020-89822e54bf40/image.png" alt=""></p>
<h2 id="갑자기-등장하는-oidc">갑자기 등장하는 OIDC</h2>
<p>예전 방식은 GitHub Secrets에 AWS Access Key / Secret Key를 오래 저장해두고 인증하는 경우가 많았다.</p>
<p>대신, <strong>OIDC</strong>를 써서 <strong>GitHub Actions가 AWS에 “나 진짜 이 저장소 워크플로우 맞아”라고 증명하고, AWS가 잠깐 쓸 수 있는 임시 자격증명(STS)을 발급해주는 구조!</strong></p>
<p>비유해보자면</p>
<ul>
<li>GitHub Actions: “나 이 저장소에서 돌아가는 공식 워크플로우야”</li>
<li>AWS: “오케이, 그럼 잠깐 쓸 수 있는 출입증 줄게”</li>
<li>그 출입증으로 SSM 명령 실행</li>
</ul>
<p>우리가 작성한 코드 최상단 <code>permissions: id-token: write</code>가 <strong>OIDC를 통해 AWS 인증을 받기 위해 필요한 부분</strong></p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/f8b2ca53-2d6c-4e94-80e5-cf09d41cff68/image.png" alt=""></p>
<h1 id="스프링-프로파일">스프링 프로파일</h1>
<blockquote>
<p>환경마다 다른 설정을 나눠서 쓰기 위한 기능</p>
</blockquote>
<p>ex.  아래의 3가지 환경이 있다고 하자! </p>
<ul>
<li>개발 환경(dev)</li>
<li>테스트 환경(test)</li>
<li>운영 환경(prod)</li>
</ul>
<p>각 환경에서 <strong>DB 주소, 로그 레벨, 시크릿 값, 외부 API 주소같은 것이 다를 수 있다.</strong></p>
<p>그런데?! 한 파일에 왕창 넣어버리면 위 험 해 </p>
<p>그래서?! 어느 환경에서 도는지에 따라 설정을 다르게 적용해보자! </p>
<h3 id="왜-써요를-정리해보자면">왜 써요!를 정리해보자면</h3>
<ol>
<li><strong>개발/운영 설정 분리</strong></li>
</ol>
<p>: 개발할 때는 로컬 DB 쓰고, 운영할 때는 AWS RDS 사용 
그러면 이렇게 두 개로 나눠야 한다! </p>
<ul>
<li>dev: localhost DB</li>
<li>prod: RDS DB</li>
</ul>
<ol start="2">
<li><strong>보안 문제</strong></li>
</ol>
<p>: 운영용 비밀번호, 운영 DB 주소를 개발 설정이랑 섞어두면 위험하다. <strong>특히 GitHub에 잘못 올리면 큰일!!!!!!</strong></p>
<ol start="3">
<li><strong>배포 자동화에 유리</strong></li>
</ol>
<p>: Docker나 EC2에서 실행할 때 <code>prod</code> 프로파일로 띄우면 운영용 설정이 자동으로 적용</p>
<p>즉, <strong>같은 코드인데 실행 환경에 따라 다르게 동작</strong>하게 만들 수 있다!
&amp;nbsp
&amp;nbsp</p>
<h1 id="마무리">마무리</h1>
<p>4주만에 완강을 했다 😎
역시 스터디같은 강제성이 없으면 힘든 것 같다 ,, 그래도 이렇게 긴 강의를 끝낼 수 있어서 뿌듯하다 ! 
중간고사 끝나면 전체적으로 한 번 훑는 시간을 가져야겠다. 시간에 쫓겨 공부한 부분이 있어 살짝 아쉽 ! 
직접 해보면서 배우는 게 베스트라지만 프로젝트 시작할 생각에 걱정이 저어어어엉말 많다 ,, 
우선 다음주에 있을 미니프로젝트부터 힘내보자 껄껄 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TAVE 17기] Spring Boot 백엔드 스터디 2주차]]></title>
            <link>https://velog.io/@yj_y/TAVE-17%EA%B8%B0-Spring-Boot-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@yj_y/TAVE-17%EA%B8%B0-Spring-Boot-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 30 Mar 2026 05:12:29 GMT</pubDate>
            <description><![CDATA[<p>우리 팀은 한조각님의 강의를 듣고 각자 맡은 부분을 좀 더 집중적으로 공부해오는 시간을 가졌다! </p>
<p>강의는 아래 참고 ,, 
<a href="https://www.inflearn.com/course/%EB%B0%B1%EC%97%94%EB%93%9C-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%82%AC%EC%9D%B4%ED%81%B4/dashboard?cid=336802">Spring Boot, AWS로 백엔드 서비스 한 사이클 완성하기</a></p>
<hr>
<p>강의가 실습 위주인 것 같아 좀 더 궁금한 부분을 찾아보았다!
2주차 스터디는 Docker와 AWS !
우선 왜 하지?를 이해하지 못하면 살짝 . . 엥? 싶어져서 이번 스터디는 Why???? 위주로 찾아보았다.</p>
<p>내가 맡은 부분은 AWS였고, 가장 먼저 왜 백엔드가 AWS를 공부해야 되는지에 대해 의문을 품게 되었다.</p>
<h2 id="🤔-백엔드가-왜-aws를-공부해야-하나요">🤔 백엔드가 왜 AWS를 공부해야 하나요</h2>
<ol>
<li><p>AWS를 사용해 백엔드 개발자는 <strong>서버 구매, 유지 관리의 필요성 없이 애플리케이션을 신속하게 배포하고 관리</strong>할 수 있다! </p>
<p> ⇒ 빠른 확장성, 높은 가용성, 보안 등 제공 </p>
</li>
<li><p>무중단 배포와 확장성 확보를 위한 전략 수립 </p>
<p> ⇒ 가용성과 성능 향상 </p>
</li>
</ol>
<p>ex. <code>AWS ELB Auto Scaling 기능</code> : 트래픽의 변동에 따라 <strong>자동으로 서버 인스턴스의 수를 조절</strong>, <strong>균형있게 트래픽을 분산 시킴</strong></p>
<p>ex. <code>AWS CodeDeploy 서비스</code> : <strong>코드 변경 사항을 자동으로 배포</strong>할 수 있음 → 코드 업데이트 과정에서 다운타임 없이 애플리케이션 최신 상태 유지 </p>
<p><strong>결론 : 비즈니스 요구사항에 다라 애플리케이션의 규모를 탄력적으로 조절 &amp; 지속적인 배포 프로세스 구축 가능</strong> </p>
<p>&amp;nbsp
&amp;nbsp</p>
<p>_참고자료
_
<a href="https://f-lab.kr/insight/aws-usage-guide-for-backend-developers">https://f-lab.kr/insight/aws-usage-guide-for-backend-developers</a></p>
<hr>
<p>그리고 두 번째, 
AWS의 구조 및 구성요소에 대해 알아보았다! 무작정 코드를 치는 것보단 이렇게 이해하고 넘어가고 싶은 마음 ,, 😎</p>
<h1 id="aws-기본-구조">AWS 기본 구조</h1>
<p><img src="https://velog.velcdn.com/images/yj_y/post/b80e9703-9752-4b1a-8f42-c6e3706a85f8/image.png" alt=""></p>
<h1 id="배포">배포</h1>
<blockquote>
<p>다른 사용자들이 인터넷을 통해서 사용할  수 있게 만드는 것
ex. 사용자 → 인터넷 → 서버</p>
</blockquote>
<ul>
<li>자신 컴퓨터: <a href="http://localhost">localhost</a> 로 테스트 개발 → 다른 컴퓨터에서 접근이 불가</li>
<li>배포 시: 고유의 주소 부여를 받게 됨 → 다른 컴퓨터에서 그 주소로 접속할 수 있다!</li>
</ul>
<h1 id="amazon-ec2">Amazon EC2</h1>
<blockquote>
<p>컴퓨터를 빌려서 <strong>원격으로 접속해 사용</strong>하는 서비스 
= 하나의 컴퓨터</p>
</blockquote>
<h3 id="1-왜-배워요">1. 왜 배워요?</h3>
<p>내 컴퓨터로 서버를 배포하면 24시간동안 컴퓨터를 켜놔야 함, 보안 위험 존재 </p>
<p><strong>⇒ 내 컴퓨터가 아닌 AWS EC2라는 컴퓨터를 빌려서 사용하자!</strong></p>
<h3 id="2-현업에서-써요">2. 현업에서 써요?</h3>
<p>실제 서버 배포 시 사용, <strong>백엔드 서버 배포 시 EC2</strong>에 서버 배포해 사용 </p>
<p>cf. 프론트엔드 배포는 vercel, netlify, AWS S3 주로 사용! </p>
<ul>
<li>클라우드 = 빌려 쓰기</li>
<li>클라우드 컴퓨팅 = 컴퓨팅 빌려 쓰기</li>
<li><strong>EC2 = 컴퓨팅을 빌려 쓰는 서비스</strong></li>
</ul>
<p>⭐ AWS에서 제일 중요한 서비스!</p>
<h1 id="리전region">리전(Region)</h1>
<blockquote>
<p>인프라를 지리적으로 나누어 배포한 각각의 데이터 센터</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yj_y/post/2fc90660-8901-413c-8759-41c7e039c32e/image.png" alt="">ex. EC2를 통해서 빌려 쓸 수 있는 컴퓨터들이 위치한 곳</p>
<blockquote>
<p>애플리케이션의 <strong>주된 사용자들의 위치와 지리적으로 가까운 리전</strong>을 선택하는 것이 포인트!
ex. 한국 유저들이 주로 사용 → 아시아 태평양(서울) 선택</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yj_y/post/35ec5dfd-5087-4732-9f5f-484a961b1c78/image.png" alt=""></p>
<h1 id="ip--port">IP &amp; Port</h1>
<h3 id="ip">IP</h3>
<blockquote>
<p>네트워크 상에서의 <strong>특정 컴퓨터</strong>를 가리키는 주소 
<code>13.250.15.032</code></p>
</blockquote>
<h3 id="port">Port</h3>
<blockquote>
<p>한 컴퓨터 내에서 실행되고 있는 <strong>특정 프로그램</strong>의 주소 
<code>13.250.15.032:3030</code> → <code>:3000</code></p>
</blockquote>
<p>+) <strong>브라우저 창에 포트 번호를 입력하지 않는 이유?</strong></p>
<p>ex. <code>naver.com:3030</code>이라고 쓰지 않고 <code>naver.com</code>이라고만 써도 이동됨 </p>
<p>⇒ 브라우저는 기본적으로 80번 포트로 통신 설정하기 때문!
&amp;nbsp
&amp;nbsp</p>
<p>+) <strong>잘 알려진 포트(well-known Port)</strong></p>
<hr>
<ul>
<li>0~65,535번까지 사용</li>
<li>0~1,023번까지는 주요 통신을 위한 규약에 따라 이미 정해져있다!</li>
<li>아래는 정해져있는 포트 중 중요한 것<ul>
<li>22번(SSH): 원격 접속을 위한 포트 번호 → EC2 인스턴스 연결 시</li>
<li>80번(HTTP) : HTTP로 통신을 할 때 사용</li>
<li>443(HTTPS) : HTTP로 통신을 할 때 사용</li>
</ul>
</li>
</ul>
<p>⇒     but, 강제는 아니다!</p>
<h1 id="aws-iam">AWS IAM</h1>
<blockquote>
<p>AWS 서비스와 서비스 리소스에 대한 액세스를 안전하게 관리해주는 서비스
AWS의 <strong>보안과 관리</strong>를 담당!</p>
</blockquote>
<h1 id="vpc">VPC</h1>
<blockquote>
<p>가상으로 존재하는 데이터 센터
→ 원하는대로 사설망 구축 가능!</p>
</blockquote>
<p>EC2 등이 실제로 실행되는 부분</p>
<h1 id="amazon-s3">AMAZON S3</h1>
<blockquote>
<p>객체 스토리지 서비스(파일 보관만 가능)</p>
</blockquote>
<ul>
<li>강력한 내구성</li>
<li>대규모 데이터 저장하고 관리하는 데 이상적</li>
</ul>
<h1 id="amazon-rds">AMAZON RDS</h1>
<blockquote>
<p>관계형 데이터베이스를 서비스화 시킨 서비스 
⇒ MySQL, MariaDB 등 여러 관계형 데이터베이스 서비스를 AWS로부터 비려서 사용하는 형태</p>
</blockquote>
<h3 id="q-왜-사용하나요">Q. 왜 사용하나요?</h3>
<blockquote>
<p>로컬 환경에서 개발할 때는 로컬 환경에 설치된 MySQL같은 DB를 연결해서 사용
⇒ <strong>but</strong>, 서버 배포 후 서버가 내 컴퓨터에 설치된 MySQL과 연결할 수 없음!
⇒ DB도 외부 인터넷에서 접근할 수 있게 같이 배포해야 됨</p>
</blockquote>
<p>= AWS RDS라는 데이터베이스를 빌려서 사용 </p>
<p>&amp;nbsp
&amp;nbsp</p>
<p>참고 영상: <a href="https://youtu.be/LU8x1UEcPFA?si=2qatHX1FJ40SpFMD">https://youtu.be/LU8x1UEcPFA?si=2qatHX1FJ40SpFMD</a></p>
<h2 id="마무리">마무리</h2>
<p>솔직히 인프라 공부 하는 것도 아니고 AWS를 왜 배우지..? 에 대한 의문이 가장 컸는데 어느정도 이해가 되었다.
근데 AWS 세팅 너무 어려워 스터디원 중에 원인도 모른 채 과금되고 있다는 안타까운 소식도 들어 (..) 더욱 조심히 다뤄야겠다는 생각이 들었다. 그럼 어렵게라도 만들지 말던가!!! 화는 그만 내고 이제 3주차 스터디를 준비하러 가야겠다! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[카카오 API ip mismatched 해결하기  ]]></title>
            <link>https://velog.io/@yj_y/1%EC%9D%BC%EC%B0%A8-%EC%B9%B4%EC%B9%B4%EC%98%A4-API-ip-mismatched-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@yj_y/1%EC%9D%BC%EC%B0%A8-%EC%B9%B4%EC%B9%B4%EC%98%A4-API-ip-mismatched-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 20 Dec 2025 13:19:27 GMT</pubDate>
            <description><![CDATA[<p>진정 내가 개발에 흥미가 있는 사람인가 싶어서 제미나이를 달달 볶아 내가 흥미 있을만한 주제를 던지라고 했다. </p>
<p>그래서 시작한 <strong>학교 공지사항 내 특정 단어</strong>가 들어간 게시물이 있을 때 나에게 카톡을 보내는 기능이었다.
일단 내가 [사이트 크롤링해서 갖고 와] -&gt; [그게 나한테 카톡으로 와] -&gt; *<em>헐 흥미돋아 *</em></p>
<p>참고로 리액트로 개발을 해봤다지만 그냥.. 감자세요?
파이썬? 그건 더 뭐예요?
<img src="https://velog.velcdn.com/images/yj_y/post/a4953b4c-1f39-449a-89e9-7331f187f889/image.png" alt=""></p>
<p>카카오 API를 처음 써보는 사람이었다는 점도 참고해주세요 
제미나이랑 1시간동안 싸웠지만 결국 날 해결해준 건 구글링 <del>(제미나이야 분발하렴 ^^?)</del> 이었다는 허무한 소식</p>
<p>해결방법 들어갑니다!
저의 삽질기같은 거 안 궁금하신 분은 <strong>3. 해결 방법</strong>으로 바로 넘어가시면 됨</p>
<h2 id="1-문제-상황">1. 문제 상황</h2>
<p><img src="https://velog.velcdn.com/images/yj_y/post/d9ba61c9-1d61-444c-94d8-d6f9768e0561/image.png" alt=""></p>
<p>당연히 이렇게 뜨고 있을 것이다.
카카오 공식 문서에도 당당하게 올라와있는 미등록 IP 주소 요청 시 발생하는 에러 .. 
<strong>ip mismatched!</strong>가 뭔데??????????</p>
<h2 id="2-ip를-허용해보자-전-안-됐어요-">2. ip를 허용해보자 <del>(전 안 됐어요 ..)</del></h2>
<p>일단 제미나이가 첫 번째로 제안한 건 이거였어요
<strong>[고급] - [허용 IP 주소]</strong> 들어가기 </p>
<p>근데? 나는? 고급 들어가면 아무것도 안 뜬다고 
말이 되는 소리를 하라고 
<img src="https://velog.velcdn.com/images/yj_y/post/02ba0389-5a8a-4bfb-bb22-363f80136422/image.png" alt=""></p>
<p>뭐 스크롤 내려라 화면 축소해봐라 이러는데 그냥 하다가 현타와서 다음 방법을 찾으러 가봅니다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/156a565f-422b-4aa5-9a71-a38baff305dd/image.png" alt=""></p>
<p>두 번째로는 내가 생성한 앱에 들어가서 <strong>[앱] - [어드민 키]</strong>에 들어가서 </p>
<ol>
<li>ip를 300번정도 쓰고 지우고 난리 치고 </li>
<li>시크릿 모드에서 앱 새로 만들어서 토큰 발급하고 다시 넣어봄</li>
</ol>
<p>하지만 해결되지 않고 그냥 1시간을 넘게 버린 사람됨 ...</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/f219e47b-4e6a-4ce8-8079-bdf04d141dc0/image.png" alt=""></p>
<p>결국 ip mismatched 해결방법 .. 검색햇어 . 
그리고 바로 원인을 찾앗어 .</p>
<h2 id="3-해결-방법">3. 해결 방법</h2>
<p>아래글 참고했고요
<a href="https://www.inflearn.com/community/questions/95313/msg-ip-mismatched-%EC%96%B4%EC%A9%8C%EA%B5%AC-%EC%A0%80%EC%A9%8C%EA%B5%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95?srsltid=AfmBOorkUHsAPfZY_v0MYDIi6dRhOCPgO7izxPzKx7sQxL7ClnpcbfEC">https://www.inflearn.com/community/questions/95313/msg-ip-mismatched-%EC%96%B4%EC%A9%8C%EA%B5%AC-%EC%A0%80%EC%A9%8C%EA%B5%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95?srsltid=AfmBOorkUHsAPfZY_v0MYDIi6dRhOCPgO7izxPzKx7sQxL7ClnpcbfEC</a></p>
<p>생각해보니까 토큰 발급 받았을 때 계속 흐린눈 하던 저것.
이걸 바꿀 수 있었던 것임
나는 그니까 계속 <strong>샘플용 토큰</strong>을 무한정으로 받고 있었던 거임 </p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/3df04d04-bc95-4164-ac3a-e7ac0a528e23/image.png" alt=""></p>
<p>이게 아니라 
<img src="https://velog.velcdn.com/images/yj_y/post/a18700b1-27ef-4b2f-9524-b0777fb6855b/image.png" alt=""></p>
<p>이렇게 <strong>내가 발급 받을 앱으로 바꾸고 토큰을 받았어야</strong> 됐어요
[앱] - [어드민 키]는 건들지 않고 이렇게 하니까 바로 끝나더라구요?</p>
<p><del>이름 보이세요 저 지금 과제하는 사람처럼 진짜최종_최종의최종 이러고 있어요</del></p>
<p>&amp;nbsp
&amp;nbsp</p>
<p>아 그리고 다시 발급 받을 때 이렇게 범위 모조리 다 비활성화 돼있으면 
<img src="https://velog.velcdn.com/images/yj_y/post/0ca8d71a-b74e-4aa1-b076-958e05336e19/image.png" alt="">
이렇게 하면 바로 해결돼요! 
<img src="https://velog.velcdn.com/images/yj_y/post/282f0521-692a-496f-ab42-e74ed853bf14/image.png" alt=""></p>
<p>&amp;nbsp</p>
<p>솔직히 아니 이딴 걸 놓친다고..? 싶을수도 있어요
말햇죠, 저 감자라고.
말햇죠, 저 카카오 API 처음 써본다고,
<img src="https://velog.velcdn.com/images/yj_y/post/bac93da0-0a3e-421d-b4b0-a106afeb0cf7/image.png" alt=""></p>
<p>귀엽게 봐주세요 </p>
<p>어찌됐든 이렇게 해서 !!!!!!!!! 
다시 토큰을 발급 받았고요 </p>
<p>제 코드에 다시 아름답게 넣었고
<img src="https://velog.velcdn.com/images/yj_y/post/c3249c36-21cb-4e25-8edb-bc5514f1a849/image.png" alt=""></p>
<p>드디어 -401 에러를 탈출해서 <strong>&quot;전송 성공&quot;</strong>을 보았어요 
<img src="https://velog.velcdn.com/images/yj_y/post/b93d9adc-f176-4ed5-ad26-7eccc1b4ab3e/image.png" alt="">
짠 이렇게 처음으로 크롤링을 성공했어요 ^^! 
카톡도 보내봤어요 칭찬해주세요 </p>
<hr>
<h2 id="오늘의-교훈">오늘의 교훈</h2>
<ol>
<li><p>제미나이가 텔레그램으로 하라고 추천해준 거 꾸역꾸역 붙잡고 있으니까 결국 해결했다 이런 성취감 .. 좋아 .. 앞으로도 꾸역꾸역 잡고 있을테야 <del>근데 나 개발 잘 맞는 걸까?</del>
<img src="https://velog.velcdn.com/images/yj_y/post/9a84357f-d48f-415d-9d3e-831a35c90d9d/image.png" alt=""></p>
</li>
<li><p>제미나이 지피티 다 좋지만 구글링도 잊지 말자 ,,</p>
</li>
</ol>
<p>이상 3-2 겨울방학을 지나고 있는 감자 1일차 일지 끝 
2일차 언제 나올진 모르겠지만 또 찾아올게요</p>
<p>이게 개발 블로그야 내 일상 블로그야 , </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CORS 에러]]></title>
            <link>https://velog.io/@yj_y/CORS-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@yj_y/CORS-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Tue, 25 Nov 2025 04:09:10 GMT</pubDate>
            <description><![CDATA[<p>작성하게 된 이유: 
<img src="https://velog.velcdn.com/images/yj_y/post/bea02fd9-7885-4524-8204-31468cb14fab/image.png" alt=""></p>
<p>어제 연결 세션을 하다보니 백엔드를 너무 모르는 것도 안 될 것 같다라는 생각이 들었다. 기초지식 함양 레츠고 </p>
<p>어제 보았다 CORS 에러 로그
<img src="https://velog.velcdn.com/images/yj_y/post/e18e0572-8835-4ae7-b239-60aab91a3d85/image.png" alt=""></p>
<hr>
<h1 id="cors가-뭐예요">CORS가 뭐예요?</h1>
<blockquote>
<p><strong>Cross Origin Resource Sharing</strong> 의 줄임말 
해석해보면 <strong>교차 출처(다른 출처) 리소스 공유</strong> ! </p>
</blockquote>
<p>&amp;nbsp</p>
<h3 id="먼저-출처origin에-대해-알아보자">먼저 출처(Origin)에 대해 알아보자</h3>
<blockquote>
<p><strong>Origin</strong> =  url 주소 상에서 <strong>프로토콜 + Domain 이름 + 포트</strong></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yj_y/post/e1f6eb84-59b1-4ad8-a0a0-96f228170dc6/image.png" alt=""></p>
<p>참고로 <strong>포트번호는 생략 가능</strong>하다. 
http, https 프로토콜의 기본 포트번호가 정해져 있기 때문! 
명시적으로 표기된 게 아니라면 http는 80번 https는 443번 포트가 디폴트 값이다.</p>
<h3 id="같은-출처same-origin-vs-다른-출처cross-origin">같은 출처(same origin) vs 다른 출처(cross origin)</h3>
<p><img src="https://velog.velcdn.com/images/yj_y/post/455e3771-3b62-4db9-b209-29bc5abe6a0c/image.png" alt=""></p>
<p>그러니까 <strong>CORS에러는 다른 출처</strong>일 때 나타나는 것이다! 
<img src="https://velog.velcdn.com/images/yj_y/post/b4820b23-7f73-41de-972e-659c372e936b/image.png" alt="">
&amp;nbsp</p>
<h1 id="cors-에러">CORS 에러</h1>
<blockquote>
<p><strong>same origin</strong> 상에서는 <strong>요청 오는 곳 = 처리하는 곳</strong>! 
➡️ 특별히 보안상 처리를 해줄 필요가 없다.</p>
</blockquote>
<p>하지만 <strong>cross origin에서 오는 요청이라면 내가 요청으로 받아온 결과를 믿을만한지 검증하는 과정이 필요</strong>하다. 왜냐하면 브라우저는 기본적으로 다른 서버를 신뢰하지 않아서 다른 서버에 요청을 보내거나 응답 받는 걸 차단하기 때문이다.
(참고로 이런 브라우저 정책을 <strong>SOP</strong>라고 한다.)</p>
<p>&amp;nbsp</p>
<h1 id="해결-방법">해결 방법</h1>
<h3 id="1-서버에서-cors-헤더-설정하기">1) 서버에서 cors 헤더 설정하기</h3>
<p>가장 일반적인 방법으로 서버 측에서 cors 헤더를 설정하여 도메인에서 오는 요청을 허용한다.
아래는 허용하는 도메인을 정의하는 코드 ! </p>
<pre><code>// 모든 도메인의 요청을 허용하는 경우
Access-Control-Allow-Origin: *

// 특정 도메인(https://example.com)의 요청만 허용하는 경우
Access-Control-Allow-Origin: https://example.com</code></pre><p>아래는 특정한 요청 메서드 또는 커스텀 된 헤더를 허용하도록 정의하는 코드 </p>
<pre><code>// 허용되는 메서드를 설정하는 경우
Access-Control-Allow-Methods: GET, POST, PUT, DELETE

// 허용되는 헤더를 설정하는 경우
Access-Control-Allow-Headers: Content-Type, Authorization
// +) 브라우저가 인증 정보가 포함된 요청을 보내는 경우
Access-Control-Allow-Credentials: true</code></pre><p><img src="https://velog.velcdn.com/images/yj_y/post/02c13ac6-021f-4766-a470-56491dc5117d/image.png" alt=""></p>
<h3 id="2-프록시-서버-사용하기">2) 프록시 서버 사용하기</h3>
<p>cors 에러를 우회하는 방법이다.
프록시 서버는 클라이언트와 타깃 서버 사이에 위치하며 모든 출처에 대한 요청 및 응답을 허용한다.
따라서 클라이언트가 보내는 요청을 프록시 서버가 대신 타겟 서버에게 전달해주고, 받은 응답을 다시 클라이언트에 반환해준다! </p>
<hr>
<h2 id="마무리">마무리</h2>
<p>상세하게까지 작성하진 않았지만 우선 CORS 에러에 대한 기초 개념은 알게 된 것 같다 (?)
연결 할 때 이제 CORS 얘기 나오면 괜히 아는 척 할 수 있을 듯 <del>죄송합니다</del> </p>
<p>출처 
<a href="https://docs.tosspayments.com/blog/payment-window-cors-error">https://docs.tosspayments.com/blog/payment-window-cors-error</a>
<a href="https://velog.io/@jh100m1/posts">https://velog.io/@jh100m1/posts</a>
<a href="https://selfish-developer.com/">https://selfish-developer.com/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Server Component vs Client Component ]]></title>
            <link>https://velog.io/@yj_y/Server-Component-vs-Client-Component</link>
            <guid>https://velog.io/@yj_y/Server-Component-vs-Client-Component</guid>
            <pubDate>Tue, 11 Nov 2025 07:43:10 GMT</pubDate>
            <description><![CDATA[<p>이번에도 <strong>next.js 공식 문서</strong>를 공부하다가 데리고 왔다.
<strong>서버, 클라이언트 컴포넌트</strong>에 대해 조금 더 심층 공부해볼 예정 ! 
<img src="https://velog.velcdn.com/images/yj_y/post/81debb0d-4e44-4040-a915-d00c0514bc2b/image.png" alt=""></p>
<p>지금까지 프론트 공부하면서 매 시간마다 본 </p>
<h2 id="서버-vs-클라이언트-구조">서버 vs 클라이언트 구조</h2>
<p>⬇️ 얘는 <code>SEO 관련 세미나</code> 준비 때 봤던 거 같고 
<strong>- Server Side Rendering (SSR) vs Client Side Rendering (CSR)</strong></p>
<p>⬇️ 얘는 오늘 <code>next.js</code> 공식문서에서 처음 봤다 
<strong>- Server Component vs Client Component</strong></p>
<p>&amp;nbsp
&amp;nbsp
둘이 똑같은 건 줄 알았는데 조금은 <strong>차이점</strong>이 있다고 한다? 
(참고1 : <a href="https://f-lab.kr/insight/react-server-components-vs-ssr?gad_source=1&amp;gclid=Cj0KCQjwsaqzBhDdARIsAK2gqnemvky3_9cOzvW3gRByc0bTPskIFKZnUPazRkcX6YrI5_zmkk-HOpgaAqLIEALw_wcB">https://f-lab.kr/insight/react-server-components-vs-ssr?gad_source=1&amp;gclid=Cj0KCQjwsaqzBhDdARIsAK2gqnemvky3_9cOzvW3gRByc0bTPskIFKZnUPazRkcX6YrI5_zmkk-HOpgaAqLIEALw_wcB</a>)
<img src="https://velog.velcdn.com/images/yj_y/post/9d48909d-7ff3-4993-b415-23f06d8a524b/image.png" alt=""></p>
<p>(참고2 :<a href="https://amaran-th.github.io/React/%5BNext.js%5D%20Server%20Component/">https://amaran-th.github.io/React/[Next.js]%20Server%20Component/</a>)
<img src="https://velog.velcdn.com/images/yj_y/post/195c1921-a2dc-4f27-b118-b14cf86316b6/image.png" alt=""></p>
<p>SEO 관련 세미나에서 SSR은 다뤘기 때문에 이번에는 컴포넌트에 대해 다뤄볼 예정이다!
*<em>시작 - *</em></p>
<h1 id="nextjs의-server-component-client-component">Next.js의 Server Component, Client Component</h1>
<p>Next.js 13부터 <strong>App Router</strong>가 등장하면서 <code>pages/</code> 라우터보다 강력한 기능이 생겼는데 여기서 핵심적인 개념이 바로 Server Client, Client Component이다! </p>
<h2 id="1-기본-개념---서버가-기본-클라이언트는-예외">1. 기본 개념 - 서버가 기본, 클라이언트는 예외</h2>
<p>우선 Next.js의 기본은 <strong>Server Component</strong>이다.
즉, 아무 설정을 안 하면 다 서버에서 렌더링 됨! </p>
<h3 id="server-component란">Server Component란?</h3>
<ul>
<li>서버에서 렌더링</li>
<li>결과물(HTML + React 구조 데이터)을 클라이언트로 보내주는 컴포넌트 </li>
<li>브라우저에서는 상태(<code>useState</code>), 이벤트(<code>onClick</code>)가 없음</li>
<li>대신 서버 가까이에서 데이터를 바로 불러올 수 있다!<pre><code>// 기본값: Server Component
import { getPost } from &#39;@/lib/data&#39;
</code></pre></li>
</ul>
<p>export default async function Page() {
  const post = await getPost(1)
  return <h1>{post.title}</h1>
}</p>
<pre><code>=&gt; DB나 API를 호출해도 API 키가 외부로 새지 않고, 불필요한 자바스크립트도 브라우저로 가지 않아 성능이 훨씬 좋음 !

### Client Component란?
서버 컴포넌트 안에서는 이벤트 핸들러를 직접 쓸 수 없기 때문에 
브라우저에서 동작해야 하는 부분만 따로 분리해서 `use client`를 선언해준다! </code></pre><p>&#39;use client&#39;</p>
<p>import { useState } from &#39;react&#39;</p>
<p>export default function LikeButton() {
  const [count, setCount] = useState(0)
  return &lt;button onClick={() =&gt; setCount(count + 1)}&gt;❤️ {count}</button>
}</p>
<pre><code>=&gt; 브라우저 JS 번들에 포함되고 유저가 클릭하면 실시간으로 상태가 바뀌는 부분이다 ! 



## 2. 서버 + 클라이언트 조합 
실제 프로젝트에서는 무조건!! 둘을 섞어서 쓸 수밖에 없는 일이 생긴다.
&gt; ex. 서버에서 글 데이터 불러오기 + 클라이언트에서 좋아요 버튼만 반응형으로 생성
</code></pre><p>// app/post/[id]/page.tsx (Server Component)</p>
<p>import LikeButton from &#39;@/app/ui/LikeButton&#39;
import { getPost } from &#39;@/lib/data&#39;</p>
<p>export default async function Page({ params }) {
  const post = await getPost(params.id)
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      <LikeButton likes={post.likes} />
    </article>
  )
}</p>
<pre><code>=&gt; `LikeButton`은 데이터를 받아 **브라우저 쪽에서만** 상태를 관리


## 3. `use client` 남용 금지
`use client`를 적는 순간, 그 파일 이하로 import된 모든 코드가 브라우저 번들에 포함된다.

즉, 
- `layout.tsx`에 `use client`를 넣으면 -&gt; 네비게이션, 푸터, 페이지 전부 클라로 넘어감 
- **이벤트가 필요한 컴포넌트만 따로 분리** -&gt; 성능 good, JS 번들도 훨씬 작아진다.

**좋은 예시** </code></pre><p>// app/layout.tsx (Server)
import Logo from &#39;./Logo&#39;
import Search from &#39;./Search&#39;</p>
<p>export default function Layout({ children }) {
  return (
    <nav>
      <Logo />
      <Search />
    </nav>
  )
}</p>
<pre><code></code></pre><p>// app/Search.tsx (Client)
&#39;use client&#39;
export default function Search() { /* input, useState 등 */ }</p>
<pre><code>-&gt; 이렇게 **Search만 Client로 작성**하는 것이 좋다. (Logo는 client 사용할 필요가 없으니까!)
&amp;nbsp
&amp;nbsp


**나쁜 예시** </code></pre><p>// layout.tsx
&#39;use client&#39; </p>
<pre><code>-&gt; 이렇게 되면 **전체가 클라이언트로 변해**서 번들 사이즈가 어어엄청나게 커지게 된다.

## 그래서 적절하게 사용하는 방법이 뭔데! 
: 데이터를 서버에서 미리 준비해두고, 클라이언트는 필요한 상태만 넘기는 구조로 만들자! 
&gt; **DB -&gt; Server Component -&gt; Client Component **

예를 들어 API 키가 필요한 데이터 호출은 서버에서 해야만 안전하다.</code></pre><p>// lib/data.ts
import &#39;server-only&#39;</p>
<p>export async function getSecretData() {
  const res = await fetch(&#39;<a href="https://api.com&#39;">https://api.com&#39;</a>, {
    headers: { authorization: process.env.API_KEY },
  })
  return res.json()
}</p>
<pre><code>`import &#39;server-only&#39;`를 추가해두면 클라이언트에서 잘못 import 할 경우 **빌드 에러로 막아줄 수 있다!**

# 결론 

⭐⭐⭐ 모든 걸 클라로 돌리는 게 아니라 **정적/데이터는 서버, 상호작용은 클라**로 진행하면 된다 ⭐⭐⭐

---


공부를 하다가 알게 된 건데 원래 리액트는 애플리케이션을 렌더링 하는 주체가 client였다고 한다.  **그런데 갑자기?** ![](https://velog.velcdn.com/images/yj_y/post/3e2772f7-ff97-4c0d-b833-ed60ac751c84/image.png)
next13부터는 app 디렉토리가 도입됨에 따라 **Server / Client component 개념**이 추가되었다고 한다. 
그러니까 **pages -&gt; app으로 바뀜**으로써 (근데 이것도 너무 큰 변화 아닌가? 사실 알못이어서 체감은 잘 못하겠다) 또 공부해야 될 게 생긴 거 아니야 .. ?
next에 대해 이야기(~~악플~~)했던 리드님의 세미나가 불현듯 뇌리를 스쳤다.
나 프론트.. 하는 게 맞는 걸까? 이대로 영원히 도태되는 것 아닐까..? 라는 걱정이 앞섰다.
현업에 계신 프론트 개발자분들은 정말 대단하다! 트렌디한 삶을 살아야 해 . .



걱정과 함께 마칩니다.
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[ Styled Component vs Tailwind CSS]]></title>
            <link>https://velog.io/@yj_y/Styled-Component-vs-Tailwind-CSS</link>
            <guid>https://velog.io/@yj_y/Styled-Component-vs-Tailwind-CSS</guid>
            <pubDate>Fri, 10 Oct 2025 06:21:37 GMT</pubDate>
            <description><![CDATA[<p><code>next.js</code> 공식문서 정리 중 아래와 같은 내용을 보았다.
CSS Styling 툴 중 가장 많이 쓰이는 <strong>Styled Component</strong>와 <strong>tailwindcss</strong>에 대해 비교해볼 예정이다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/d1949b26-1e4b-4184-82e5-ac51b8c78589/image.png" alt=""></p>
<hr>
<h1 id="styled-component">Styled Component</h1>
<blockquote>
<p>CSS-in-JS 라이브러리 중 하나로, JavaScript 파일 내에서 CSS를 작성할 수 있게 해주며 각 컴포넌트에 고유한 클래스를 자동으로 생성해 스타일 충돌을 방지한다.</p>
</blockquote>
<h2 id="특징">특징</h2>
<p><strong>- 쉬운 모듈화</strong>
: 스타일을 컴포넌트 단위로 모듈화 할 수 있어 재사용성과 유지 보수성이 크게 향상된다.
<img src="https://velog.velcdn.com/images/yj_y/post/fcb816db-6f1f-47c5-bd65-547843e57c7f/image.png" alt=""><strong>Button Component</strong>의 CSS를 <strong>styled-components를 사용</strong>하여 <strong>JS 내에서 정의 **
➡️ 오른쪽 코드처럼 프로젝트 내 **<em>어디서든 동일한 스타일</em></strong>로 사용될 수 있다! 
&amp;nbsp
&amp;nbsp</p>
<p><strong>- 편한 동적 스타일링</strong>
: 스타일을 동적으로 변경할 수 있어 <strong>조건부 스타일링이나 테마 변경</strong>이 용이해진다.
<img src="https://velog.velcdn.com/images/yj_y/post/19cb5c9b-09e6-4116-94b9-a8b7475d86b5/image.png" alt="">➡️ primary prop에 따라 <strong>버튼의 배경색이 동적으로 변경, 유연하고 강력한 스타일링</strong>을 구현할 수 있다.</p>
<p>&amp;nbsp
&amp;nbsp</p>
<h2 id="장점">장점</h2>
<p><img src="https://velog.velcdn.com/images/yj_y/post/e789e577-fe31-43c3-8f85-e8cc59f994ea/image.png" alt=""></p>
<p><strong>- 컴포넌트 단위의 유지보수</strong>
: Javascript 파일에 CSS를 같이 사용해 컴포넌트의 스타일링과 로직을 한 파일에서 관리할 수 있다.
➡️ 한 파일에서 직관적으로 컴포넌트를 관리할 수 있다.</p>
<p><strong>- 학습 용이성</strong>
: 기존 CSS 지식을 바탕으로 쉽게 사용할 수 있다.
&amp;nbsp
&amp;nbsp</p>
<h2 id="단점">단점</h2>
<p>*<em>- Javascript 파일 증가 *</em>
: 대규모 프로젝트에서 번들 크기 증가 -&gt; 초기 웹 페이지 로딩 속도가 느려짐 </p>
<p>*<em>- 런타임 성능 저하 가능성 *</em>
: 스타일을 컴포넌트 렌더링 시점에 생성 -&gt; 렌더링 성능 저하
📌 웹페이지 사용자의 경험을 떨어뜨리고, 예매 사이트와 같이 성능에 민감한 애플리케이션에서는 큰 문제가 된다.</p>
<h2 id="결론">결론</h2>
<blockquote>
<p>CSS와 JavaScript  파일을 통합하여 코드의 재사용과 유지 보수가 용이하다는 특징 때문에 컴포넌트 단위의 점진적인 스타일링할 때 적합하다</p>
</blockquote>
<hr>
<p>&amp;nbsp</p>
<h1 id="tailwind-css">Tailwind CSS</h1>
<blockquote>
<p>유틸리티 퍼스트(Utility-First) CSS 프레임워크로 <strong>미리 정의된 클래스를 사용</strong>하기 때문에 클래스 충돌 문제를 방지할 수 있다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yj_y/post/f3be24ff-75fc-4eeb-bd7c-d51c4682c709/image.png" alt=""></p>
<p><strong>➡️ TailwindCSS는 하나의 클래스가 하나의 속성을 나타냄</strong></p>
<blockquote>
<p>ex. <code>p-5</code> = <code>padding: 20px</code>
: 이는 코드 <strong>작성 속도를 크게 높여</strong>주며 스타일을 빠르게 적용할 수 있도록 도와준다.</p>
</blockquote>
<h2 id="특징-1">특징</h2>
<p><strong>- 일관성 유지</strong>
: 미리 정의된 유틸리티 클래스들은 일관된 스타일 가이드를 제공, 팀 내 모든 개발자가 동일한 스타일링 규칙을 따르게 된다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/d85770bd-d62c-4f55-9393-af1cfa5302c1/image.png" alt="">➡️ <code>tailwind.config.js</code> 파일에서 디자인 시스템에 맞는 유틸리티 클래스를 정의한다.</p>
<p>&amp;nbsp
<strong>- 편한 반응형 디자인</strong>
: 미디어 쿼리를 사용하지 않고, 다양한 화면 크기에 맞춰 스타일을 적용할 수 있는 유틸리티 클래스 제공 
<img src="https://velog.velcdn.com/images/yj_y/post/7c84a579-730a-4161-980a-28c7a2ab1281/image.png" alt="">➡️ 화면 크기에 따라 자동으로 조정됨</p>
<h2 id="장점-1">장점</h2>
<p><strong>- 빠른 스티일링 적용</strong>
: 미리 정의된 유틸리티 클래스 사용하여 신속하게 스타일을 적용할 수 있다.
➡️ 프로토타입이나 빠른 반복 개발에 유리</p>
<p><strong>- 심플해진 프로그래밍</strong>
: HTML + CSS / JavaScript로 나뉘며 로직과 스타일링 두 가지로 명확하게 분리될 수 있다.</p>
<h2 id="단점-1">단점</h2>
<p><strong>- 긴 클래스명으로 인한 HTML 가독성 저하</strong>
: 여러 유틸리티를 조합하다보면 가독성이 떨어져 유지 보수가 어려워진다.
<img src="https://velog.velcdn.com/images/yj_y/post/96683f59-3f43-4037-a989-e57bdea44d79/image.png" alt=""></p>
<p><strong>- 학습의 어려움</strong>
: 처음에 유틸리티 클래스의 개념과 사용법을 이해하는 데 시간이 걸리며, 기본적인 스타일 구성에 필요한 클래스를 암기하는 것이 어렵다.</p>
<hr>
<p>&amp;nbsp</p>
<h1 id="언제-어떤-기준으로-선택해야-할까">언제, 어떤 기준으로 선택해야 할까?</h1>
<p><img src="https://velog.velcdn.com/images/yj_y/post/f26b66cf-cff9-4492-819e-3343634b489b/image.png" alt=""></p>
<h2 id="styled-component-1">Styled Component</h2>
<p>⭐ <strong>몇 가지의 컴포넌트가 반복적으로 많이 쓰이는 상황 **
-&gt; Styled Component의 **모듈화</strong>를 통해 해결하자! </p>
<h2 id="tailwindcss">tailwindcss</h2>
<p>⭐ <strong>빠른 개발 속도가 필요하거나 웹 사이트의 크기, 성능이 중요한 작업, 일관된 디자인 시스템 속에서 개발 되어야 할 때</strong></p>
<hr>
<h1 id="npm-다운로드-수">npm 다운로드 수</h1>
<p><img src="https://velog.velcdn.com/images/yj_y/post/573514c5-f8a1-4685-b383-2dace16f8c3f/image.png" alt=""></p>
<p>Styled Components와 Tailwind CSS의 npm 다운로드 수를 나타낸 그래프
2023년을 기점으로 <strong>tailwind CSS</strong>가 더 많이 사용되는 것을 알 수 있다! </p>
<hr>
<h1 id="결론-1">결론</h1>
<p>물론 실제 선택은 둘 중 한 가지만 선택해서 사용하는 것이 아닌 두 기술을 혼용하여 사용하는 것도 가능하다. 여러가지 상황을 고려해서 선택하면 좋을 것 같다! </p>
<p>참고
<a href="https://www.elancer.co.kr/blog/detail/290">https://www.elancer.co.kr/blog/detail/290</a>
<a href="https://x2bee.tistory.com/105">https://x2bee.tistory.com/105</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDG 프로젝트 트랙 종료! ]]></title>
            <link>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%EC%A2%85%EB%A3%8C</link>
            <guid>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%EC%A2%85%EB%A3%8C</guid>
            <pubDate>Sun, 31 Aug 2025 08:02:11 GMT</pubDate>
            <description><![CDATA[<p>드디어 2달간의 프로젝트 트랙이 종료됐다!
그렇다면 개강이 찾아왔다는 거겠지 쩝 ,, 그래도 방학동안 프로젝트 하나라도 마무리해서 다행이라는 생각이 든다</p>
<p>프로젝트 회고를 위해 마지막 글을 작성해보자!</p>
<h3 id="liked---좋았던-점">Liked - 좋았던 점</h3>
<p>프로젝트 트랙에서 성공적으로 진행됐던 부분이나 스스로 칭찬할 점 등을 적어주세요.</p>
<blockquote>
<ol>
<li>프론트 - 백 API 연결 </li>
</ol>
</blockquote>
<p>커뮤니티를 만들어야 되는 특성상 프론트와 백 연결이 필수적이었는데 오랜 시간이 걸렸지만 완성했다!</p>
<blockquote>
<ol start="2">
<li>매주 오프라인 코어타임 진행</li>
</ol>
</blockquote>
<p>온라인 코어타임을 최대한 지양하고 오프라인으로 만나 개선점, 진행상황을 공유하며 집중하는 시간을 가졌다!</p>
<blockquote>
<ol start="3">
<li>(일부 기능들을 생략했지만) 구현한 부분은 완성도 있게 마무리 </li>
</ol>
</blockquote>
<p>우리팀의 최고 장점 : 쳐낼 수 있는 부분을 과감하게 쳐냈다 (?) 
매칭 및 채팅 기능을 구현해내지 못한 부분은 아쉽지만 사전에 개발 범위를 줄임으로써 오히려 완성도 있게 만들어낸 거 같다.</p>
<h3 id="learned---배운-점">Learned - 배운 점</h3>
<p>새로 익힌 기술, 개념뿐만 아니라 팀원들과의 협업에서 배운 점도 적어주세요.</p>
<blockquote>
<ol>
<li>백엔드와의 협업 방법 </li>
</ol>
</blockquote>
<p>프론트엔드 혼자 눈에 보이는 UI 만들기는 이제 너무 쉬운 시대(?가 왔으나 여전히 백엔드와의 협업은 쉽지 않은 것 같다. 하지만 이번 API 연결을 진행하면서 백엔드와의 협업 방식에 대해 알게 되었다! </p>
<blockquote>
<ol start="2">
<li>의사소통 방식</li>
</ol>
</blockquote>
<p>의사소통의 중요성을 또 한 번 깨달았다! 다인원이 진행하는 프로젝트다보니 사전에 완벽하게 협의되지 않으면 시간을 버린다는 사실 을 또 한 번 깨닫게 되었다!</p>
<h3 id="lacked---부족했던-점">Lacked - 부족했던 점</h3>
<p>기술적인 부족함, 협업에서의 어려움, 시간 관리 실패 등 아쉬웠던 점이 있다면 적어주세요.</p>
<blockquote>
<ol>
<li>우선순위 정하기 </li>
</ol>
</blockquote>
<p>외국인을 대상으로 하는 프로젝트인만큼 번역기능의 중요도가 높았는데 다른 기능에 좀 더 초점을 맞춰서 개발을 진행했던 것 같다.
그와중에 완벽하게 진행된 로그인 회원가입 아이디 비밀번호 찾기  ㅎㅎ</p>
<blockquote>
<ol start="2">
<li>최종 배포 미진행 </li>
</ol>
</blockquote>
<p>시간상 최종 배포를 하지 못했는데 이 점이 참 아쉽다..!! 하지만 한 번 모여서 배포해보기로 했는데 팀원분들 잊지 않았죠 저 진심이었어요 </p>
<h3 id="longed-for---바라는-점">Longed for - 바라는 점</h3>
<p>미래에 개선되었으면 하는 부분, 더 성장하고 싶은 부분과 그에 따른 앞으로의 목표를 작성해주세요.</p>
<blockquote>
<ol>
<li>보다 완성도 있는 프로젝트 만들기 </li>
</ol>
</blockquote>
<p>지금은 찍먹 수준의 프로젝트였지만 다음에 진행하게 될 프로젝트는 보다 퀄리티 있는 프로젝트를 만들어보고 싶다. 거의 뭐 런칭해버리기 (?) </p>
<blockquote>
<ol start="2">
<li>백엔드 + 프론트엔드 공부 </li>
</ol>
</blockquote>
<p>프로젝트를 해보니 깨달았다. 백엔드라고 해도 프론트를 모르고 프론트라고 해도 백엔드를 모르면 서로 의사소통이 어렵다는 걸 ..!! 그런 의미에서 이번 2학기는 백엔드 공부에 좀 더 비중을 둬보고 싶다.</p>
<p>프로젝트 관련 이미지도 쓰면서 플젝 얘기 하고싶은데
모바일 작성 이슈 … 추후에 여러가지 추가해서 써봐야겠다! 
두 달간의 프로젝트가 끝나니 후련하다!!!! 그리고 맞이한 개강 다들 2학기도 파이팅팅</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발 3주차 - 여러가지 기능들 ✂️]]></title>
            <link>https://velog.io/@yj_y/%EA%B0%9C%EB%B0%9C-3%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@yj_y/%EA%B0%9C%EB%B0%9C-3%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 12 Aug 2025 15:41:19 GMT</pubDate>
            <description><![CDATA[<p>드디어 로그인, 회원가입을 끝내고 게시판 및 마이 프로필 등 다양한 기능들을 개발하기 시작했다.
&amp;nbsp
&amp;nbsp</p>
<p>내가 담당한 건 *<em>총 3가지 *</em></p>
<blockquote>
<ol>
<li>마이 프로필 (+ 비밀번호 수정)</li>
<li>게시판 메인 화면 </li>
<li>작성 글 리스트 </li>
</ol>
</blockquote>
<p>마이 프로필, 비밀번호 수정 화면을 만들 때 공통 섹션인 <strong>Header 영역을 재사용</strong>하기로 하였고, 이론으로만 배웠던 리액트의 재사용의 용이성을 실감하게 되었다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/31622008-1bd2-4e73-9f2f-4b19da76b89b/image.png" alt=""></p>
<p>가장 기본은 아래의 [비밀번호 변경] 처럼 <strong>로고 + 타이틀</strong>만 있는 헤더</p>
<h3 id="1-headerjsx">1. Header.jsx</h3>
<pre><code>import React from &#39;react&#39;;
import { useNavigate } from &#39;react-router-dom&#39;;
import koundaryLogo from &#39;../../assets/images/koundary_logo.png&#39;;

const Header = ({ title = &#39;내 프로필&#39; }) =&gt; {
  const navigate = useNavigate();

  const handleLogout = () =&gt; {
    localStorage.clear();
    navigate(&#39;/login&#39;);
  };

  return (
    &lt;header className=&quot;border-b py-4&quot;&gt;
      &lt;div className=&quot;max-w-screen-lg mx-auto px-4 flex justify-between items-center&quot;&gt;
        &lt;div className=&quot;flex items-center gap-2&quot;&gt;
          &lt;img src={koundaryLogo} alt=&quot;Koundary Logo&quot; className=&quot;h-8 object-contain&quot; /&gt;
          &lt;span className=&quot;text-xl font-semibold&quot;&gt;{title}&lt;/span&gt;
        &lt;/div&gt;

        &lt;button
          onClick={handleLogout}
          className=&quot;px-4 py-1 border rounded hover:bg-gray-100&quot;
        &gt;
          로그아웃
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/header&gt;
  );
};

export default Header;</code></pre><p>-&gt; 기본값은 &quot;내 프로필&quot;로 유지하고, 필요하면 override할 수 있도록 만듦!</p>
<p>그렇다면 다른 페이지에서는 어떻게 재사용하나?</p>
<h3 id="2-myprofilejsx에서는-그대로-사용하면-된다">2. MyProfile.jsx에서는 그대로 사용하면 된다.</h3>
<pre><code>&lt;Header /&gt;</code></pre><h3 id="3-changepasswordjsx에서는-이렇게-변경">3. ChangePassword.jsx에서는 이렇게 변경</h3>
<pre><code>&lt;Header title=&quot;비밀번호 변경&quot; /&gt;</code></pre><p>이렇게 사용하니 하나의 Header.jsx 컴포넌트를 계속 재사용하면서</p>
<p>페이지마다 내 프로필, 비밀번호 변경, 회원가입 등 원하는 텍스트로 유연하게 표시가 가능했다.
정말 재사용하기 편한 구조였다..! 또한 코드에 대한 직관적인 이해도도 상승하는 느낌이었다.</p>
<hr>
<p>하지만, 초기 와이어프레임에는 헤더의 또 다른 기능이 있었는데 
아래의 사진 처럼 일부 페이지에는 [내 프로필], [로그아웃] 버튼이 필요했다.</p>
<p>그냥 Header2를 만드는 게 더 편할수도 있겠지만, 보다 쉬운 파일 관리를 위해 <del>(파일 많으면 머리 아프다 🥹)</del> 위의 <code>Header.jsx</code> 파일을 재사용하기로 마음먹었다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/540e2c78-cc29-4532-b0ea-bf470b189db6/image.png" alt=""></p>
<p>그래서 아래의 코드를 상단에 추가했고, 필요할 때마다 <code>SHOW_BUTTONS_PATHS</code>에 경로를 추가하면 해당 페이지에는 두 개의 버튼이 출력되게 된다. </p>
<pre><code>const BRAND = &#39;#2e8ada&#39;;

// 버튼을 노출할 경로 prefix 목록 (필요에 맞게 수정)
const SHOW_BUTTONS_PATHS = [&#39;/main&#39;, &#39;/posts&#39;];

const Header = ({ title = &#39;&#39; /* 필요 없으면 &#39;&#39; */ , showActions /* 강제 표시/숨김용 선택 프롭 */ }) =&gt; {
  const navigate = useNavigate();
  const location = useLocation();

  // 경로 기반 자동표시: /main, /board, /board/123 ... 에서 true
  const routeWantsButtons = SHOW_BUTTONS_PATHS.some(p =&gt;
    location.pathname.startsWith(p)
  );

  // showActions 프롭이 있으면 우선, 없으면 경로 규칙 사용
  const shouldShowActions = typeof showActions === &#39;boolean&#39; ? showActions : routeWantsButtons;</code></pre><p><img src="https://velog.velcdn.com/images/yj_y/post/21dc1822-64c9-402d-aacc-3dfcedce99e5/image.png" alt=""></p>
<hr>
<p>추가로 유용한 방식을 알게되었다!</p>
<p>이전까지는 백엔드와의 연결 전 UI 확인을 위해 더미 데이터를 하드코딩 했었다. 
하지만, 연결 할 때는 하드코딩한 부분을 다 지우고 변수와 함수 등을 다시 짜서 넣어 일을 2번 하였는데! </p>
<blockquote>
<ol>
<li><code>.env</code> 파일에 코드 작성</li>
<li><code>axiosInstance.jsx</code> 파일과 해당 기능을 사용하는 파일의 코드를 일부 수정</li>
</ol>
</blockquote>
<p>=&gt; 간편하게 <strong>목업 데이터 + 스위치 기능</strong>이 추가! </p>
<p>&amp;nbsp
&amp;nbsp</p>
<p>상세한 코드는 아래에서 👇👇 </p>
<h3 id="1-루트에-env-생성">1. 루트에 .env 생성</h3>
<pre><code>VITE_API_BASE_URL= http://111.11.11.1.11
VITE_USE_MOCK=true</code></pre><ul>
<li>VITE_API_BASE_URL → 백엔드 주소</li>
<li>VITE_USE_MOCK → <code>true</code>면 더미 데이터로 동작, <code>false</code>면 실제 서버로 호출</li>
</ul>
<p>⭐ 주의: 저장 후 서버를 재시작해야 반영됨 → <code>npm run dev</code> 다시 실행</p>
<h3 id="2-srcapiaxiosinstancejs">2. <code>src/api/axiosInstance.js</code></h3>
<pre><code>import axios from &#39;axios&#39;;

const axiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL, // .env에서 읽음
  headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },
  timeout: 10000,
});</code></pre><h3 id="3-srcapiboardjs-목업실서버-자동-전환">3. <code>src/api/board.js</code> (목업/실서버 자동 전환)</h3>
<pre><code>import axiosInstance from &#39;./axiosInstance&#39;;

const USE_MOCK = import.meta.env.VITE_USE_MOCK === &#39;true&#39;;
const wait = (ms) =&gt; new Promise(r =&gt; setTimeout(r, ms));

export const getBoardList = async ({ category, page = 1, size = 20 }) =&gt; {
  if (USE_MOCK) {
    // --- 목업 데이터 ---
    await wait(300); // 로딩감 주기
    const total = 83;
    const start = (page - 1) * size;

    const items = Array.from({ length: size }).map((_, i) =&gt; {
      const n = start + i + 1;
      return {
        id: n,
        title: `[${category}] 더미 글 제목 ${n}`,
        author: n % 3 === 0 ? &#39;길동&#39; : &#39;홍길동&#39;,
        createdAt: &#39;2025.07.01&#39;,
      };
    });

    return { items, total, page, size };
  }

  // --- 실서버 호출 ---
  const { data } = await axiosInstance.get(&#39;/boards&#39;, {
    params: { category, page, size },
  });
  return data; // 서버 응답 형식에 맞게 그대로 반환
};
</code></pre><p>이렇게 하면 아래와 같이 더미 데이터가 생성되며 <code>.env</code> 파일에 작성한 true 부분을 false로 변경한다면 더미 데이터가 사라진다! </p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/2ce8de96-1b24-4627-b5a3-debd4e3e41c8/image.png" alt=""></p>
<hr>
<h3 id="느낀-점">느낀 점</h3>
<p>로그인, 회원가입 이외에 다른 기능을 만들어보니 이론으로 배웠던 구조나 특징들이 직관적으로 이해되는 기분이었다.
나름 성장하고 있는 거겠지. . (아마)
벌써 2주밖에 안 남은 게 거짓말 같지만 남은 2주 알차게 써서 프로젝트 기분좋게 마무리하고 싶당 
다들 파이팅입니닷 💪💪 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발 2주차 - 로그인 프론트 & 백 연결 ]]></title>
            <link>https://velog.io/@yj_y/Temp-Title-k9lzmhal</link>
            <guid>https://velog.io/@yj_y/Temp-Title-k9lzmhal</guid>
            <pubDate>Tue, 29 Jul 2025 15:53:46 GMT</pubDate>
            <description><![CDATA[<p>진짜 슬프다
1주일 전에 로그인 마무리 과정까지 미리 작성해놨는데 날아감 내 글 내놔 대체 어디 간 거야 ....</p>
<p>황급히 복기해서 써보는 글이다 아주 허접할 듯 하다 🥹</p>
<hr>
<p>로그인 UI까지 완성했고 이제는 백엔드와의 연결을 남겨둔 상태</p>
<p><strong>첫 번째로 <code>axiosInstance</code> 만들기</strong> </p>
<pre><code>import axios from &#39;axios&#39;;

const axiosInstance = axios.create({
  baseURL: &#39;http://실제 백엔드 주소&#39;,
  headers: {
    &#39;Content-Type&#39;: &#39;application/json&#39;,
  },
});

export default axiosInstance;</code></pre><p><strong>API 모듈 분리: <code>auth.js</code></strong></p>
<pre><code>import axiosInstance from &#39;./axiosInstance&#39;;  // axiosInstance.js 파일에서 axios 인스턴스를 import

export const login = async (loginId, password) =&gt; {
  try {
    const response = await axiosInstance.post(&#39;백엔드 경로&#39;, {
      loginId,
      password
    });
    return response.data;  // 서버에서 받은 데이터 반환
  } catch (error) {
    throw error.response?.data || error;  // 에러 처리
  }
}
</code></pre><p>*<em>두 번째: <code>LoginForm.jsx</code> 파일에 유효성 검사 코드 추가 *</em></p>
<pre><code> if (isEmpty(loginId) || isEmpty(password)) {
      alert(&#39;회원정보를 모두 입력해주세요.&#39;);
      return;
    }

    try {
      const result = await login(loginId, password);  
      console.log(&#39;로그인 성공&#39;, result);

      // 토큰 저장 (예: localStorage)
      localStorage.setItem(&#39;accessToken&#39;, result.accessToken);
      localStorage.setItem(&#39;refreshToken&#39;, result.refreshToken);

      // 페이지 이동
      window.location.href = &#39;/main&#39;;
    } catch (err) {
      console.error(&#39;Error:&#39;, err);  // 에러 메시지 출력
      if (err.response) {
        alert(err.response.data || &#39;로그인에 실패했습니다.&#39;);
      } else {
        alert(&#39;서버 연결에 실패했습니다.&#39;);
      }
    }</code></pre><p>까지 완성해놓은 상태로 어제 API 연결을 진행했다.
회원가입을 담당한 프론트와 머지 후 발생한 충돌을 가까스로 정리하고 드디어 백엔드와의 연결을 진행했는데...! </p>
<p>역시나 한 번에 되진 않았다.
가장 큰 문제는 계속해서 &quot;서버 연결에 실패했습니다&quot; 팝업이 뜨는 것
! 콘솔 로그에는 <code>404</code> 에러가 뜨기 시작했다.
<del>밈으로만 쓰던 <code>404</code> 에러를 직접 보게 되다니 웃겼음</del> 
<img src="https://velog.velcdn.com/images/yj_y/post/f227be14-ad7c-4377-ac85-8b0d53f37a95/image.png" alt=""></p>
<p>이 팝업이 계속해서 떴는데 첫 번째 이유로는 
<strong>실제 백엔드 API 경로</strong>를 작성하지 않아서였다.</p>
<p>백엔드 실제 경로를 작성한 뒤에 해결되는가 싶었더니 동일한 팝업이 뜨기 시작했고, 콘솔 로그를 확인해보니 <code>400</code> 에러가 뜨기 시작했다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/7e06209f-a153-4e0b-b8a9-260f8774b8d9/image.png" alt=""></p>
<p>&amp;nbsp
우선 문법 오류라고 하니 맞는지는 모르겠지만 함수에서 보내는 데이터에 문제가 있다고 판단하였고, 백엔드와 이야기를 해보았는데</p>
<p>유저 ID의 변수명이 상이했던 것이다.</p>
<blockquote>
<ul>
<li>프론트: <code>ID</code></li>
</ul>
</blockquote>
<ul>
<li>백: <code>userID</code></li>
</ul>
<p>이를 알게되고 프론트에서 <code>ID</code>를 사용한 변수를 모두 <code>userID</code>로 변경하게 되니.....!!! 해결된 듯 싶었으나 <code>500</code> 에러가 발생했다.
<del>그래서 저는 쉬고 백엔드가 조금 더 고생했어요</del></p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/7d8b3380-235e-44aa-a0cc-834c44fcbcc2/image.gif" alt=""></p>
<p>화질이 좀 눈물나지만 연결 성공한 거 자랑하고 갈게요 
내일 있을 중간 발표 때도 동일한 얘기를 할 것 같지만 개인 기록용으로 여기도 첨부 ✏️</p>
<p>어찌됐든 로그인 연결은 끝났다! </p>
<p>이제 게시판 같은 굵직한 애들이 남아있으니 남은 한 달은 얘네 완성 시키기에 몰두해보아야겠다 💪 </p>
<hr>
<h2 id="느낀-점">느낀 점</h2>
<p>이번 과정에서 느낀 점은 간단하다.
개발 전 과정이 참 중요하구나... 사실 로그인 하면서 발생한 이슈들 모두 사전에 정의되고 정리됐다면 굳이? 싶은 이슈들인 것 같다.
*<em>API 경로 공유, 변수명 통일 *</em>이런 거 다 미리 진행해야 되는 거잖아!!! 하지만.. 아는 게 없는 초보들은 어쩔 수 없다 하핫
어찌됐든 직접 맞으면서 배우는 개발 나쁘지 않다고 생각한다
다음에는 말하고 생각했나요?가 아니라 생각하고 말했나요? 느낌으로 할 수 있겠지!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[가비지 컬렉터(Garbage Collector)]]></title>
            <link>https://velog.io/@yj_y/%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%ED%84%B0Garbage-Collector</link>
            <guid>https://velog.io/@yj_y/%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%ED%84%B0Garbage-Collector</guid>
            <pubDate>Sun, 20 Jul 2025 15:33:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="가비지-컬렉터란">가비지 컬렉터란?</h2>
<p>자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객체(Garbage)를 모아 주기적으로 제거하는 프로세스 
줄여서 GC라고도 한다.</p>
</blockquote>
<p><strong>C, C++</strong> 등의 프로그래밍 언어는 가비지 컬렉터가 존재하지 않아 프로그래머가 <code>free()</code>와 같은 함수를 사용해서 수동으로 메모리 할당과 해제를 일일이 진행했어야 했다.</p>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {
    int* ptr = (int*)malloc(sizeof(int)); // 동적 메모리 할당
    if (ptr == NULL) return 1;

    *ptr = 100;
    printf(&quot;값: %d\n&quot;, *ptr);

    free(ptr); // 메모리 해제
    return 0;
}</code></pre><p>이런식으로 <code>malloc</code>으로 메모리를 할당한 후 <code>free</code>로 수동 해제가 필요했다.</p>
<p>&amp;nbsp
&amp;nbsp</p>
<p>하지만 Java, C# 등의 언어는 처음부터 가비지 컬렉터가 존재하여 프로그래머가 동적으로 할당한 메모리 영역의 전체를 완벽하게 관리할 필요가 없어졌다. 이로 인해 버그를 줄이거나 막을 수 있음! </p>
<hr>
<h2 id="장점">장점</h2>
<ul>
<li><p>관리되는 힙에 효율적으로 개체를 할당한다.</p>
</li>
<li><p>더 이상 사용되지 않는 개체를 회수하고 이러한 개체의 메모리를 비워 이후 할당에서 이 메모리를 사용할 수 있도록 한다. 관리되는 개체는 자동으로 시작을 위한 정리된 콘텐츠를 받으므로 개체의 생성자가 모든 데이터 필드를 초기화할 필요가 없다.</p>
</li>
<li><p>개체가 다른 개체에 할당된 메모리를 자체적으로 사용할 수 없도록 하여 메모리 안전성을 제공한다.</p>
</li>
</ul>
<p>하지만 단점도 존재한다.</p>
<hr>
<h2 id="단점">단점</h2>
<ul>
<li>개발자는 메모리가 언제 해제되었는지 정확하게 알 수 없다.</li>
<li>GC가 동작하는 동안 다른 동작을 멈추기 때문에 오버헤드가 발생한다.</li>
<li>너무 자주 동작한다면 소프트웨어 성능 하락의 문제가 발생할 수도 있다.</li>
</ul>
<hr>
<h2 id="gc-대상">GC 대상</h2>
<p>가비지 컬렉션은 특정 객체가 garbage인지 아닌지 판단하기 위해서 도달성, 도달능력이라는 개념을 적용한다.
어떠한 변수에도 참조(reference)되지 않는 객체는 GC의 대상인데, 이를 <code>도달할 수 없는 객체(Unreachable Object)</code>라고 한다.</p>
<pre><code>public class Test {
    public static void main(String[] args) {
        String a = new String(&quot;hello&quot;);
        a = null;  // &quot;hello&quot;는 이제 누구도 참조하지 않음 → GC 대상
    }
}
</code></pre><p><img src="https://velog.velcdn.com/images/yj_y/post/005d2264-9ed0-4630-8009-c1a9d0a414c0/image.png" alt=""></p>
<hr>
<h2 id="gc-동작-원리">GC 동작 원리</h2>
<h3 id="1-mark-and-sweep-알고리즘">1. Mark and Sweep 알고리즘</h3>
<p>: 사용 중인 객체를 표시(mark)한 후 사용하지 않는 객체는 제거(sweep)
&amp;nbsp
&amp;nbsp</p>
<p>** 1) Mark (표시 단계)**</p>
<ul>
<li>루트(Root) 객체부터 시작해서 살아있는 객체를 전부 따라가며 표시한다.</li>
<li>루트란 스택에 있는 지역변수, static 변수, 레지스터 등을 말한다.</li>
</ul>
<p>&amp;nbsp
<strong>2) Sweep(제거 단계)</strong></p>
<ul>
<li><code>표시되지 않은 객체(Unreachable)</code>는 메모리에서 제거한다.
<img src="https://velog.velcdn.com/images/yj_y/post/546daff4-3fb8-4581-aea6-cf7c09d52811/image.png" alt="">
&amp;nbsp
&amp;nbsp<h3 id="2-stop-the-world-stw">2. Stop-The-World (STW)</h3>
: GC가 작동할 때 JVM이 모든 실행을 멈추고 메모리 정리를 시작<ul>
<li>서비스 이용에 차질이 생길 수 있기 때문에 이 시간을 최소화 시키는 것이 쟁점이다.
<img src="https://velog.velcdn.com/images/yj_y/post/081c794e-a722-405a-abbc-ac8d1dd85751/image.png" alt=""></li>
</ul>
</li>
</ul>
<p>하지만, GC가 너무 자주 실행되면 <strong>소프트웨어 성능 하락의 문제</strong>가 발생한다.
따라서 사용성을 유지하면서 효율적이게 GC를 실행하는 최적화 작업이 필요한데 이러한 최적화 작업을 <strong>GC 튜닝</strong>이라고 한다.
&amp;nbsp
&amp;nbsp</p>
<h2 id="3-세대generation-개념">3. 세대(Generation) 개념</h2>
<p>: JVM은 객체의 생명주기를 기반으로 메모리를 세대별로 나눠서 GC 효율을 높임 </p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/49f1bd69-1d2e-49d1-a2a7-60f0fb9f7ce0/image.png" alt=""></p>
<p> <strong>1) Young Generation</strong></p>
<ul>
<li>새로 생성된 객체가 저장</li>
<li>대부분의 객체가 금방 Unreachable 상태가 되기 떄문에, 많은 객체가 Young 영역에 생성되었다가 사라짐</li>
<li>Young 영역에 대한 가비지 컬렉션을 <code>Minor GC</code>라고도 한다.
&amp;nbsp</li>
</ul>
<p><strong>2) Old (Tenured) Generation</strong></p>
<ul>
<li>Young Generation에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역 </li>
<li>Young 영역보다 크게 할당, 크기가 큰 만큼 가비지는 적게 발생 </li>
<li>Old 영역에 대한 가비지 컬렉션을 Major GC or Full GC라고도 한다.</li>
</ul>
<p>&amp;nbsp</p>
<p>&amp;nbsp
힙 영역은 더욱 효율적인 GC를 위해 Young 영역을 <strong>3가지 영역 (Eden, survivor 0, survivor 1)</strong>으로 나눈다.</p>
<p>** 1)  Eden**</p>
<ul>
<li>new를 통해 새로 생성된 객체가 위치함</li>
<li>정기적인 쓰레기 수집 후 살아남은 객체들은 survivor 영역으로 보냄</li>
</ul>
<p><strong>2) survivor 0 / survivor 1</strong></p>
<ul>
<li>최소 1번의 GC 이상 살아남은 객체가 존재하는 영역</li>
<li>survivor 0 또는 survivor 1 둘 중 하나는 꼭 비어 있어야 한다는 규칙 존재 </li>
</ul>
<hr>
<p>출처: <a href="https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC">https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발 1주차 - 로그인 뿌수기 👊]]></title>
            <link>https://velog.io/@yj_y/%EA%B0%9C%EB%B0%9C-1%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@yj_y/%EA%B0%9C%EB%B0%9C-1%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 15 Jul 2025 13:34:19 GMT</pubDate>
            <description><![CDATA[<p>개발에 들어가기 전 여러가지 규칙을 정했고, 간략하게 지금까지 사용했던 규칙들만 작성해보려고 한다. </p>
<h2 id="브랜치-전략">브랜치 전략</h2>
<p><code>main</code>, <code>dev</code>, <code>feature/</code> 브랜치를 생성하여 각 기능별로 세세하게 브랜치를 나눠서 작업하기로 결정했다.</p>
<blockquote>
<p>main        ← 배포용 (최종 완성본)
└─ dev      ← 개발 통합 브랜치 (여기서 작업 브랜치 파생됨)
    ├─ feature/login
    └─ feature/signup
    .
    .
    .</p>
</blockquote>
<p>우선 현재 깃허브에 세팅한 브랜치는 아래와 같이 구성되어있다. 차차 추가될 예정! 
<img src="https://velog.velcdn.com/images/yj_y/post/1e49042c-8303-4e4d-a9b2-d0435c05e673/image.png" alt=""></p>
<h2 id="폴더-구조">폴더 구조</h2>
<p>우선 큼지막한 프론트 폴더 구조는 아래와 같이 정했다.
<img src="https://velog.velcdn.com/images/yj_y/post/8d5b240b-0c48-450c-bc5b-961e176c3674/image.png" alt=""></p>
<h2 id="가장-먼저-로그인과-회원가입을-진행하기로-결정했고-로그인을-담당하게-되어-우선-조그만-컴포넌트들로-쪼개서-진행하였다">가장 먼저 <code>로그인</code>과 <code>회원가입</code>을 진행하기로 결정했고, <code>로그인</code>을 담당하게 되어 우선 조그만 컴포넌트들로 쪼개서 진행하였다.</h2>
<h2 id="✏️-로그인-화면-진행-과정">✏️ 로그인 화면 진행 과정</h2>
<h3 id="1--로그인-폼-구현">1. ** 로그인 폼 **구현</h3>
<p>아래와 같이 <code>LoginForm.jsx</code> 파일과 <code>Login.jsx</code> 파일을 생성하여 진행하였다.</p>
<pre><code>src/
├── assets/           
├── components/
│   └── auth/
│       └── LoginForm.jsx        ← 로그인 input + 버튼
├── pages/
│   └── Login/
│       └── Login.jsx         ← 전체 레이아웃 </code></pre><p><img src="https://velog.velcdn.com/images/yj_y/post/8123e196-47d0-41c6-869f-5fcbd212e2fb/image.png" alt=""></p>
<p>또한 처음으로 <strong>기능 추가 커밋</strong>을 진행했다.</p>
<blockquote>
<p><strong>커밋 메시지</strong>는 아래의 블로그를 참고해서 작성! 
<a href="https://duektmf34.tistory.com/206">https://duektmf34.tistory.com/206</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yj_y/post/e8b16a51-5c84-4ed6-a90e-00914e089098/image.png" alt=""></p>
<h3 id="2--상단-로고-영역-">2. ** 상단 로고 영역 **</h3>
<p><code>LoginLogo.jsx</code>와 <code>Koundarytext.jsx</code>, 로고 이미지 등을 폴더에 추가해서 작업하였다.</p>
<pre><code>src/
├── assets/           ← 이미지, 폰트 등 정적인 리소스
│   └── logo.jpg
│   └── Koundary_text.png
│
├── components/
│   └── auth/
│       └── LoginForm.jsx     ← 로그인 input + 버튼
│       └── Koundarytext.jsx     ← &quot;Koundary&quot; 로고 컴포넌트
│       └── LoginLogo.jsx    ← 위쪽 회색 이미지(로고) 컴포넌트
│
├── pages/
│   └── Login/
│       └── Login.jsx         ← 전체 레이아웃 (Form + Logo + Image 조합)</code></pre><p><img src="https://velog.velcdn.com/images/yj_y/post/0c3c0f2a-7ef1-4346-bde7-860e4eddfc50/image.png" alt=""></p>
<h3 id="3--언어-선택-드롭다운-">3. ** 언어 선택 드롭다운 **</h3>
<p><code>LanguageSelector.jsx</code> 파일을 추가하여 작업하였다.</p>
<pre><code>src/
├── components/
│   └── auth/
│       ├── LoginForm.jsx
│       ├── LoginLogo.jsx
│       ├── LoginImage.jsx
│       └── LanguageSelector.jsx   ← 드롭다운+지구아이콘</code></pre><p>코드는 아래와 같은데 특이점은 지구 아이콘을 외부에서 저장해 가지고 오는 형식이 아닌 <code>react-icons</code>를 설치해 진행하였다.
&amp;nbsp</p>
<h4 id="react-icons-사용법"><code>react-icons</code> 사용법</h4>
<p><strong>1. 아래의 명령어를 이용해 설치</strong></p>
<pre><code>npm install react-icons</code></pre><p><strong>2. <code>LanguageSelector.jsx</code>  파일 최상단에 아래의 명령어 작성</strong>
: <code>{ }</code> 안의 코드는 아이콘마다 상이하니 검색해볼 것! </p>
<pre><code>import { FaGlobe } from &#39;react-icons/fa&#39;</code></pre><p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<hr>
<h2 id="최종-로그인-화면">최종 로그인 화면</h2>
<p><img src="https://velog.velcdn.com/images/yj_y/post/0596750b-562c-4bba-88b1-de31179c3a19/image.png" alt=""></p>
<p>로그인 화면 <code>와이어프레임</code>은 아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/52912a16-3842-474e-856b-73c4442c6b57/image.png" alt=""></p>
<p>최대한 비슷하게 해보려고 노력했다 😹
무조건적인 칭찬과 박수갈채 부탁드립니다 👏👏👏</p>
<hr>
<h2 id="보완해야-될-점">보완해야 될 점</h2>
<h3 id="1-이번에도-역시나-무작정-개발-시작">1. 이번에도 역시나 무작정 개발 시작!</h3>
<p>: 혼자 개발하는 것이 아니기 때문에 좀 더 세세하게 공통 컴포넌트나 개발 규칙 등을 정했어야 됐는데.. 현생이 바쁘다, 귀찮다라는 여러가지 핑계로 냅다 그냥 시작해버린 것 같다. 뭔가 지금까지 스무스하게 진행되는 것이 불안한 ;; <code>dev</code> 브랜치로 합칠 때 어떤 문제가 발생할지 벌써 두렵다. 
<del>하지만 미래의 일이니 어떻게든 되겠지.. 라는 마인드로 만들고 있다.</del></p>
<h3 id="2-이제서야-슬슬-이해되는-react-구조">2. 이제서야 슬슬 이해되는 react 구조</h3>
<p>: 프론트 스터디에서 공식 문서를 정리해서 발표하는 시간을 매주 가지고 있어 안일하게 react 강의를 듣지 않았다. <del>동현오빠한테 왜 물어봤지 어차피 안 할 거 미안합니다</del>
그랬더니 역시 처음에는 내맘대로 복사하고 붙여넣고 삭제하고 다시 넣고.. 이랬더니 슬슬 이해되기 시작했다. 개발할 때 당연히 지피티 도움을 받았지만 보다 중요한 건 <strong>코드와 구조를 정확히 이해하는 것!</strong>이라고 생각한다. 
그래서 우선 로그인 화면을 표면상?으로는 만들었으니, 내일 하루는 코드를 이해하고 tailwindcss를 학습하는 데 시간을 할애할 예정이다.</p>
<h3 id="3-여전히-부족한-tailwindcss-사용법">3. 여전히 부족한 tailwindcss 사용법</h3>
<p>: 모른다. 정말 모른다! 아직도 지피티한테 &quot;버튼 모양 바꿔줘&quot;, &quot;아 글씨가 좀 이상한데?&quot; 이러고 있다. 빠른 진행을 위해 관련 코드들을 숙지하고 있어야겠다는 생각을 했다.</p>
<h3 id="4-백엔드와의-연결을-위한-학습-필요">4. 백엔드와의 연결을 위한 학습 필요</h3>
<p>: 로그인 화면만 만들었다고 끝난 것이 아니고, 로그인 프로세스를 위한 백엔드와의 연결 과정이 필요할 텐데 프로젝트 트랙 미션 코스 마지막주에 굉장한 고생을 한 게 생각났다. 이를 위한 학습이 필요할 것 같다. 이게 최종보스일 듯 😨</p>
<p>&amp;nbsp
&amp;nbsp</p>
<p>다음 블로그는 코드 리뷰 위주로 작성해야지 
2주차도 힘내보자 ✏️✏️</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로젝트 기획의 시작과 끝 ✏️]]></title>
            <link>https://velog.io/@yj_y/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D%EC%9D%98-%EC%8B%9C%EC%9E%91%EA%B3%BC-%EB%81%9D</link>
            <guid>https://velog.io/@yj_y/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D%EC%9D%98-%EC%8B%9C%EC%9E%91%EA%B3%BC-%EB%81%9D</guid>
            <pubDate>Tue, 01 Jul 2025 14:29:37 GMT</pubDate>
            <description><![CDATA[<p>2주동안의 기획 코스가 끝이 났다!</p>
<p>아무것도 모르는 상태에서 킥오프를 진행하고, 어색한 상태에서 팀원들과 모여서 아이디어를 던져보고, 끊임없이 아이디어를 던지고 구체화하는 과정이 제일 재밌었던 것 같다. (괜히 뭔가 된 것 같은 느낌)</p>
<p>1주차 때 내가 냈던 의견은 AI를 이용한 <strong>여행 경로 추천 사이트</strong>였다.
괜히 있어보이게 플로우차트도 만들어봤다. 정말 코딱지만한 기능만 존재한데 실제 서비스 중인 사이트들을 보니 훨씬 유용한 기능들과 깔끔한 UI들에 감탄했다 🥹 
<img src="https://velog.velcdn.com/images/yj_y/post/90f6c924-dc44-41e7-a108-2a0c61254bbb/image.png" alt=""></p>
<p>현실적으로 단 두 달만에 초심자들이 AI를 이용한 개발은 불가능하다고 판단하여 다른 팀원의 아이디어인 <strong>외국인 유학생을 위한 커뮤니티</strong>를 선정했다.</p>
<hr>
<p>기획 코스를 회고해보자면 </p>
<h2 id="현실적으로-구현-가능한-범위">현실적으로 구현 가능한 범위</h2>
<p>우선 회의 중에 가장 힘들었던 부분은 현실과의 타협이었다. 
&quot;우리가.. 이걸 구현할 수 있을까?&quot;라는 생각과 함께 겁이 났다.
넣고 싶은 기능들에 대해 생각해보고, 현실적으로 구현 가능한지 판단해보고, 선택했다. 그리고 어느순간부터는 과감하게 생략을 해버렸던 것 같다 (사실 대부분 생략한 것 같기도)</p>
<h2 id="중구난방-얼렁뚱땅-기획">중구난방 얼렁뚱땅 기획</h2>
<p>되돌아보면 정말 얼렁뚱땅 기획을 했던 것 같다.
좀 더 체계적이었으면 좋았을 텐데..! 어제 개발 블로그 쓰다가 알게 된 개발 전후 프로세스를 따라간다던가..? 우리는 우선 플로우차트 만들고 UI 시각화부터 바로 시작.</p>
<p>단점으로는 여러 케이스를 생각하지 못해 시각화 중간에 &quot;근데 이런 케이스도 있지 않을까요?&quot; 하면 즉각적으로 추가해서 회의하고 있었다.
하지만 또 이를 극복하기 위해 마무리 후 유저 플로우대로 진행해보며 추가 케이스를 만들고, 이에 대한 보완을 해나갔다. 
사실 개발 중간중간에도 계속 기획이 보완되어야 될 것 같다는 생각이 들지만.. <del>결과만 좋으면 됐지 뭐</del></p>
<h2 id="개발-작업을-위한-추가-회의--문서화">개발 작업을 위한 추가 회의 &amp; 문서화</h2>
<p>API나 기술 명세서 같은 작업은 아직 안 ㅎ.. 진짜 해야한다 
프론트엔드 스터디 하면서 협업에 필요한 여러가지 규칙이 필요하다는 것! 만 알고 있지 딱히 실천은 안 하고 있는 듯 반성하자.. </p>
<p>그리고 온라인 회의나 피그마에 대강 적어놔서 문서화 되지 않은 여러가지 항목들을 얼른 정리해서 노션에 남겨놔야겠다는 생각을 했다. 쩝 언제 다하지 
&amp;nbsp
&amp;nbsp</p>
<hr>
<p>최종적으로 우리 팀의 최종 기획을 아주 조금 설명해보고 마무리</p>
<h2 id="✏️-외국인-유학생-커뮤니티---koundary">✏️ 외국인 유학생 커뮤니티 - Koundary</h2>
<p><strong>주제 선정 배경</strong></p>
<ul>
<li>유학생들을 위한 커뮤니티 서비스가 존재하지 않음</li>
<li>유학생들에게 한국인을 통한 문화 교류 기회 제공</li>
</ul>
<p><strong>서비스 타겟</strong></p>
<ul>
<li>외국인과 문화 교류를 하고 싶은 유학생, 한국인</li>
<li>외국인 전용 커뮤니티를 활용하고 싶은 유학생들</li>
</ul>
<p>*<em>주요 기능 *</em></p>
<ul>
<li>에브리타임과 같은 유학생 전용 커뮤니티 활성화</li>
<li><del>유학생:한국인 1:1로 한국에 대해 도움을 받고 싶은 유학생, 대화를 통해 언어 스킬을 늘리고 싶은 한국인 2명이 winwin하는 1:1 매칭 시스템</del>
=&gt; 사실 1:1 매칭이나 채팅 기능은 커뮤니티 기능 구현 여부에 따라 결정될 것 같다. 현실적으로 조금 어려울 것 같기도 함 😭</li>
</ul>
<hr>
<p>&amp;nbsp
뭔가 더 쓸 말이 많았던 거 같은데 모두 휘발 완 💪
다음 회고록은 쓸 만한 것들 미리 적어놓고 임시저장 해놓자 맨날 후회의 연속
개발기간도 모두모두 파이팅 ,, ~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프레임워크 vs 라이브러리 ]]></title>
            <link>https://velog.io/@yj_y/%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-vs-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</link>
            <guid>https://velog.io/@yj_y/%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-vs-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</guid>
            <pubDate>Sun, 29 Jun 2025 16:28:36 GMT</pubDate>
            <description><![CDATA[<p>프로젝트 진행 중 어떻게 하면 효율적으로 기획 및 개발을 할 수 있을지에 대해 고민했고, 
<code>개발 전/후에 대한 프로세스</code>를 조사해보았다.</p>
<p>참고로 <code>개발 프로세스</code>는 아래와 같다고 한다!<img src="https://velog.velcdn.com/images/yj_y/post/0b2120b6-5b5b-49f5-9219-55e0af6300db/image.png" alt=""></p>
<p>그 중 프레임워크와 라이브러리에 대한 개념이 생소해 이에 대해 조사해보았다 ✏️ 
 &amp;nbsp
  &amp;nbsp
   &amp;nbsp
    &amp;nbsp</p>
<h2 id="프레임워크-vs-라이브러리❓"><strong>프레임워크 vs 라이브러리❓</strong></h2>
<ul>
<li><strong>프레임워크</strong> = 뼈대 + 규칙 있는 건축 설계도
&amp;nbsp<ul>
<li><strong>라이브러리</strong> = 부품 모음집 (필요할 때 가져다 쓰는 도구)</li>
</ul>
</li>
</ul>
<p>라고 요약할 수 있다.
&amp;nbsp
&amp;nbsp</p>
<hr>
<h3 id="프레임워크란">프레임워크란?</h3>
<blockquote>
<p><strong>규칙이 정해져 있는 개발 뼈대</strong></p>
</blockquote>
<ol>
<li><p>코드를 프레임워크 안에 <strong>끼워 넣는</strong> 구조</p>
</li>
<li><p>개발자가 규칙을 따르며 만들어야 함</p>
</li>
<li><p>무언가 만들기 위한 전체 구조를 미리 세팅해야 함 
&amp;nbsp
&amp;nbsp</p>
</li>
</ol>
<h4 id="예시">예시</h4>
<ul>
<li><p><strong>웹 백엔드</strong> → <code>Django</code>, <code>Spring</code>, <code>Express</code></p>
</li>
<li><p><strong>프론트엔드</strong> → <code>React</code>, <code>Vue</code>, <code>Angular</code></p>
</li>
<li><p>*<em>모바일 앱 *</em>→ <code>Flutter</code>, <code>React Native</code>, <code>SwiftUI</code></p>
</li>
</ul>
<h4 id="▶️-django">▶️ <code>Django</code></h4>
<blockquote>
</blockquote>
<ul>
<li>쉽고 빠르게 웹사이트를 개발할 수 있도록 돕는 파이썬으로 만들어진 무료 오픈소스 프레임워크</li>
<li>회원가입, 로그인, 로그아웃과 같이 사용자 인증을 다루는 방법이나 웹사이트의 관리자 패널, 폼, 파일 업로드와 같은 것들의 요소 모음
(로그인/DB연결/페이지 라우팅 등 기본 기능 모두 제공)</li>
</ul>
<p>참고 링크: <a href="https://tutorial.djangogirls.org/ko/django/">https://tutorial.djangogirls.org/ko/django/</a>
&amp;nbsp
&amp;nbsp</p>
<hr>
<h3 id="라이브러리란">라이브러리란?</h3>
<blockquote>
<p><strong>특정 기능을 쉽게 도와주는 코드 조각들</strong></p>
</blockquote>
<ol>
<li><p>내가 원할 때 가져다 써서 조립</p>
</li>
<li><p>자유도가 높고, 필요한 기능만 골라서 씀
&amp;nbsp
&amp;nbsp</p>
<h4 id="예시-1">예시</h4>
</li>
</ol>
<ul>
<li><p><strong>날짜 처리</strong> → <code>moment.js</code>, <code>date-fns</code></p>
</li>
<li><p><strong>HTTP 요청</strong> → <code>axios</code>, <code>fetch</code></p>
</li>
<li><p><strong>차트</strong> → <code>chart.js</code>, <code>d3.js</code></p>
</li>
</ul>
<h4 id="▶️-momentjs">▶️ <code>moment.js</code></h4>
<blockquote>
<p><a href="https://momentjs.com/">https://momentjs.com/</a></p>
</blockquote>
<ul>
<li>JavaScript에서 <strong>가장 많이 사용되어 온 날짜 라이브러리</strong></li>
<li>현재 날짜를 가져오거나, 특정 날짜의 년/월/일만을 가져오거나, 내가 원하는 날짜 포맷으로 형식을 변경해 주거나, 특정 날짜와 비교해 주는 등 <strong>날짜 관련해서 다양한 처리가 필요할 때 사용</strong></li>
</ul>
<p>사용 방법 참고 링크: 
<a href="https://velog.io/@dojunggeun/JavaScript-Moment.js%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-Date-Time-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0">https://velog.io/@dojunggeun/JavaScript-Moment.js%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-Date-Time-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</a>
&amp;nbsp
&amp;nbsp</p>
<hr>
<h3 id="☑️최신-웹개발-스택-트렌드">☑️<strong>최신 웹개발 스택 트렌드</strong></h3>
<blockquote>
<p><a href="https://twentytwentyone.tistory.com/248">https://twentytwentyone.tistory.com/248</a></p>
</blockquote>
<ul>
<li>이 부분이 다음주부터 진행될 프로젝트 개발 기간에 참고하면 좋을 것 같아서 캡처해왔다! </li>
</ul>
<p><img src="https://velog.velcdn.com/images/yj_y/post/081d6942-1630-44e5-8b85-88ffb75c189c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩 컨벤션(coding convention)]]></title>
            <link>https://velog.io/@yj_y/%EC%BD%94%EB%94%A9-%EC%BB%A8%EB%B2%A4%EC%85%98coding-convention</link>
            <guid>https://velog.io/@yj_y/%EC%BD%94%EB%94%A9-%EC%BB%A8%EB%B2%A4%EC%85%98coding-convention</guid>
            <pubDate>Tue, 03 Jun 2025 09:55:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>코딩 컨벤션을 정리하게 된 계기</strong> 👇
: 첫 번째 스터디 변수 챕터 내 관련 내용이 있다는 것이..! 뇌리를 스쳤다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yj_y/post/3c6d78e8-2e1f-48d9-9ce0-f0591738c910/image.png" alt=""></p>
<h2 id="1-코딩-컨벤션이란-무엇이고-왜-중요할까">1. 코딩 컨벤션이란 무엇이고 왜 중요할까?</h2>
<blockquote>
<p>코드를 작성할 때 지켜야 할 일종의 <strong>스타일 가이드</strong></p>
</blockquote>
<ul>
<li><p>가독성 향상: 누가 봐도 한눈에 이해하기 쉬움.</p>
</li>
<li><p>협업 효율성: 여러 명이 작성해도 하나의 코드처럼 보이게 함.</p>
</li>
<li><p>유지보수 용이: 시간이 지나도 고치거나 이해하기 쉬움.</p>
</li>
</ul>
<p>✏️ 이러한 이유로 코드 컨벤션은 꽤나 중요하다!</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/bd67ead9-4a9b-4a76-a2da-03cd40c2107d/image.png" alt=""></p>
<h2 id="2-코딩-컨벤션의-대표적인-항목">2. 코딩 컨벤션의 대표적인 항목</h2>
<p>-** 들여쓰기 (Indentation)**</p>
<blockquote>
<ul>
<li>보통 2칸 또는 4칸. 팀 규칙에 따름.</li>
</ul>
</blockquote>
<p>-** 변수명 /  함수 스타일 **</p>
<blockquote>
<ul>
<li>camelCase, snake_case, PascalCase 
ex. userName, get_user_data(), UserProfile</li>
</ul>
</blockquote>
<p>-** 줄바꿈 / 공백**</p>
<blockquote>
<ul>
<li>연산자 앞뒤, 함수 인자 간격, 블록 간 공백 등
ex. if (a == b) vs if(a==b)</li>
</ul>
</blockquote>
<p>-** 주석 스타일 **</p>
<blockquote>
<ul>
<li>한 줄 주석, 블록 주석 사용 기준
ex. 너무 많은 주석 vs 의미 있는 주석</li>
</ul>
</blockquote>
<p>-** 파일 / 클래스 / 함수 구조 **</p>
<blockquote>
<ul>
<li>한 파일에 클래스 하나만, 짧은 함수 단위로 쪼개기 등</li>
</ul>
</blockquote>
<p>이전 발표 때 snake_case에 대해 잘 알지 못하여서 이번에는 snake_case에 대해 보충 설명을 해볼 예정 ! </p>
<h2 id="2-1-snake_case란">2-1. snake_case란?</h2>
<p>: 주로 <strong>파이썬(Python)</strong>에서 많이 쓰이는 이름 규칙</p>
<blockquote>
</blockquote>
<p>소문자 단어들을 언더스코어(_)로 구분하는 표기법</p>
<ul>
<li>함수명, 변수명에 사용<pre><code>def get_user_info():
  user_name = &quot;YJ&quot;
  return user_name
</code></pre></li>
</ul>
<pre><code>-  모듈명, 파일명에 사용</code></pre><h1 id="파일-이름-예시">파일 이름 예시</h1>
<p>user_controller.py
data_loader.py</p>
<pre><code>❌ **단, 클래스명에는 사용하지 않음! ** 
- 클래스명은 **PascalCase**를 사용</code></pre><p>class UserProfile:</p>
<p>```</p>
<ul>
<li><strong>다른 언어</strong>에서는?<ul>
<li>Java, JavaScript, C# 등은 대부분 <code>camelCase</code> 선호</li>
<li>하지만 <code>상수(const)</code>는 대문자 <code>snake_case</code> 사용<pre><code>const MAX_VALUE = 100;
</code></pre></li>
</ul>
</li>
</ul>
<p>&amp;nbsp</p>
<h2 id="3-코딩-컨벤션을-도와주는-도구들">3. 코딩 컨벤션을 도와주는 도구들</h2>
<p>: 아래 블로그에 도구들이 잘 모아져있어 링크로 첨부한다!</p>
<blockquote>
<p><a href="https://blog.naver.com/rinjyu/222458111066">https://blog.naver.com/rinjyu/222458111066</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDG 프로젝트 트랙 프론트엔드 4주차 미션 회고록]]></title>
            <link>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-4%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-4%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Tue, 03 Jun 2025 09:22:43 GMT</pubDate>
            <description><![CDATA[<p>이번주는 시험 공부로 인하여 미션 진행을 거의 진행하지 못했다..! 
그런 의미에서 2-3주차 미션으로 진행했던 클론 코딩을 회고해보려고 함 .. ✏️</p>
<p>&amp;nbsp</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/8db21dbc-0b22-4776-b81b-de770c5e1ef6/image.png" alt=""></p>
<ul>
<li>화살표 <code>&gt;</code> 버튼과 함께 슬라이드 기능 추가 
&amp;nbsp
&amp;nbsp</li>
</ul>
<h3 id="1-화살표--버튼-ui-추가-코드-">*<em>1. 화살표 <code>&gt;</code> 버튼 UI 추가 코드 *</em></h3>
<pre><code>&lt;button
  className=&quot;absolute top-1/2 right-2 -translate-y-1/2 bg-white text-gray-700 shadow-md rounded-full w-10 h-10 flex items-center justify-center hover:bg-gray-100&quot;
&gt;
  &lt;span className=&quot;text-2xl&quot;&gt;›&lt;/span&gt;
&lt;/button&gt;</code></pre><p>&amp;nbsp</p>
<p>✅ <code>카드 리스트(div)</code>와 화살표 버튼 <code>&gt;</code>을 같은 relative 안에 넣어주기 </p>
<p>&amp;nbsp</p>
<h3 id="2-클릭-시-슬라이드-기능-추가scrollby-ref-이용"><strong>2. 클릭 시 슬라이드 기능 추가(scrollBy, ref 이용)</strong></h3>
<ul>
<li><code>useRef</code>로 카드 리스트 DOM 제어
: 파일 상단 아래 코드 추가 </li>
</ul>
<pre><code>import { useRef } from &#39;react&#39;</code></pre><ul>
<li><code>RecommendSection</code> 함수 안에 아래 코드 넣기<pre><code>const scrollRef = useRef(null);
</code></pre></li>
</ul>
<p>const handleScrollRight = () =&gt; {
  scrollRef.current.scrollBy({
    left: 300,
    behavior: &#39;smooth&#39;,
  });
};</p>
<pre><code>

&amp;nbsp
&amp;nbsp
### **3. 스크롤 대상 div에 ref={scrollRef} 추가**</code></pre><div
  ref={scrollRef}
  className="flex space-x-4 overflow-x-auto scrollbar-hide pr-14"
>
  {/* 카드들 */}
</div>

<pre><code>(이걸 안 해줘서 첫 시도에 슬라이드가 넘어가지 않는 오류가 발생했다 😅) 

&amp;nbsp


#### **아래는 결과물** 👇👇
![](https://velog.velcdn.com/images/yj_y/post/50aee609-40bd-4b1a-8fdf-8593c87241ce/image.png)![](https://velog.velcdn.com/images/yj_y/post/4bcfb63b-8ed4-46b4-b0d2-dc8bdb2826fb/image.png)
슬라이드까지 구현 완! 


이번 주차는 기말고사로 인해 4주차 미션을 진행하지 못했지만 꼭 종강 후에 시도해보아야겠다는 다짐을 💪💪 !! 



&amp;nbsp
&amp;nbsp
&amp;nbsp





</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[GDG 프로젝트 트랙 프론트엔드 3주차 미션 회고록]]></title>
            <link>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-3%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-3%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Tue, 27 May 2025 12:40:56 GMT</pubDate>
            <description><![CDATA[<p>이번주는 생각보다 스무스하게 진행되었다.  <del>2주차가 유난이었던 거겠지</del></p>
<p>미션 진행 중 발생했던 오류를 리마인드 해보려 한다.
&amp;nbsp
&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h3 id="1-tailwindcss-코드를-작성했으나-적용-되지-않음"><strong>1. <code>tailwindcss</code> 코드를 작성했으나 적용 되지 않음</strong></h3>
<p><img src="https://velog.velcdn.com/images/yj_y/post/66373a63-9c1d-46d7-ba1a-1786c4624108/image.png" alt=""></p>
<p>➡️신규 미션용  폴더를 만들었으나 <strong><code>tailwindcss</code>를 설치하지 않았다.</strong>
&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<p><strong>매일 잊어버려 복기해보는</strong></p>
<blockquote>
<h3 id="tailwindcss-세팅-방법"><code>tailwindcss</code> 세팅 방법</h3>
</blockquote>
<h4 id="1-프로젝트-생성"><strong>(1) 프로젝트 생성</strong></h4>
<pre><code>pnpm create vite@latest 프로젝트명 -- --template react
cd 프로젝트명
pnpm install</code></pre><h4 id="2-tailwindcss-3x-설치">(2) TailwindCSS 3.x 설치</h4>
<pre><code>pnpm add -D tailwindcss@3 postcss autoprefixer</code></pre><p>*<em>설치 완료 후 *</em></p>
<pre><code>npx tailwindcss init -p</code></pre><h4 id="3-tailwindconfigjs-수정">(3) tailwind.config.js 수정</h4>
<pre><code>/* @type {import(&#39;tailwindcss&#39;).Config} */
module.exports = {
  content: [
    &quot;./index.html&quot;,
    &quot;./src/**/*.{js,jsx,ts,tsx}&quot;,
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}</code></pre><h4 id="4-css-설정"><strong>(4) CSS 설정</strong></h4>
<p>: <code>src/index.css</code> 파일에 다음 내용 추가</p>
<pre><code>@tailwind base;
@tailwind components;
@tailwind utilities;
</code></pre><h4 id="5-mainjsx-수정"><strong>(5) <code>main.jsx</code> 수정</strong></h4>
<pre><code>import React from &#39;react&#39;
import ReactDOM from &#39;react-dom/client&#39;
import App from &#39;./App.jsx&#39;
import &#39;./index.css&#39; // ← TailwindCSS 스타일을 포함한 CSS

ReactDOM.createRoot(document.getElementById(&#39;root&#39;)).render(
  &lt;React.StrictMode&gt;
    &lt;App /&gt;
  &lt;/React.StrictMode&gt;
)</code></pre><p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<hr>
&nbsp
&nbsp
&nbsp

<p>하지만 또 다른 문제에 봉착하였다.</p>
<h3 id="2-tailwindcss를-적용했으나-가운데-정렬이-되지-않음-">*<em>2. <code>tailwindcss</code>를 적용했으나 가운데 정렬이 되지 않음 *</em></h3>
<p><img src="https://velog.velcdn.com/images/yj_y/post/2fc1ddb6-93b5-4fbb-934a-066106a77195/image.png" alt=""></p>
<h4 id="➡️indexcss-내-css-코드가-tailwindcss-코드를-덮어쓰고-있어-안-보이는-것처럼-보였던-것이다">➡️<code>index.css</code> 내 css 코드가 <code>tailwindcss</code> 코드를 덮어쓰고 있어 안 보이는 것처럼 보였던 것이다.</h4>
<pre><code>@tailwind base;
@tailwind components;
@tailwind utilities;

.
.
button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}

.
.

</code></pre><h4 id="1-심플하게-css-코드를-삭제했다">1) 심플하게 css 코드를 삭제했다.</h4>
<pre><code>@tailwind base;
@tailwind components;
@tailwind utilities;
</code></pre><p><span style="color: red">➡️ 가운데 정렬은 되나 </span> <code>Main Page</code>** / **<code>UseEffect Page</code> <span style="color: red"> 버튼 UI가 사라짐 
<img src="https://velog.velcdn.com/images/yj_y/post/3355cf23-1163-4cd4-b937-8369c30ba6da/image.png" alt="내버튼돌려내"></p>
<p><strong>2) 그치만 가운데 정렬을 포기할 수 없어 css 코드에 의존하고 있던 버튼들을 <code>tailwindcss</code>로 변경하기로 했다.</strong></p>
<p><strong>- 변경 전 코드</strong> </p>
<pre><code>&lt;button onClick={() =&gt; navigate(&quot;/&quot;)}&gt;Main Page&lt;/button&gt;</code></pre><p>*<em>- 변경 후 코드  ⭐⭐ *</em></p>
<pre><code>&lt;button
 className=&quot;rounded-lg border border-transparent px-4 py-2 text-base font-medium bg-gray-200 hover:border-gray-400 transition&quot; onClick={() =&gt; navigate(&quot;/&quot;)}&gt;Main Page&lt;/button&gt;</code></pre><p><img src="https://velog.velcdn.com/images/yj_y/post/ef9e3515-3c0a-43d3-ac20-65e35d45b535/image.png" alt=""></p>
<h3 id="span-stylecolor-red해결-완료-🥳🥳-span"><span style="color: red">*<em>해결 완료! *</em>🥳🥳 </span></h3>
<p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h3 id="-github-근황-제출">+) GitHub 근황 제출</h3>
<p><img src="https://velog.velcdn.com/images/yj_y/post/08c90fd4-188e-48ec-b96d-e264abae59d8/image.png" alt=""></p>
<blockquote>
<p>*<em>지난주 강제 push 이후로 산산조각이 되었던 기록들이 여러가지 조작을 통하여 복구됨 *</em></p>
</blockquote>
<ul>
<li><p>몇 시간의 삽질이 도움이 되었는지 적응되어 나름 commit 메시지 형식도 맞추고 깔끔하게 진행해보려고 노력 중이다.</p>
</li>
<li><p>1-2주차까지는 커밋 메시지도 뒤죽박죽,, </p>
</li>
<li><p>이제 미션 코스는 마지막이지만 종강하고 진행될 프로젝트에서는 협업하기 좋은 방향으로 개선해보도록..!!</p>
</li>
</ul>
<p>  &amp;nbsp</p>
<p>  &amp;nbsp
  &amp;nbsp</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDG 프로젝트 트랙 프론트엔드 2주차 미션 회고록]]></title>
            <link>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-2%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-2%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Tue, 20 May 2025 14:23:32 GMT</pubDate>
            <description><![CDATA[<p>역대급 삽질을 기록해보려고 한다
참 피가 말렸던 시간들,, 
&amp;nbsp
&amp;nbsp</p>
<h3 id="발단-세상에서-가장-바보같은-일을-저질렀다">발단: 세상에서 가장 바보같은 일을 저질렀다.</h3>
<p>: <strong>PR 시 node_modules 같은 폴더가 함께 올라가 100K개의 파일</strong>이 업로드 되었다는 것이었다.
&amp;nbsp
&amp;nbsp</p>
<p><strong>+) 추가로 이 문제를 해결하다가 더 황당한 실수 발견</strong>
: <strong>동일한 이름의 폴더를 두 가지 경로</strong>에 저장해놓은 것이다.
이걸 2주차 1번 미션 완료 후 push된 코드를 검토해보았을 때 깨닫게 됨  😭
분명,, 코드를 적었는데 왜 커밋이 안 됐지? 왜 이러지? 
사실은 동일한 폴더가 두 개 있다는 것도 이땐 알지 못했다.
<img src="https://velog.velcdn.com/images/yj_y/post/b4c22307-e091-41f9-b767-3b9e983568b7/image.png" alt=""></p>
<h3 id="전개-대체-무엇이-문제지">전개: 대체 무엇이 문제지?</h3>
<p>우선 100K의 파일이 업로드 된 게 가장 문제였고, 오후에 디스코드에서 동일한 질문이 오간 것을 보았다.</p>
<p><img src="https://velog.velcdn.com/images/yj_y/post/bb119e25-39b2-436e-ab27-81fde836f3e7/image.png" alt=""><strong>=&gt; 링크를 참고해서 진행 해보았으나 해결되지 않았다 😭</strong>
&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<p>🤔 그래서 같이 미션 프로젝트를 하는 친구에게 질문을 했고, 유사한 문제를 해결했을 때 참고했던 링크를 보내주었다.</p>
<p>그 블로그에선 아래의 명령어를 알려주었는데
.
.</p>
<h4 id="여기서부터-공포-시작">여기서부터 공포 시작</h4>
<pre><code>git filter-branch --force --index-filter &#39;git rm --cached --ignore-unmatch ./node_modules -r option&#39; --prune-empty --tag-name-filter cat -- --all


git push --force --all</code></pre><p>바로 이 명령어였다. 
나는 마음이 급한 나머지 이 명령어가 무엇을 뜻하는지 알지 못하고 무작정 복사+붙여넣기 진행 </p>
<p>그리고 결과는 바로바로‼️‼️
&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h3 id="위기절정-네-제-레포가-다-날라갔다고요">위기&amp;절정: 네? 제 레포가 다 날라갔다고요?</h3>
<p>그래서 또 다른 나의 친구에게 원인을 물어보았음 ( GPT야 도와줘,, )
<img src="https://velog.velcdn.com/images/yj_y/post/e02aedad-df70-44ae-86ec-32561dfd7235/image.png" alt=""></p>
<h3 id="네">네....?</h3>
<p>진짜 거짓말이겠지, &quot;전부 날아감&quot;이라는 문장에 꽂혀 정상적인 사고가 불가능했다.
그래서 미션2로 회피를 함
 &amp;nbsp
 &amp;nbsp
 &amp;nbsp</p>
<h3 id="결말-나름의-해피엔딩">결말: 나름의 해피엔딩</h3>
<p>카페에서 탈출하여 집으로 되돌아온 후 차근차근 문제의 원인부터 찾기 시작했다.</p>
<p><strong>아래는 GPT의 답변 👇</strong></p>
<blockquote>
<p>Pull Request가 병합(Merged)되었거나, 관련 브랜치가 삭제된 경우
아래 중 하나라도 해당되면 Reopen 버튼이 사라집니다:</p>
</blockquote>
<ul>
<li><p>PR이 이미 merged 된 경우 → 되돌릴 수는 있지만 reopen은 불가</p>
</li>
<li><p>PR의 소스 브랜치가 삭제된 경우 → PR을 reopen할 수 없습니다</p>
</li>
</ul>
<p>📌 이 경우에는:</p>
<p>브랜치를 다시 만든 뒤, 새 Pull Request를 생성해야 합니다.
<img src="https://velog.velcdn.com/images/yj_y/post/a033a594-a64b-4153-8597-1bd58616a525/image.png" alt=""><span style="color: gray">(실제로 모든 일을 마무리하고 다시 확인해보니 아래 이런 코멘트가 있었다) </text>
&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<pre><code>git checkout -b YJ-Y
git push origin YJ-Y</code></pre><p>그리고 GitHub에서 새 PR을 열면 됩니다.</p>
<h3 id="-결국-새로운-pr을-생성하기로-결심-">*<em>=&gt; 결국 새로운 PR을 생성하기로 결심 *</em></h3>
<p>&amp;nbsp
&amp;nbsp</p>
<p>이후에는 아래의 방식으로 fix 버전의 브랜치와 함께 PR을 다시 한 번 생성했다.</p>
<blockquote>
<ol>
<li>원격 저장소의 main 브랜치 최신 상태 가져오기</li>
</ol>
</blockquote>
<pre><code>git fetch origin</code></pre><blockquote>
<ol start="2">
<li>main 브랜치로 이동하고 최신화</li>
</ol>
</blockquote>
<pre><code>git checkout main
git pull origin main</code></pre><blockquote>
<ol start="3">
<li>새 브랜치 만들기 (예: YJ-Y-fix)</li>
</ol>
</blockquote>
<pre><code>git checkout -b YJ-Y-fix</code></pre><p>이러한 과정으로 진행하니 중간중간 에러코드가 뜨지 않고 스무스하게 진행되어 약간의 기대감이 생겼고, 결과는</p>
<h3 id="span-stylecolor-red1주차-미션-기록은-살렸다---text"><span style="color: red">1주차 미션 기록은 살렸다 ! ! </text><a href="https://velog.velcdn.com/images/yj_y/post/ef198ede-e429-4742-8849-69b94a433819/image.png"></a></h3>
<p>솔직히 아직까지 맞는 건가? 싶긴 하지만 어찌됐든 무언가 다시 복구돼서 내 눈앞에 보이는 게 어딘가 ㅠ.ㅠ 
2주차 미션은 복구되지 않아 다시 처음부터 해야되지만 이것도 감사했다.
정말 롤러코스터 탄 것 같은 몇 시간이었다.
&amp;nbsp&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h3 id="📌-느낀-점">📌 느낀 점</h3>
<blockquote>
<p><strong>명령어는 잘 알아보고 쓰자</strong> ‼️
: 성급하게 복사 붙여넣기 금지 </p>
</blockquote>
<blockquote>
<p><strong>GitHub에 대해 한 발짝 더 가까워진 느낌 (?)</strong>
: 솔직히 지금까진 Commit / PR만 썼던 것 같은데 
branch도 다시 만들어보고 변경도 해보고,, 깃허브가 어떤 식의 명령어로 구성되고 어떻게 굴러가는지 직접 경험해보았다.</p>
</blockquote>
<h3 id="📌-궁금한-점">📌 궁금한 점</h3>
<blockquote>
<p>그럼 원래 쓰던 YJ-Y 브랜치는 사용이 불가한 것인가?</p>
</blockquote>
<blockquote>
<p>GitHub 사용 시 보다 안전하게 백업할 수 있는 방법이 있을까?</p>
</blockquote>
<p>다시는 이런 실수를 하지 않도록 GitHub 사용법을 익히고 안전하게 파일을 관리해야겠다는 생각이 들었다 ,, 
이 글을 보는 여러분들은 본인 손으로 이런 일을 저지르지 마세요 🥹</p>
<p>**
+) 25.05.21 **
또 한 번 node_modules이 npm_mission 폴더에 잡혀 커밋할 파일 개수가 10,000개가 넘어갔고 이에 대한 해결책을 찾았다.</p>
<p>: 전역 폴더에 <strong>.gitignore</strong>     파일 생성 &gt; <strong>node_modules</strong> 한 줄 써주면  commit 할 때 함께 잡히지 않음 !! 
<img src="https://velog.velcdn.com/images/yj_y/post/566c05b0-1d59-477d-a9e2-680efef1997a/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP와 네트워크 ]]></title>
            <link>https://velog.io/@yj_y/HTTP%EC%99%80-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@yj_y/HTTP%EC%99%80-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Sun, 18 May 2025 12:48:47 GMT</pubDate>
            <description><![CDATA[<h1 id="1-httphypertext-transfer-protocol란">1. HTTP(HyperText Transfer Protocol)란?</h1>
<blockquote>
<p>HTML과 같은 문서를 전송하기 위한 프로토콜 
즉, 웹 서버와 클라이언트 간의 <strong>데이터를 주고받기 위해 만들어놓은 통신 규약</strong></p>
</blockquote>
<p>☑️ 추가 개념: <strong>HTTPS란?</strong></p>
<blockquote>
<p>암호화되지 않은 HTTP 프로토콜에 암호화 프로토콜의 사용하여 통신을 <strong>암호화한 HTTP의 보안 버전</strong>
로그인 자격 증명이 필요한 웹사이트는 HTTPS 사용이 필요하다. 
<strong>📌 브라우저 주소창에서 🔒 자물쇠 모양이 보이면 HTTPS!</strong></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yj_y/post/7704e683-f15e-4432-b592-a58e41f2209c/image.png" alt="">출처: <a href="https://yozm.wishket.com/magazine/detail/1852/">https://yozm.wishket.com/magazine/detail/1852/</a></p>
<p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h1 id="2-http-동작-원리---request--response">2. HTTP 동작 원리 - Request &amp; Response</h1>
<p><strong>: HTTP의 핵심은 아주 간단하다!</strong></p>
<blockquote>
<p><strong>요청(Request) -&gt; 응답(Response)</strong></p>
</blockquote>
<p>예를 들어 브라우저에 <a href="https://www.naver.com">https://www.naver.com</a> 을 입력하게 되면</p>
<blockquote>
<ol>
<li><strong>브라우저가 서버에게 요청(Request)</strong>
: 페이지 좀 보여줘! </li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li><strong>서버가 응답(Response)</strong>
: HTML 파일, 이미지, 스타일 등을 보여줌 </li>
</ol>
</blockquote>
<blockquote>
<ol start="3">
<li>*<em>브라우저는 받은 걸 화면에 그려줌 *</em></li>
</ol>
</blockquote>
<p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h1 id="3-요청은-어떻게-생겼을까❓">3. 요청은 어떻게 생겼을까❓</h1>
<pre><code>GET /index.html HTTP/1.1
Host: example.com
</code></pre><blockquote>
<ul>
<li><strong>GET:</strong> 요청 방식 </li>
</ul>
</blockquote>
<ul>
<li><strong>/index.html</strong>: 어떤 리소스를 요청하는지 </li>
<li><strong>Host</strong>: 어디서 요청하는지 </li>
</ul>
<p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h1 id="4-http-요청-방식">4. HTTP 요청 방식</h1>
<p>: 어떻게 요청할지 말해주는 것! 이걸 Method(메소드)라고 한다.</p>
<blockquote>
<ul>
<li><strong>GET</strong>: 정보 주세요 (가장 흔함)</li>
</ul>
</blockquote>
<ul>
<li><strong>POST</strong>: 데이터 보낼테니 처리해주세요 (ex. 로그인, 폼 제출 등)</li>
<li><strong>PUT</strong>: 기존 데이터를 완히 바꿀래요 </li>
<li><strong>DELETE</strong>: 특정 데이터를 지워주세요 </li>
</ul>
<p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h1 id="5-요청을-받은-서버는-어떻게-응답할까❓">5. 요청을 받은 서버는 어떻게 응답할까❓</h1>
<pre><code>HTTP/1.1 200 OK
Content-Type: text/html

&lt;html&gt;...&lt;/html&gt;
</code></pre><blockquote>
<ul>
<li><strong>200 OK</strong>: 잘 처리했어요!  </li>
</ul>
</blockquote>
<ul>
<li>*<em>그 뒤에 HTML, JSON, 이미지 등 리소스가 따라옴 *</em></li>
</ul>
<h3 id="☑️-상태-코드">☑️** 상태 코드**</h3>
<ol>
<li><p>*<em>1XX 정보 제공 *</em></p>
</li>
<li><p><strong>2XX 성공</strong>
Ex. 리소스가 성공적으로 생성되었을 시, 201 Created</p>
</li>
<li><p>*<em>3XX 리디렉션 *</em>
Ex. URL이 바뀌었을 때 자동 이동시킬 때, 301 Moved Pemanently / 302 Found </p>
</li>
<li><p>*<em>4XX 클라이언트 오류 *</em>
Ex. URL 오타 시, 404 NOT FOUND
 요청 자체가 잘못되었을 시(형식 오류 등), 400 Bad Request</p>
</li>
<li><p>*<em>5XX 서버 오류 *</em>
Ex. 서버 내부 문제, 500 Internal Server Error</p>
</li>
</ol>
<p>&amp;nbsp</p>
<h3 id="🤔-상태-코드를-직접-확인하는-방법"><strong>🤔 상태 코드를 직접 확인하는 방법?</strong></h3>
<p>: 브라우저 F12 &gt; 네트워크 탭에서 요청 하나 클릭 -&gt; status code 바로 확인 가능<br><img src="https://velog.velcdn.com/images/yj_y/post/3eb670a8-f625-4ff2-bde3-3d936010675e/image.png" alt=""></p>
<h1 id="6-http는-상태를-기억하지-못함">6. HTTP는 상태를 기억하지 못함!</h1>
<h4 id="☑️-http는-한-번-요청하고-응답하면-잊어버리며-이걸-무상태stateless라고-한다">☑️ HTTP는 한 번 요청하고 응답하면 잊어버리며, 이걸 무상태(stateless)라고 한다.</h4>
<h4 id="➡️로그인-정보를-유지하려면-쿠키-세션-토큰-같은-것을-따로-써야-한다">➡️로그인 정보를 유지하려면 쿠키, 세션, 토큰 같은 것을 따로 써야 한다!</h4>
<p>&amp;nbsp
&amp;nbsp
&amp;nbsp</p>
<h2 id="🫡-결론">🫡 결론</h2>
<h3 id="http는">HTTP는</h3>
<ul>
<li><p>브라우저와 서버가 통신하는 약속이고</p>
</li>
<li><p><strong>요청 → 응답</strong>의 구조로 작동하며</p>
</li>
<li><p><strong>GET, POST</strong> 같은 방식으로 동작하고</p>
</li>
<li><p><strong>상태를 기억하지 않는</strong> 구조다!</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDG 프로젝트 트랙 프론트엔드 1주차 미션 회고록 ]]></title>
            <link>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-1%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@yj_y/GDG-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8A%B8%EB%9E%99-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-1%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Tue, 13 May 2025 13:25:25 GMT</pubDate>
            <description><![CDATA[<h3 id="-react-설정-시-참고-영상-">*<em># React 설정 시 참고 영상 *</em></h3>
<p>: pnpm and vite 
<a href="https://youtu.be/ZkqT3JnOUOE?si=rO3iAu8GWgoMBvtE">https://youtu.be/ZkqT3JnOUOE?si=rO3iAu8GWgoMBvtE</a>
&nbsp;
&nbsp;</p>
<h3 id="-생성-파일-접근-방법-">*<em># 생성 파일 접근 방법 *</em></h3>
<ol>
<li>명령 프롬포트 </li>
<li>cd 폴더명  </li>
<li>pnpm run dev </li>
<li>localhost 주소 출력 </li>
</ol>
<p>&nbsp;
&nbsp;</p>
<h3 id="-실수-">*<em># 실수 *</em></h3>
<p>*<em>1. 맨처음 html과 css를 inline 방식으로 한 번에 작성 *</em>
-&gt; 과제의도와 다르다는 걸 깨닫고 분리 방식을 찾아봄 </p>
<p><strong>참고 링크)</strong>
<strong>&lt; css &gt;</strong>
<a href="https://developer.mozilla.org/ko/docs/Learn_web_development/Getting_started/Your_first_website/Styling_the_content">https://developer.mozilla.org/ko/docs/Learn_web_development/Getting_started/Your_first_website/Styling_the_content</a>
**&lt; javascript &gt; **
<a href="https://opentutorials.org/course/1375/6620">https://opentutorials.org/course/1375/6620</a></p>
<p>&nbsp;
&nbsp;</p>
<p>*<em>2. GitHub Commit, Push, Pull Request(PR) *</em></p>
<ul>
<li>Commit: 로컬에서 변경한 코드를 Git에 저장소에 저장</li>
<li>Push: commit을 GitHub 서버에 업로드</li>
<li>Pull Request(PR): 특정 브랜치의 변경 내용을 main 같은 기준 브랜치에 합치자고 요청</li>
</ul>
<p><strong>현재 상태: Push가 되지 않고 있는 상태</strong> <img src="https://velog.velcdn.com/images/yj_y/post/047c394a-33ba-425c-b9c2-c4f95473b53c/image.png" alt="">
*<em>참고 링크) *</em>
<a href="https://velog.io/@hill0ne/git-push-%EC%98%A4%EB%A5%98-Updates-were-rejected-because-the-tip-of-your-current-branch-is-behind">https://velog.io/@hill0ne/git-push-%EC%98%A4%EB%A5%98-Updates-were-rejected-because-the-tip-of-your-current-branch-is-behind</a></p>
<p>요 링크를 참고해서 하나씩 해보고 있는데 아직도 되지 않고 있다 ........
일요일에 했던 push는 어떻게 한 걸까 의문이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[미션 0. HTML, CSS, JavaScript]]></title>
            <link>https://velog.io/@yj_y/%EB%AF%B8%EC%85%98-0.-HTML-CSS-JavaScript</link>
            <guid>https://velog.io/@yj_y/%EB%AF%B8%EC%85%98-0.-HTML-CSS-JavaScript</guid>
            <pubDate>Sun, 11 May 2025 13:34:04 GMT</pubDate>
            <description><![CDATA[<h1 id="html">HTML</h1>
<h3 id="14-웹-페이지-기본-태그">#1.4 웹 페이지 기본 태그</h3>
<ul>
<li>link tag
: 외부 리소스와의 연게 정보 표시, HTML과 외부 CSS 파일 연계<pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot;&gt;</code></pre></li>
<li>script tag
: client-side JavaScript 정의 <pre><code>&lt;script&gt;
    document.addEventListener(&#39;click&#39;, function () {
      alert(&#39;Clicked!&#39;);
    });
  &lt;/script&gt;</code></pre></li>
</ul>
<h3 id="17-표-형식-표현을-위한-태그">#1.7 표 형식 표현을 위한 태그</h3>
<ul>
<li>table: 표를 감싸는 태그 </li>
<li>tr: 표 내부 행(table row)</li>
<li>th: 행 내부 제목 셀(table heading)</li>
<li>td: 행 내부 일반 셀 (table data)
<img src="https://velog.velcdn.com/images/yj_y/post/708f247f-d74f-4323-b6f1-2c4aeb8464b0/image.png" alt=""></li>
</ul>
<h3 id="18-폼-태그">#1.8 폼 태그</h3>
<p>기능이 정말 많음.. 과제 하면서 차차 뽀개보자 
참고) <a href="https://poiemaweb.com/html5-tag-forms">https://poiemaweb.com/html5-tag-forms</a></p>
<h1 id="css">CSS</h1>
<h3 id="14-박스-모델">#1.4 박스 모델<img src="https://velog.velcdn.com/images/yj_y/post/0e70079a-15e9-40bc-9aa9-fb7a6c922de0/image.png" alt=""></h3>
<ul>
<li>content: 실제 내용이 위치하는 영역, width, height 프로퍼티를 가짐 </li>
<li>padding: 테두리 안쪽에 위치하는 내부 여백 </li>
<li>border: 테두리 영역</li>
<li>margin: 테두리 바깥에 위치하는 외부 여백</li>
</ul>
<h3 id="110-우선순위">#1.10 우선순위</h3>
<ul>
<li>Cascading (캐스캐이딩)
: CSS 적용 우선 순위 <ol>
<li>중요도: CSS가 어디에 선언 되었는지에 따라 우선순위가 달라짐</li>
<li>명시도: 대상을 명확하게 특정할수록 우선순위 높아짐 </li>
<li>선언순서: 선언된 순서에 따라 우선 순위가 적용, 나중에 선언된 스타일이 우선 적용 </li>
</ol>
</li>
</ul>
<h4 id="javascript는-파트-스터디에서-다루기-때문에-생략-">JavaScript는 파트 스터디에서 다루기 때문에 생략 ,,</h4>
]]></description>
        </item>
    </channel>
</rss>