<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>tl_dr.log</title>
        <link>https://velog.io/</link>
        <description>복잡한 세상 편하게 살자</description>
        <lastBuildDate>Tue, 30 Jan 2024 16:52:58 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>tl_dr.log</title>
            <url>https://velog.velcdn.com/images/tl_dr/profile/1a11fb7c-3778-44ff-abb4-0fe376390383/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. tl_dr.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tl_dr" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[졸음 운전 방지 서비스 "하지마(HAGIMA)" 제작 후기]]></title>
            <link>https://velog.io/@tl_dr/HAGIMA</link>
            <guid>https://velog.io/@tl_dr/HAGIMA</guid>
            <pubDate>Tue, 30 Jan 2024 16:52:58 GMT</pubDate>
            <description><![CDATA[<h4 id="들어가기에-앞서">들어가기에 앞서</h4>
<p>본 글은 Naver Cloud Platform의 주니어 개발자 지원 프로그램 &quot;Green Developers&quot;의 참여 후기 작성을 위해 제작되었습니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/839dae81-0cdc-4853-aecc-09c94a628068/image.png" alt=""></p>
<p><a href="https://www.ncloud.com/support/greenDevelopers">Green Developers 알아보기</a></p>
<p>12월에 프로젝트 끝나자 마자 쓰려고 했었는데 어쩌다 보니 해를 넘겨 2월을 향하고 있네요... 그치만 NCP가 너무 좋기도 했고 나름대로 후기를 남기고 싶어서 이렇게 글을 쓰게 되었습니다.</p>
<h2 id="프로젝트-소개">프로젝트 소개</h2>
<h3 id="프로젝트명">프로젝트명</h3>
<p>HAGIMA <code>(Hands-free Audio Guided Intelligent Mobile Application)</code></p>
<h3 id="기획-의도">기획 의도</h3>
<p>이 프로젝트는 ** 차량 내부에서 사용할 수 있는 센터페시아 프로그램 컨셉의 졸음운전, 휴대폰 사용 감지 및 경고음성 출력 서비스** 를 제작하는 프로젝트였습니다.</p>
<p>졸음운전이나 휴대폰 조작 등 차량 내부에서의 이상행동으로 인한 교통사고는 꾸준히 발생하고 있습니다. 그래서 이번 프로젝트에서는, 비전인식 기술을 활용하여 운전자가 이상행동을 할 경우 이를 빠르게 감지하여 경고음성을 출력하도록 구현했습니다.</p>
<p>또한 경고 음성 출력시 AI 음성 기술을 활용해 지인의 음성을 학습하고 그 목소리로,경고를 출력하여 더 효과적인 경고를 출력하는 것을 목표로 하였습니다.</p>
<p>그리고 차량 탑승 시 사용자의 얼굴을 인식하여 사용자를 식별하고 지인 음성 등 저장된 설정을 자동으로 불러와 편하게 서비스를 사용할 수 있도록 하는 것을 목표로 잡았습니다.</p>
<h3 id="결과물">결과물</h3>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/a66ec59b-9e28-4d2f-8f90-ce619ac00443/image.png" alt=""></p>
<p>GCP 및 NCP의 무료 크레딧 소진 문제로 지금은 서비스를 종료해 더는 사용해 볼 수 없지만, 관련한  Repository를 아래에서 확인하실 수 있습니다.
<a href="https://github.com/Albatross-Five/hagima-backend">NCP에 호스팅한 Spring Boot Server Repository</a></p>
<h2 id="ncloud에서-사용한-기술">Ncloud에서 사용한 기술</h2>
<p>한참 서비스했던 12월을 기준으로 보면 아래와 같은 서비스들을 사용했었습니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/1ba69e21-da5d-4a53-8481-103282c044a9/image.png" alt="">
각 서비스들을 설명해보자면..</p>
<h4 id="block-storage">Block Storage</h4>
<p>Server Instance 의 저장소 (SSD)로 사용하는 서비스로 기억합니다.  </p>
<h4 id="cloud-log-analytics">Cloud Log Analytics</h4>
<p>간단한 로그 확인은 무료로 할 수 있도록 도와줬던 서비스입니다.</p>
<h4 id="certificate-manager">Certificate Manager</h4>
<p>세팅하는 게 굉장히 어려웠던 Certificate Manager...
Server Instance 내에서 certbot 등을 이용해 SSL 인증을 구현하는 것 보다는 ALB를 통한 프록시를 구현하고, ALB에 인증서를 달고 싶어 사용했던 서비스였습니다.</p>
<p>외부에서 발급받은 도메인 대한 인증서를 직접 등록해야 쓸 수 있었는데, 이를 등록하는 과정이 Windows 이외에는 할 수 없었어서, Window Server Instance를 빠르게 생성하여 거기서 원격으로 작업했던 것이 기억에 남습니다.</p>
<p>지금은 업데이트되어 좀 더 편해졌다는 뉴스레터를 봤던 것 같은데, 자세히는 확인 안해봐서 모르겠네요</p>
<p>관련한 삽질 내용이 궁금하시다면
<a href="https://guide-fin.ncloud-docs.com/docs/security-certificatemanager-certificatemanagerconsole">참고: Certificate Manager 사용 가이드
</a></p>
<h4 id="load-balancer">Load Balancer</h4>
<p>AWS의 ALB와 거의 동일한 기능을 제공했습니다. 위에서 언급했듯 SSL 인증서 등록 + Server Instance Proxy를 위해 사용했고, 따로 부하에 따른 로드밸런싱은 구현하지 않았었습니다.</p>
<h4 id="cloud-db-for-mysql">Cloud DB for MySQL</h4>
<p>마찬가지로 AWS RDS와 거의 동일한 기능을 제공했었습니다. 처음에는 그냥 Server 를 MySQL 용으로 띄울까 했었는데, 이왕 쓰는거 좋은거 쓰자~ 하며 사용했었습니다.
다만 Replica 를 필수로 사용해야 했어서 그냥 Server에 MySQL을 구현하는 것보다 비용이 2배로 청구된다는 단점이 있었습니다.</p>
<h4 id="object-storage">Object Storage</h4>
<p>프로필 저장 등을 위해 사용했었습니다.</p>
<h4 id="public-ip">Public IP</h4>
<p>처음 Server를 사용하면 ssh 접속을 위한 임시 IP만 있고, 실제로 서비스하기 위해서는 Public IP가 필요했습니다.
연결되어있는 Elastic IP 1개에 대해서는 비용을 청구하지 않는 AWS와 달리 1개부터도 비용이 청구됩니다.</p>
<h4 id="source-deploy">Source Deploy</h4>
<p>AWS의 CodeDeploy처럼 이용할 수 있을까 싶어 살짝 건드려봤는데, Github Action에서 연동하는게 어려워 사용을 포기했던 서비스입니다.</p>
<h4 id="server">Server</h4>
<p>NCP의 알파이자 오메가. 서버 인스턴스입니다.</p>
<h2 id="ncloud-서비스를-어떻게-적용-하였나요">Ncloud 서비스를 어떻게 적용 하였나요?</h2>
<p>위에서 말로 구구절절 설명하긴 했지만.. 아키텍처로 보는게 더 빠르실 것 같습니다.</p>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/cc7e776a-6191-4cce-91f2-14904dfb31ca/image.png" alt="">
구현한 서비스는 회원 정보 저장 및 외부 API 등을 사용하는 Spring Boot Main Server와, 졸음운전을 실시간으로 인식하는 FastAPI ML Server. 총 두 개의 Server를 사용하였습니다.</p>
<p>그중 ML Server는 <strong>NCP에서는 허가받은 사용자가 아니면 GPU Instance를 사용할 수 없다는 문제</strong>가 있어서 GCP에서 GPU Instance를 이용하여 구현하였습니다.</p>
<p>NCP를 이용한 서버는 Spring Boot Server인데, 위에서 언급했던 Load balancer, Server, Object Storage 등의 서비스를 적절히 이용하여 필요한 서비스들을 구현하였습니다.</p>
<h2 id="ncloud-사용-중-특히-만족했던-점과-아쉬웠던-점은-무엇인가요">Ncloud 사용 중 특히 만족했던 점과, 아쉬웠던 점은 무엇인가요?</h2>
<p>가장 만족스러웠던 점은 역시 <strong>Server의 성능</strong> 및 <strong>한국어 친화적인 콘솔과 Document</strong> 아닐까 싶습니다.</p>
<p>물론 타 Cloud Platform에서도 어느정도 비용을 지출하면 좋은 성능의 Server를 이용할 수 있겠지만, 넉넉한 Credit으로 부담 없이 AWS Free tier보다 월등히 좋은 성능의 Server를 이용할 수 있던 점이 좋았습니다.</p>
<p>또한 여러 서비스의 Document들이 한국어로 작성되어 있어 단순한 기계번역이 많은 AWS Document보다 훨씬 읽기 쉽고 설명도 친절해서 더욱 쉽게 사용할 수 있었습니다.</p>
<p>아쉬웠던 점은 <strong>Elastic IP에 부과되는 비용</strong>과 <strong>중지시에도 부과되는 Server 요금</strong> 이었습니다. 물론 Credit으로 사용하긴 했지만.. Terminate시에는 요금이 부과되지 않는 타 Cloud Platform과 달리 꺼놓고 있어도 요금이 나가서 그냥 항상 켜고 있었던 것 같습니다. 또 안정적인 ssh 연결 및 서버 운영을 위해서는 고정 IP가 항상 필요했는데, 한 IP 부터 요금이 부과되는 점이 조금 아쉬웠던 것 같습니다.</p>
<h2 id="green-developers-프로그램-참여-소감-말씀-부탁-드립니다">Green Developers 프로그램 참여 소감 말씀 부탁 드립니다.</h2>
<p>Green Developers를 통해 국내 개발자를 위해 최적화된 NCP의 뛰어난 서비스 (Server, Object Storage) 등을 사용해볼 수 있었어서 너무 좋은 경험이었습니다.</p>
<p>Oracle, AWS, GCP 이외에 더 새로운 클라우드 플랫폼을 이용해볼 수 있었다는 점에서 더 재밌었던 것 같습니다!</p>
<h2 id="마지막-한-말씀-부탁-드립니다">마지막 한 말씀 부탁 드립니다.</h2>
<h3 id="프로젝트-결과">프로젝트 결과</h3>
<table>
<thead>
<tr>
<th>수상1</th>
<th>수상2</th>
</tr>
</thead>
<tbody><tr>
<td><img src="https://velog.velcdn.com/images/tl_dr/post/6be12dfa-7904-4e88-9087-83860ed07a1c/image.png"></td>
<td><img src="https://velog.velcdn.com/images/tl_dr/post/80ec8f5c-1f65-42ef-ab67-a479d3f84aa4/image.png"></td>
</tr>
</tbody></table>
<p>졸업작품이자 동시에 교내 경진대회 출품작이기도 했던 우리 하지마 서비스는 참여했던 두 대회에서 모두 상을 수상할 수 있었다.</p>
<p>FastAPI Server를 처음 구현해보는 팀원이 있어 많이 도와주기도 했고, 또 Spring Boot 3을 처음 사용해본 프로젝트여서 NCP 사용과는 별개로 많이 삽질했던 기억이 남는 프로젝트였다.</p>
<p>다만 Object Storage와 Server 등 필요한 인프라를 구축할 때는 NCP의 문서가 너무 잘 준비되어 있어 편하게 구축했었다.</p>
<p>제일 힘들었던건 Certificate Manager와 Load Balancer를 연동하는거였는데.. 이제는 Certificate Manager에서 직접 인증서를 발급받을 수도 있다고 하니 더 쉬워질 것 같다.</p>
<p>삽질도 많고 새벽까지 학교 연구실을 못 벗어나는 일도 많았던 프로젝트.. 그래도 결과가 좋아서 다 좋았었다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[IntelliJ SpringBoot HotSwap 설정으로 빠른 재시작하기]]></title>
            <link>https://velog.io/@tl_dr/IntelliJ-SpringBoot-HotSwap</link>
            <guid>https://velog.io/@tl_dr/IntelliJ-SpringBoot-HotSwap</guid>
            <pubDate>Tue, 09 May 2023 13:56:20 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tl_dr/post/f842f577-57ba-4590-8153-3663de20e93d/image.png" alt=""></p>
<h2 id="tldr">TL;DR</h2>
<ol>
<li>Gradle에 <code>developmentOnly(&quot;org.springframework.boot:spring-boot-devtools&quot;)</code>  를 추가합니다.</li>
<li>실행 → 구성 편집 / 옵션 수정 → &#39;Update&#39; 작업 시 → &quot;클래스를 핫스왑하고 실패할 경우 트리거 파일을 업데이트합니다&quot; 를 클릭합니다.</li>
<li>저장 후 <strong>디버그 모드</strong> 로 Spring Boot Server를 재실행해줍니다.</li>
<li>파일 작업 후 빌드(Ctrl + F9) 실행시 위 스샷과 같은 팝업 표시 → &quot;다시 로드&quot; 클릭시 작업내용이 서버에 바로 반영됩니다</li>
</ol>
<h4 id="출처">출처</h4>
<p><a href="https://www.jetbrains.com/help/idea/spring-boot.html#application-update-policies">IntelliJ 공식 문서</a></p>
<h2 id="본문">본문</h2>
<p>스프링 부트를 공부하던 중 매번 파일을 수정하고 서버를 켜는 것이 너무 귀찮아져서... Vue나 Nuxt, Live Server 같은 Hot Reload 기능이 없을까? 하고 찾아보던 찰나에 스프링부트에서도 &quot;Hot Swap&quot; 이라는 기능을 제공한다는 것을 알게 되었습니다.</p>
<p>다만 현재 구글링해서 나오는 글들은 다 오래전에 작성된 글이, 또 과거에는 필요했을지 모르지만 지금은 필요없는 세팅들도 포함되어있어 작성일 기준 버전으로 가장 빠른 세팅방법을 공유하고자 합니다.</p>
<h3 id="적용-환경">적용 환경</h3>
<pre><code>Windows 10
Java 11
Spring Boot 2.7.11 (Gradle)
IntelliJ IDEA Ultimate 2022.1.4</code></pre><h3 id="설정-방법">설정 방법</h3>
<ol>
<li><p>build.gradle에 <code>dependencies</code> 항목에 아래 의존성을 추가합니다.</p>
<pre><code>dependencies {
 ...
 implementation &#39;org.springframework.boot:spring-boot-devtools:2.6.3&#39;
 ...
}</code></pre><p>인텔리제이에서 최신버전으로 업데이트 가능하다고 경고를 표시하는데, 최신버전(3.0.4)로 업데이트시 Java17 이상부터 사용 가능하다면서 빌드에러가 납니다.</p>
</li>
<li><p>실행 → 구성 편집
<img src="https://velog.velcdn.com/images/tl_dr/post/9eb70e9c-879a-4a66-bd45-221d3e197845/image.png" alt=""></p>
</li>
<li><p>빌드 및 실행에서 &quot;옵션 수정&quot;을 선택합니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/fbfb2b6f-9d43-44f0-bf77-ea672a372e8c/image.png" alt=""></p>
</li>
<li><p>Spring Boot → &#39;Update 적용 시&#39; → 클래스를 핫스왑하고 실패할 경우 트리거 파일을 업데이트합니다. 를 선택합니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/db37d6d3-a3fa-4156-aaf5-2f097136b3ef/image.png" alt=""></p>
</li>
</ol>
<h3 id="설정-후-테스트">설정 후 테스트</h3>
<p>위 단계를 따랐다면 기본적인 세팅은 끝났습니다.</p>
<p>이제 컨트롤러 등 서버 내부 파일 수정 후 빌드(Ctrl+F9)시 아래와 같은 팝업이 뜹니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/c45ec879-c145-42a0-8812-b19378822118/image.png" alt=""></p>
<p>&quot;다시 로드&quot; 를 클릭하면 수정한 내용이 바로 반영됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[학교 인증으로 Github Copilot 무료 사용하기]]></title>
            <link>https://velog.io/@tl_dr/%ED%95%99%EA%B5%90-%EC%9D%B8%EC%A6%9D%EC%9C%BC%EB%A1%9C-Github-Copilot-%EB%AC%B4%EB%A3%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tl_dr/%ED%95%99%EA%B5%90-%EC%9D%B8%EC%A6%9D%EC%9C%BC%EB%A1%9C-Github-Copilot-%EB%AC%B4%EB%A3%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 18 Apr 2023 02:14:33 GMT</pubDate>
            <description><![CDATA[<h2 id="tldr">TL;DR</h2>
<ol>
<li>깃허브 코파일럿은 인증 가능한 교육기관 계정 / 오픈소스 활동 이력이 있으면 무료로 사용할 수 있어요.</li>
<li>학생 인증절차는 학생증을 직접 찍어 업로드하여 인증하면 됩니다.</li>
<li>만약 안된다면 영문 재적증명서를 발급받아 업로드하면 됩니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/ae2c31b3-db5a-4962-9cd4-a1324b77cff0/image.png" alt=""></li>
</ol>
<h2 id="깃허브-코파일럿-무료로-사용하기">깃허브 코파일럿 무료로 사용하기</h2>
<p>학생 계정이 없어도 한달간 무료로 체험해볼 수 있어요.
<a href="https://github.com/github-copilot/signup">https://github.com/github-copilot/signup</a></p>
<p>만약 인증된 대학 혹은 교육기관에 소속되어있다면, 인증을 통해 코파일럿을 무료로 사용할 수 있습니다.</p>
<p><a href="https://education.github.com/pack">https://education.github.com/pack</a>
위 사이트에서 Student Developer Pack을 신청하면 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/a3006ea6-0a77-418a-9681-aebb4a55f279/image.png" alt=""></p>
<p>위 인증을 위해 깃허브 계정에 학교 이메일을 등록해두어야 하는데요.
<a href="https://github.com/settings/emails">https://github.com/settings/emails</a></p>
<p>에서 학교 이메일을 추가할 수 있습니다.</p>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/e48f0d26-639f-4c3d-a7c4-28136ba1f917/image.png" alt=""></p>
<p>만약 인증된 교육기관인 경우 Developer Pack 신청 페이지에서 위 이미지처럼 표시되고, name of school은 이미 채워져 readonly로 표시됩니다.</p>
<p>Plan to use Github 은 자유롭게 채워줍니다.
<code>Use Private Repository</code>, <code>Use Copilot</code> 등등..</p>
<p>Continue를 통해 계속 진행해줍니다.</p>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/e8fe8373-e4ab-4277-a1a3-88b7b12d8d9c/image.png" alt=""></p>
<p>이런 페이지가 표시되며, 인증을 위해 학생증이나 증명 서류 등을 업로드하라고 합니다.</p>
<p>이때 학생증을 통해 인증하실 분들은 파일 업로드가 아닌 해당 페이지에서 <code>Take a picture</code> 를 이용하여 사진을 직접 업로드하는것을 권장드립니다.
아닌 경우 아래와 같은 추천 사항을 보게 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/e3c1ec57-9c95-4d28-b0f1-3689cd1d4f83/image.png" alt="">
업로드한 사진은 조작이 쉬우니 직접 찍어서 올리라는 내용이네요.</p>
<p>저도 처음에는 학생증을 올려 인증받으려고 시도했었는데요, 아무래도 오래 된 학생증이고 이름이 한국어로 적혀있다보니 계속 실패했습니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/312cdf43-26ee-4de7-8cbc-4e790e817bc7/image.png" alt="">
깃허브와 계속 싸운 흔적들이 보이네요</p>
<p>이런 경우는</p>
<ol>
<li>우선 깃허브 프로필에서 이름을 영문으로 변경한 뒤</li>
<li>학교 사이트에서 영문 이름을 등록하고</li>
<li>학교 내부 증명서 발급 사이트를 이용해 영문 증명서를 발급받아 인증하면 됩니다.</li>
</ol>
<p>증명서 발급비용은 아프지만.. 달에 10달러 내는 것보다는 커피 한잔 안마신다 생각하고 발급받으면 편합니다..ㅎㅎ..</p>
<p>저는 그렇게 발급받은 pdf 인증서를 pdf to jpg 사이트를 이용해 이미지로 변환하여 업로드한 후 인증에 성공했습니다.</p>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/044cd2dd-c1a2-414f-8468-cddd42809e30/image.png" alt="">
인증에 성공하면 이런 메일을 받을 수 있습니다.</p>
<p>그 후 깃헙 코파일럿 등록 페이지로 이동하면..
<img src="https://velog.velcdn.com/images/tl_dr/post/34ea5bdd-5445-4993-9ccc-7fb9ceefd291/image.png" alt="">
드디어! 무료로 코파일럿을 이용할 수 있다는 페이지를 볼 수 있습니다.
만약 인증과정이 제대로 이루어지지 않은 경우 결제 플랜이 보이게 됩니다.</p>
<p><code>Get access to GitHub Copilot</code>을 클릭해 등록하고, Vscode에서 코파일럿 Extension을 다운로드받아 깃허브를 로그인하고 나면..
<img src="https://velog.velcdn.com/images/tl_dr/post/15bad272-4624-48b5-943a-29d80090e04c/image.png" alt="">
귀여운 코파일럿이 성공적으로 등록되었습니다.</p>
<p>이제 코파일럿을 이용해 좀 더 빠른 개발을 할 수 있게 되었네요.</p>
<h2 id="마무리">마무리</h2>
<p>오늘은 이렇게 학생계정을 이용한 코파일럿 무료 사용법에 대해 알아보았습니다.
이외에도 학생계정이 있으면 Azure for Student, Office365, Intellij Student Pack, Notion Educition+ Plan 등 여러 혜택을 이용할 수 있으니 그것들도 한번 찾아보시는 것을 추천드립니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[NestJS와 Typescript5의 엇갈린 만남]]></title>
            <link>https://velog.io/@tl_dr/NestJS%EC%99%80-Typescript5%EC%9D%98-%EC%97%87%EA%B0%88%EB%A6%B0-%EB%A7%8C%EB%82%A8</link>
            <guid>https://velog.io/@tl_dr/NestJS%EC%99%80-Typescript5%EC%9D%98-%EC%97%87%EA%B0%88%EB%A6%B0-%EB%A7%8C%EB%82%A8</guid>
            <pubDate>Fri, 14 Apr 2023 15:20:29 GMT</pubDate>
            <description><![CDATA[<h3 id="들어가기에-앞서">들어가기에 앞서</h3>
<p>이 글은 작성 시점인 2023년 4월 15일을 기준으로 작성되었습니다.
시간에 따라 Nest.js와 Typescript Decorator의 구현에 차이가 있을 수 있으니 변경점을 발견하신다면 언제든 댓글 달아주세요!</p>
<h3 id="tldr">TL;DR</h3>
<ol>
<li>Typescript 5에 Decorator가 실험적 기능을 벗어나 정식 기능으로 출시되었습니다.</li>
<li>그런데 들어오면서 기존의 실험 방식과는 완전 다른 형태의 파라미터를 가지게 되었습니다.</li>
<li>해당 기능을 통해 AOP를 구현하고 있던 Nest.js는 당분간 <code>--experimentalDecorators</code>의 사용을 유지하기로 하였습니다.<h3 id="본문">본문</h3>
<h4 id="2023년-3월-16일-드디어-typescript5가-출시되었습니다">2023년 3월 16일. 드디어 Typescript5가 출시되었습니다.</h4>
자세한 변경 사항은 <a href="https://velog.io/@hustle-dev/TypeScript-5.0-%EB%B2%88%EC%97%AD">링크를</a> 참고해 주세요.</li>
</ol>
<p>이 중에서도 눈여겨 볼 점이 바로 Decorator가 정식으로 도입되었다는 점인데요, NestJS등 여러 프레임워크와 라이브러리에서 사용하고 있는 기능이니만큼 언젠가는 정식 기능으로 도입될거라고 생각했죠. 그런데....</p>
<h4 id="달라져버린-구현">달라져버린 구현</h4>
<p>기존 NestJS는 클래스 / 메소드 / 접근자 / 프로퍼티 / 매개변수 데코레이터를 제공하며 각 상황에 맞게 데코레이터 함수에 매개변수를 넣어 주고 있었습니다.</p>
<pre><code class="language-ts">// 메소드 데코레이터 예시
function deco(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  console.log(&#39;데코레이터가 평가됨&#39;);
}

class TestClass {
  @deco
  test() {
    console.log(&#39;함수 호출됨&#39;)
  }
}

// 실행 결과
데코레이터가 평가됨
함수 호출됨</code></pre>
<p>그런데 Typescript5.0의 데코레이터는 아래와 같이 다른 형식으로 구현되어 있습니다.</p>
<pre><code class="language-ts">function loggedMethod(originalMethod: any, context: ClassMethodDecoratorContext) {
    const methodName = String(context.name);

    function replacementMethod(this: any, ...args: any[]) {
        console.log(`LOG: Entering method &#39;${methodName}&#39;.`)
        const result = originalMethod.call(this, ...args);
        console.log(`LOG: Exiting method &#39;${methodName}&#39;.`)
        return result;
    }

    return replacementMethod;
}</code></pre>
<p>기존 <code>PropertyDescriptor</code>에는 이런 값들이 들어있었습니다.</p>
<pre><code class="language-ts">interface PropertyDescriptor {
  configurable?: boolean;
  enumerable?: boolean;
  value?: any;
  writable?: boolean;
  get?(): any;
  set?(v: any): void;</code></pre>
<p>그런데 새로 만들어진 <code>ClassMethodDecoratorContext</code> 에는 final 여부, 메소드 이름 등 간단한 값만 들어있고 <code>PropertyDescriptor</code>에서 제공하는 여러 값들은 더 이상 제공하지 않게 되었습니다.</p>
<p><code>PropertyDescriptor</code>를 사용하여 유저 입력 데이터의 글자수 / 정규식 검증 등을 진행하고 있는 NestJS 에게는 큰 일이 발생해버렸죠. 애초에 인터페이스도 안맞아서 쓸 수도 없었구요.</p>
<h4 id="그래서-typescript-50은-못-쓰는-건가요">그래서 Typescript 5.0은 못 쓰는 건가요?</h4>
<p>다행히 <code>--experimentalDecorators</code> 플래그를 tsconfig에서 바로 제거하지 않았고, 한동안은 제거하지 않을 것 같습니다. 그래서 기존에 Nest.js로 개발을 하시던 분들은 기존 tsconfig를 그대로 유지한 채로 Typescript 버전을 올리는 것이 가능할 것 같습니다.</p>
<h4 id="ts-50의-decorator는-언제쯤-적용할-수-있을까요">TS 5.0의 Decorator는 언제쯤 적용할 수 있을까요?</h4>
<p>이 궁금증을 해결하기 위해 Nest.js 공식 디스코드를 확인해보았습니다.
<img src="https://velog.velcdn.com/images/tl_dr/post/520a2f6a-adc7-4b2e-836c-ca897be0bbbd/image.png" alt="">
<img src="https://velog.velcdn.com/images/tl_dr/post/cf585599-be05-4bad-b0ac-fcc81b8747a5/image.png" alt="">
여러 내용들이 있는데요, 요약하자면 우선은 <code>--experimentalDecorators</code>을 그대로 유지한 채 사용하는 것을 권장하고 있습니다.
그리고 조금씩 작업을 하고 있다고는 합니다. 언제 다 끝날지는 모르겠네요😂</p>
<h3 id="결론-정리">결론 정리</h3>
<p>Typescript 5.0에서 정식으로 도입된 Decorator 기능! 하지만 기존 실험적 기능을 통해 제공되던 Decorator의 구현과 많은 부분이 달라져서, NestJS 등 기존 Decorator를 사용하던 많은 프레임워크들과 라이브러리들에게 큰 숙제를 안겨준 것 같습니다.</p>
<p>하지만 우리는 언제나 고쳐나가겠죠? 늘 그랬던 것 처럼요👩‍💻</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Vue] Dom Template에서는 Self-Closing Tag를 사용하면 안된다.]]></title>
            <link>https://velog.io/@tl_dr/Vue-Dom-Template%EC%97%90%EC%84%9C%EB%8A%94-Self-Closing-Tag%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%A9%B4-%EC%95%88%EB%90%9C%EB%8B%A4</link>
            <guid>https://velog.io/@tl_dr/Vue-Dom-Template%EC%97%90%EC%84%9C%EB%8A%94-Self-Closing-Tag%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%A9%B4-%EC%95%88%EB%90%9C%EB%8B%A4</guid>
            <pubDate>Thu, 06 Apr 2023 01:44:19 GMT</pubDate>
            <description><![CDATA[<p><a href="https://v2.vuejs.org/v2/style-guide/index.html?redirect=true#Self-closing-components-strongly-recommended">참고자료 - Vue2 공식 문서</a>
<a href="https://github.com/element-plus/element-plus/issues/4278">참고자료2 - Github Element+ Issue</a></p>
<p>Element+ 의 Table을 제작하던 중 문제가 생겼다.
나는 .vue 파일이 아니라 CDN에서 직접 vue를 다운로드받아 페이지를 생성하고 있었는데, Table 생성 예제를 그대로 복사해서 실행했더니 아래와 같이 테이블이 잘못 표시되는 문제가 생겼다.</p>
<p><img src="https://velog.velcdn.com/images/tl_dr/post/0327b91d-fd8d-4603-8832-37fc87d05bc6/image.png" alt="잘못 나온 테이블"></p>
<pre><code>// 사용한 코드
&lt;script src=&quot;//unpkg.com/vue@next&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;//unpkg.com/element-plus/dist/index.full.js&quot;&gt;&lt;/script&gt;
&lt;div id=&quot;app&quot;&gt;
  &lt;el-table :data=&quot;tableData&quot; style=&quot;width: 100%&quot;&gt;
    &lt;el-table-column prop=&quot;date&quot; label=&quot;Date&quot; width=&quot;180&quot; /&gt;
    &lt;el-table-column prop=&quot;name&quot; label=&quot;Name&quot; width=&quot;180&quot; /&gt;
    &lt;el-table-column prop=&quot;address&quot; label=&quot;Address&quot; /&gt;
  &lt;/el-table&gt;
&lt;/div&gt;
</code></pre><pre><code class="language-javascript">var Main = {
  data() {
  return {
    tableData: [
      {
        date: &#39;2016-05-03&#39;,
        name: &#39;Tom&#39;,
        address: &#39;No. 189, Grove St, Los Angeles&#39;,
      },
      {
        date: &#39;2016-05-02&#39;,
        name: &#39;Tom&#39;,
        address: &#39;No. 189, Grove St, Los Angeles&#39;,
      },
      {
        date: &#39;2016-05-04&#39;,
        name: &#39;Tom&#39;,
        address: &#39;No. 189, Grove St, Los Angeles&#39;,
      },
      {
        date: &#39;2016-05-01&#39;,
        name: &#39;Tom&#39;,
        address: &#39;No. 189, Grove St, Los Angeles&#39;,
      },
    ],
  }
},
};

const app = Vue.createApp(Main);
app.use(ElementPlus);
app.mount(&quot;#app&quot;);</code></pre>
<p>정상적으로 표시될 경우 아래와 같이 나와야 한다.
<img src="https://velog.velcdn.com/images/tl_dr/post/883d2658-e7b6-4394-9b9f-ff896b6068a4/image.png" alt=""></p>
<p>뭐가 원인인가 싶어 찾아보다 vue2 공식문서에서 그 답을 찾을 수 있었다.</p>
<p>.vue 파일 같은 SFC (Single File Component)에서는 Self Closing Component를 사용하는 것이 권장되지만, DOM은 <strong>Self Closing Component를 해석할 줄 모른다는 것이다</strong></p>
<p>그래서 DOM에서는 항상 아래와 같이 컴포넌트를 작성해야 한다.</p>
<pre><code>&lt;!-- In DOM templates --&gt;
&lt;my-component&gt;&lt;/my-component&gt;
</code></pre><p>SFC나 JSX에는 아래와 같이 써도 괜찮다고 한다.</p>
<pre><code>&lt;!-- In single-file components, string templates, and JSX --&gt;
&lt;MyComponent/&gt;</code></pre><p>처음에 작성한 el-table 코드에 <code>el-table-column</code>이 Self Closing으로 작성되어 있어 테이블을 그리는 과정에서 문제가 발생한 것 같다.</p>
<p>아래와 같이 수정해주었다.</p>
<pre><code>&lt;el-table :data=&quot;tableData&quot; style=&quot;width: 100%&quot;&gt;
      &lt;el-table-column prop=&quot;date&quot; label=&quot;Date&quot; width=&quot;180&quot;&gt;&lt;/el-table-column&gt;
      &lt;el-table-column prop=&quot;name&quot; label=&quot;Name&quot; width=&quot;180&quot;&gt;&lt;/el-table-column&gt;
      &lt;el-table-column prop=&quot;address&quot; label=&quot;Address&quot;&gt;&lt;/el-table-column&gt;
&lt;/el-table&gt;</code></pre><p>아래와 같이 잘 표시되는 것을 확인할 수 있었다.
<img src="https://velog.velcdn.com/images/tl_dr/post/753b3d50-5db2-4a0b-87e1-774ef61faeb8/image.png" alt=""></p>
<p>처음에는 Vue2에서 Vue3으로 마이그레이션하면서 생긴 문제인가 싶어 이 삽질 저 삽질 다 해봤는데 안돼서 정말 막막했는데,, 이래서 공식문서를 잘 읽어야 하나 싶다.</p>
<p>대부분 .vue 파일에서 작업하다가 이번에 좀 특수한 상황이 생겨 직접 vue를 CDN 에서 다운받은 후 작업하려다 보니 이런 처음 보는 문제들을 자주 마주치는데, 정리해두면 나중에 위와 같은 문제가 생겼을 때 참고하기 좋을 것 같다!</p>
]]></description>
        </item>
    </channel>
</rss>