<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Shin-JaeHeon</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 04 Feb 2026 15:01:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Shin-JaeHeon</title>
            <url>https://images.velog.io/profiles/shin-jaeheon/thumbnails/1548386625.88.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Shin-JaeHeon. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/shin-jaeheon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[agent-skill-cast, 여러 레포에서 스킬을 관리하는 가장 쉬운 CLI]]></title>
            <link>https://velog.io/@shin-jaeheon/agent-skill-cast-%EC%97%AC%EB%9F%AC-%EB%A0%88%ED%8F%AC%EC%97%90%EC%84%9C-%EC%8A%A4%ED%82%AC%EC%9D%84-%EA%B4%80%EB%A6%AC%ED%95%98%EB%8A%94-%EA%B0%80%EC%9E%A5-%EC%89%AC%EC%9A%B4-CLI</link>
            <guid>https://velog.io/@shin-jaeheon/agent-skill-cast-%EC%97%AC%EB%9F%AC-%EB%A0%88%ED%8F%AC%EC%97%90%EC%84%9C-%EC%8A%A4%ED%82%AC%EC%9D%84-%EA%B4%80%EB%A6%AC%ED%95%98%EB%8A%94-%EA%B0%80%EC%9E%A5-%EC%89%AC%EC%9A%B4-CLI</guid>
            <pubDate>Wed, 04 Feb 2026 15:01:31 GMT</pubDate>
            <description><![CDATA[<h2 id="개발-계기">개발 계기</h2>
<p>팀에서는 레포가 여러개 있습니다. 프론트를 예로 치면 product-desktop, product-mobile 처럼 있는 셈입니다..
다들 Claude Code나 Codex 같은 AI Agent를 쓰기 때문에 스킬을 커밋하여 공유하고 있는데요.
아무래도 같은 프론트라면 공통적인 스킬들(예: 아키텍처 등)도 있을 겁니다.</p>
<p>여기서 몇가지 문제가 생깁니다.</p>
<ul>
<li>스킬 개선하면 레포마다 같은 스킬 복사해서 넣기...</li>
<li>다른 브랜치에 커밋했으면 체리픽 해오기...</li>
<li>결론 : 스킬 하나 수정하면 = 복사 × 붙여넣기 × 커밋 × N개 레포 × M개 브랜치</li>
<li>다른 팀과 공유하려면 zip으로..?</li>
</ul>
<p>게다가 public github는 보안상 쓰기 어렵기에... 어디에다 올려서 쓸 수 없었습니다.
bitbucket에 올리는거 까지는 괜찮은데 이걸 레포마다 동기화하는건 어떻게 해결하지? 라는 생각이 들었습니다.
심볼릭 링크면 이를 해결할 수 있을 것 같았고, 그래서 만든 CLI도구가 바로 agent-skill-cast 입니다.
마치 마법을 외우는거 처럼 스킬을 agent에게 장착 시키는 CLI도구입니다.</p>
<hr>
<h2 id="agent-skill-cast">Agent Skill Cast</h2>
<p>먼저 설치를 진행합니다.</p>
<pre><code class="language-bash">npm install -g agent-skill-cast</code></pre>
<ol>
<li><p><strong>스킬 소스 등록</strong> (GitHub 레포 또는 로컬 폴더)
먼저 스킬을 가져올 소스를 정합니다. </p>
<pre><code class="language-bash">cast source add https://github.com/your-team/shared-skills
cast source add ~/projects/my-skills</code></pre>
</li>
<li><p><strong>필요한 스킬 선택</strong>
인터렉티브 UI로 스킬을 선택할 수 있습니다.</p>
<pre><code class="language-bash">cast use
cast use my-skills/react</code></pre>
<p>선택한 스킬은<code>.claude/skills/</code>, <code>.gemini/skills/</code>, 또는 <code>.codex/skills/</code> 하위에 심볼릭 링크됩니다</p>
</li>
<li><p><strong>동기화</strong></p>
<pre><code class="language-bash">cast source sync</code></pre>
<p>명령으로 모든 외부 소스를 pull 받습니다. (로컬 폴더는 symbolic link라 pull X)</p>
</li>
</ol>
<h2 id="작동-방식">작동 방식</h2>
<ol>
<li>home 디렉터리에 소스를 넣습니다. (외부 레포면 clone, 로컬 폴더면 심볼릭 링크)</li>
<li><code>cast use</code>로 사용할 때마다 해당 skill을 .claude/skills 하위로 심볼릭 링크를 합니다.</li>
</ol>
<pre><code>스킬 소스 (GitHub/Local)
         ↓
~/.asc_sources/shared-skills/  ← 클론/심볼릭 링크
         ↓
    ┌────┼────┐
    ↓    ↓    ↓
프로젝트 A  B  C
.claude/skills/ → [symlinks]</code></pre><ul>
<li><strong>디스크 낭비 제로</strong>: 복사본이 아닌 심볼릭 링크</li>
<li><strong>즉시 업데이트</strong>: 소스 변경이 모든 곳에 반영</li>
<li><strong>선택적 설치</strong>: 각 프로젝트마다 다른 스킬 조합 가능</li>
</ul>
<h3 id="스킬-감지">스킬 감지</h3>
<p>소스의 폴더를 기준으로 각 agent 폴더(<code>.claude/skills</code> 등)와 1~2 depth에서 SKILL.md가 존재하는 폴더를 탐색합니다.</p>
<ul>
<li>/.claude/skills/react/SKILL.md</li>
<li>/mobile/screen/SKILL.md</li>
<li>/docs-write/SKILL.md</li>
</ul>
<p>와 같은 케이스를 모두 지원합니다.</p>
<p>따라서 실제 사용하고 있는 프로젝트를 소스로 삼거나, <a href="awesome-claude-skills">https://github.com/ComposioHQ/awesome-claude-skills</a>와 같은 외부 프로젝트를 모두 소스로 삼을 수 있습니다.</p>
<h2 id="미래">미래</h2>
<p>앞서 개발 계기에서 이야기한 것 처럼, 현재 레포의 스킬을 특정 git reop를 통해 publish하는 기능 까지 계획했었는데, 생각보다 사용자 플로우 정의가 어려워서 우선은 use에 초점을 맞췄습니다.</p>
<h2 id="사용-예시">사용 예시</h2>
<p><img src="https://velog.velcdn.com/images/shin-jaeheon/post/e72f56d5-2d52-4886-9376-50a93261e800/image.png" alt=""></p>
<p>Github : <a href="https://github.com/Shin-JaeHeon/agent-skill-cast">https://github.com/Shin-JaeHeon/agent-skill-cast</a> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[일기예보가 나오는 힙한 터미널 만들기]]></title>
            <link>https://velog.io/@shin-jaeheon/%EC%9D%BC%EA%B8%B0%EC%98%88%EB%B3%B4%EA%B0%80-%EB%82%98%EC%98%A4%EB%8A%94-%ED%9E%99%ED%95%9C-%ED%84%B0%EB%AF%B8%EB%84%90-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@shin-jaeheon/%EC%9D%BC%EA%B8%B0%EC%98%88%EB%B3%B4%EA%B0%80-%EB%82%98%EC%98%A4%EB%8A%94-%ED%9E%99%ED%95%9C-%ED%84%B0%EB%AF%B8%EB%84%90-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Fri, 10 Jun 2022 15:57:58 GMT</pubDate>
            <description><![CDATA[<p>터미널을 킬 때마다 날씨 정보가 나오면 편리할 것이다. 마치 아래처럼.</p>
<p><img src="https://velog.velcdn.com/images/shin-jaeheon/post/7b9257a7-19f8-43b0-9026-0b18eeb29a86/image.png" alt=""></p>
<p>wttr.in은 wego의 래핑으로 시작한 프로젝트로 콘솔 지향 기상 예보 서비스다. 
이미지 없이 Text만으로도 멋진 날씨 정보를 볼 수 있는 서비스다. 자세한 정보는 <a href="https://github.com/chubin/wttr.in">https://github.com/chubin/wttr.in</a> 를 참조하면 된다.</p>
<p>원문 보기 : <a href="https://jaeheon.kr/277">jaeheon.kr/277</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[당신이 몰랐던 마진 상쇄(margin collapsing)현상의 이유 요약]]></title>
            <link>https://velog.io/@shin-jaeheon/%EB%8B%B9%EC%8B%A0%EC%9D%B4-%EB%AA%B0%EB%9E%90%EB%8D%98-%EB%A7%88%EC%A7%84-%EC%83%81%EC%87%84margin-collapsing%ED%98%84%EC%83%81%EC%9D%98-%EC%9D%B4%EC%9C%A0-%EC%9A%94%EC%95%BD</link>
            <guid>https://velog.io/@shin-jaeheon/%EB%8B%B9%EC%8B%A0%EC%9D%B4-%EB%AA%B0%EB%9E%90%EB%8D%98-%EB%A7%88%EC%A7%84-%EC%83%81%EC%87%84margin-collapsing%ED%98%84%EC%83%81%EC%9D%98-%EC%9D%B4%EC%9C%A0-%EC%9A%94%EC%95%BD</guid>
            <pubDate>Mon, 25 Apr 2022 13:32:02 GMT</pubDate>
            <description><![CDATA[<p>본문 보기 : <a href="https://jaeheon.kr/274">https://jaeheon.kr/274</a></p>
<p>마진상쇄가 일어나는 것은, 문서에 비유해서 생각하면 왜 발생하는지 이해하기가 쉽다.
또한 margin을 적어도 n픽셀의 빈 공간이 있어야 한다고 생각한다면, 마진상쇄 현상을 이해하기 쉽다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[em, rem을 꼭 써야 하는 걸까?]]></title>
            <link>https://velog.io/@shin-jaeheon/em-rem%EC%9D%84-%EA%BC%AD-%EC%8D%A8%EC%95%BC-%ED%95%98%EB%8A%94-%EA%B1%B8%EA%B9%8C</link>
            <guid>https://velog.io/@shin-jaeheon/em-rem%EC%9D%84-%EA%BC%AD-%EC%8D%A8%EC%95%BC-%ED%95%98%EB%8A%94-%EA%B1%B8%EA%B9%8C</guid>
            <pubDate>Mon, 20 Dec 2021 11:31:57 GMT</pubDate>
            <description><![CDATA[<h3 id="em과-rem">em과 rem</h3>
<p>em과 rem의 차이에 대해 설명한다.</p>
<h3 id="em-rem을-꼭-써야-하는-걸까">em, rem을 꼭 써야 하는 걸까?</h3>
<p>em과 rem을 꼭 써야하는지에 대해 설명하는 문단이다.</p>
<h3 id="em과-rem을-사용하면-좋은-경우">em과 rem을 사용하면 좋은 경우</h3>
<p>em과 rem을 적절히 활용한 페이지의 예시에 관한 문단.</p>
<p>전체 내용은 <a href="https://jaeheon.kr/242">https://jaeheon.kr/242</a> 에서 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TypeScript 4.5 Update]]></title>
            <link>https://velog.io/@shin-jaeheon/TypeScript-4.5-Update</link>
            <guid>https://velog.io/@shin-jaeheon/TypeScript-4.5-Update</guid>
            <pubDate>Mon, 22 Nov 2021 01:04:22 GMT</pubDate>
            <description><![CDATA[<p>TypeScript 4.5에서 추가된 기능들</p>
<ul>
<li>Awaited 유형을 통한 Promise 개선</li>
<li>사용하지 않는 import 제거를 끄는 플래그 추가</li>
<li>in 연산자를 통해 private 필드 존재 확인</li>
<li>realpathSync.native를 통한 로드 성능 개선</li>
<li>기타 등등</li>
</ul>
<p>자세한 글은 <a href="">https://jaeheon.kr/239</a>에서 확인 가능</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[11/2 - 메타버스는 사기? 아니면 미래?]]></title>
            <link>https://velog.io/@shin-jaeheon/DailyThinking-metaverse-2021-11</link>
            <guid>https://velog.io/@shin-jaeheon/DailyThinking-metaverse-2021-11</guid>
            <pubDate>Thu, 04 Nov 2021 09:42:02 GMT</pubDate>
            <description><![CDATA[<p>메타버스에 대한, 일종의 회의론을 담은 글</p>
<p><a href="https://jaeheon.kr/228">원문 보기</a></p>
<h2 id="목차-소개">목차 소개</h2>
<h3 id="메타버스로-가득-찬-메타버스">메타버스로 가득 찬 메타버스</h3>
<p>여기도, 저기도, 온통 메타버스로 가득하다...</p>
<h3 id="원격근무는-메타버스가-아니다">원격근무는 메타버스가 아니다</h3>
<p>원격근무의 효과를 메타버스로 포장해서는...</p>
<h3 id="솔직히-메타버스가-더-불편해보인다">솔직히 메타버스가 더 불편해보인다</h3>
<p>급해서 계단을 뛰어서...</p>
<h3 id="vr-쇼핑몰이라는-예제">VR 쇼핑몰이라는 예제</h3>
<p>예전에 액티브X 때문에...</p>
<h3 id="자꾸-현실로-넘어온다">자꾸 현실로 넘어온다</h3>
<p>위에서 언급된 맥락과 유사한...</p>
<h3 id="모니터-안에서-모니터-보기">모니터 안에서 모니터 보기?</h3>
<p>적어도 메타버스 솔루션에서 무언가 다른 작업을...</p>
<h3 id="모니터에서-벗어나면-됐었네">모니터에서 벗어나면 됐었네</h3>
<p>생각해보니, 모니터에서 벗어나면 된다....</p>
<h3 id="스큐어모피즘">스큐어모피즘</h3>
<p>지금까지 메타버스는 마치 스큐어모피즘 같다...</p>
<h3 id="미니멀-메타버스">미니멀 메타버스?</h3>
<p>한 발자국 먼저 앞서서 생각해보면...</p>
<h3 id="그래도-메타버스는-좋은-솔루션이다">그래도 메타버스는 좋은 솔루션이다</h3>
<p>현실과 디지털을 통합하는 데 있어서....</p>
<h3 id="미래는-게임-소설이다">미래는 게임 소설이다!</h3>
<p>아무리 봐도 메타버스의 최종 종착지는....</p>
<h3 id="아닌가-메트릭스인가">아닌가? 메트릭스인가?</h3>
<p>빛이 게임 소설이라면 어둠은...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트 개발과 API]]></title>
            <link>https://velog.io/@shin-jaeheon/%ED%94%84%EB%A1%A0%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EA%B3%BC-API</link>
            <guid>https://velog.io/@shin-jaeheon/%ED%94%84%EB%A1%A0%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EA%B3%BC-API</guid>
            <pubDate>Tue, 05 Oct 2021 23:12:47 GMT</pubDate>
            <description><![CDATA[<p>프론트 개발에 있어서 API와 인터페이스에 관한 글.</p>
<p><a href="https://jaehoen.kr/225">https://jaehoen.kr/225</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이슈 리오픈은 개발자에게 있어서 부끄러운 일]]></title>
            <link>https://velog.io/@shin-jaeheon/%EC%9D%B4%EC%8A%88-%EB%A6%AC%EC%98%A4%ED%94%88%EC%9D%80-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90%EA%B2%8C-%EC%9E%88%EC%96%B4%EC%84%9C-%EB%B6%80%EB%81%84%EB%9F%AC%EC%9A%B4-%EC%9D%BC</link>
            <guid>https://velog.io/@shin-jaeheon/%EC%9D%B4%EC%8A%88-%EB%A6%AC%EC%98%A4%ED%94%88%EC%9D%80-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90%EA%B2%8C-%EC%9E%88%EC%96%B4%EC%84%9C-%EB%B6%80%EB%81%84%EB%9F%AC%EC%9A%B4-%EC%9D%BC</guid>
            <pubDate>Wed, 21 Apr 2021 12:00:44 GMT</pubDate>
            <description><![CDATA[<p>Resolved로 변경하기 전에, 한번 더 확인해서, 리오픈 하는 일이 없도록 노력하자!</p>
<p>본문은 <a href="https://jaeheon.kr/187">https://jaeheon.kr/187</a> 에서 확인</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 데코레이터 ]]></title>
            <link>https://velog.io/@shin-jaeheon/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0</link>
            <guid>https://velog.io/@shin-jaeheon/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0</guid>
            <pubDate>Tue, 20 Apr 2021 12:29:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/shin-jaeheon/post/cd9ab5cf-8bc8-4081-9a91-c72c60f661cc/image.png" alt="">
데코레이터 쓰고싶다와 관련된 글.</p>
<p><a href="https://jaeheon.kr/186">https://jaeheon.kr/186</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[도지코인 및 VTI ETF]]></title>
            <link>https://velog.io/@shin-jaeheon/%EB%8F%84%EC%A7%80%EC%BD%94%EC%9D%B8-%EB%B0%8F-VTI-ETF</link>
            <guid>https://velog.io/@shin-jaeheon/%EB%8F%84%EC%A7%80%EC%BD%94%EC%9D%B8-%EB%B0%8F-VTI-ETF</guid>
            <pubDate>Tue, 20 Apr 2021 12:27:51 GMT</pubDate>
            <description><![CDATA[<p>목차 </p>
<ul>
<li>필멸적인 도지코인</li>
<li>VTI</li>
</ul>
<p>자세히 보기 : <a href="https://jaeheon.kr/185">https://jaeheon.kr/185</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[일기를 쓰게 된 이유]]></title>
            <link>https://velog.io/@shin-jaeheon/%EC%9D%BC%EA%B8%B0%EB%A5%BC-%EC%93%B0%EA%B2%8C-%EB%90%9C-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@shin-jaeheon/%EC%9D%BC%EA%B8%B0%EB%A5%BC-%EC%93%B0%EA%B2%8C-%EB%90%9C-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Tue, 20 Apr 2021 12:24:00 GMT</pubDate>
            <description><![CDATA[<p>요약 : 글 쓸 거리를 많이 생각했는데, 글을 쓰는게 너무 어렵다.</p>
<p>자세히 보기 : <a href="https://jaeheon.kr/184">https://jaeheon.kr/184</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[평단가 계산기 findon.kr 공개]]></title>
            <link>https://velog.io/@shin-jaeheon/%ED%8F%89%EB%8B%A8%EA%B0%80-%EA%B3%84%EC%82%B0%EA%B8%B0-findon.kr-1.0-%EA%B3%B5%EA%B0%9C</link>
            <guid>https://velog.io/@shin-jaeheon/%ED%8F%89%EB%8B%A8%EA%B0%80-%EA%B3%84%EC%82%B0%EA%B8%B0-findon.kr-1.0-%EA%B3%B5%EA%B0%9C</guid>
            <pubDate>Sat, 13 Feb 2021 15:19:22 GMT</pubDate>
            <description><![CDATA[<h2 id="findonkr-소개">findon.kr 소개</h2>
<p>2월 4일부터 시작한 토이프로젝트 하나를 공개할 수 있게 되었다.</p>
<p>시작은 평단가 계산기지만, 금융과 관련된 기능들을 더 추가할 예정이다. 다크모드는 당연히 지원한다.</p>
<p>접속 주소는 <a href="https://findon.kr">https://findon.kr</a> 이다.</p>
<h2 id="개발-의도">개발 의도</h2>
<p>가장 큰 이유는 국내에서, 경제와 관련된 서비스들은 UI가 불친절 하거나 예쁘지 않은 경우가 많았는데, 이러한 부분을 개선하고 싶었다.</p>
<h2 id="ui-소개">UI 소개</h2>
<p><img src="https://images.velog.io/images/shin-jaeheon/post/00d55a07-3155-400b-bbb2-d7fc44230af8/image.png" alt=""></p>
<p>간단한 UI로 구성되어있다.</p>
<p><img src="https://images.velog.io/images/shin-jaeheon/post/d359b14b-19c4-4c48-847c-d52d512f5797/image.png" alt=""></p>
<p>단위 및 테마 변경이 가능하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[await의 함정, 숨은 병목을 찾자]]></title>
            <link>https://velog.io/@shin-jaeheon/await%EC%9D%98-%ED%95%A8%EC%A0%95-%EC%88%A8%EC%9D%80-%EB%B3%91%EB%AA%A9%EC%9D%84-%EC%B0%BE%EC%9E%90</link>
            <guid>https://velog.io/@shin-jaeheon/await%EC%9D%98-%ED%95%A8%EC%A0%95-%EC%88%A8%EC%9D%80-%EB%B3%91%EB%AA%A9%EC%9D%84-%EC%B0%BE%EC%9E%90</guid>
            <pubDate>Mon, 04 May 2020 13:15:14 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글의 원본은 <a href="https://jaeheon.kr/161">https://jaeheon.kr/161</a> 입니다.</p>
</blockquote>
<h3 id="await과-async">await과 async</h3>
<p>자바스크립트에서 <code>async</code>, <code>await</code>을 사용하면 좀 더 깔끔한 코드를 작성할 수 있습니다. 하지만, 적절하게 사용하지 않으면 적지 않은 시간을 사용해야할 수도 있습니다. 특히, 여러개의 <code>await</code>을 사용할 경우에 주의해야합니다.</p>
<p><img src="https://images.velog.io/images/shin-jaeheon/post/891d3bbe-4e5c-42e4-af34-fee6afa01296/carbon%20(8).png" alt="">
위와 같은 코드가 있을 때, <code>end</code>를 보려면 얼마나 기다려야할까요?</p>
<p><code>2700ms</code>를 기다려야합니다. 생각보다 긴 시간입니다.</p>
<p><img src="https://images.velog.io/images/shin-jaeheon/post/8e943eb5-79a3-4ba4-8c46-a100169be85b/carbon%20(10).png" alt=""></p>
<p><code>Promise.all</code>를 사용해서 시간을 단축해보았습니다. 이제는, <code>1900ms</code>만 기다리면됩니다. <code>800ms</code>나 줄였습니다.</p>
<p>하지만 아직 개선의 여지가 있어보입니다. </p>
<p><img src="https://images.velog.io/images/shin-jaeheon/post/18ed7a27-0a3c-4790-832d-22d3a85b060a/carbon%20(11).png" alt=""></p>
<p>자, 이제 <code>1200ms</code>면 모든 작업을 끝내고, <code>end</code>를 볼 수 있습니다. API의 응답시간 개선 없이 <code>1700ms</code>를 단축했습니다.</p>
<h3 id="왜-이런-차이가-발생할까요">왜 이런 차이가 발생할까요?</h3>
<p><code>async</code>, <code>await</code>을 사용하는 목적은 코드를 동기식으로 작성하기 위함입니다.</p>
<p>1개만 있을 때에는 크게 문제가 되지 않지만, 두 개 이상의 <code>await</code>을 사용할 시에는 의존관계를 면밀히 살펴봐야 할 필요가 있습니다.</p>
<p>예를 들어, <code>read</code>와 <code>readSomething</code>은 &#39;독립적인 관계&#39;를 가진 함수입니다. <code>read</code>를 먼저 호출하나, <code>readSomething</code>을 먼저 호출하나 서로에게 영향을 주지 않습니다.</p>
<p>반대로, <code>readThat</code>과 <code>checkValidKey</code>는 &#39;의존적인 관계&#39;을 가진 함수입니다. 반드시, <code>readThat</code>이 선행되어야, <code>checkValidKey</code>를 호출할 수 있습니다.</p>
<p>또, <code>read</code>와 <code>readSomething</code>은 <code>readThat</code>, <code>checkValidKey</code> 2개의 함수와 &#39;독립적인 관계&#39;를 가진 함수입니다. 세가지 작업을 동시에 비동기적으로 진행하여도 무방합니다.</p>
<p>&#39;의존적인 관계&#39;에서는 <code>await</code>을 사용하여 동기식으로 작성하여도 무방합니다. 동기적으로 동작하여야하는 코드이니깐요.</p>
<p>그러나, &#39;독립적인 관계&#39;에서는 위의 예시처럼 <code>Promise.all</code>을 사용하거나, 아래와 같이 사용할 수도 있습니다.
<img src="https://images.velog.io/images/shin-jaeheon/post/144ac3cc-7a13-4385-9384-2d692c8bc3e3/carbon%20(12).png" alt="">
위의 예시에서, <code>run1</code>, <code>run2</code>, <code>run3</code>은 동시에 시작합니다.</p>
<p><code>run2</code> 와 <code>run3</code>은 <code>run1</code> 보다 빨리 끝났지만, <code>run1</code>이 아직 끝나지 않아, <code>run1</code>이 끝날 때 까지 기다리게 됩니다.
<img src="https://images.velog.io/images/shin-jaeheon/post/ff6cd1da-5d22-45be-8b20-175bd7890c04/carbon%20(13).png" alt="">
&#39;후속 작업&#39;이 존재하면, 그것을 우선적으로 <code>await</code> 하여, 가능한 빨리 후속 작업을 호출할 수 있도록 하면 됩니다.</p>
<p>일반적인 경우에, <code>await</code>을 사용하는 것이 더 깔끔한 코드를 작성할 수 있도록 해줍니다. 또한 대부분의 경우에 API 호출에 오래 걸리지 않습니다. 그렇기 때문에, 적극적으로 <code>await</code>을 사용하는 것을 추천드립니다.</p>
<p>하지만, API가 느리거나, 최적화를 원하는 경우(라고 쓰지만, <code>100ms</code>라도 로딩시간을 줄일 수 있으면 줄이는 것은 매우 좋습니다)에는, 대부분의 경우에 <code>Promise.all</code>같은 기법을 사용해야합니다.</p>
<h3 id="두-줄-요약">두 줄 요약</h3>
<ol>
<li><p><code>await</code>은 동기식으로 코드를 만들어줌으로, 주의가 필요하다.</p>
</li>
<li><p><code>Promise.all</code>이나, 적절한 <code>await</code> 배치로, 많은 시간을 절약할 수 있다.</p>
</li>
</ol>
<p>[ 수정내용 ]</p>
<ul>
<li>2020.04.30 가독성을 증대하였습니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Vue.js용 네이버 지도 라이브러리]]></title>
            <link>https://velog.io/@shin-jaeheon/Vue.js%EC%9A%A9-%EB%84%A4%EC%9D%B4%EB%B2%84-%EC%A7%80%EB%8F%84-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-vue-naver-maps</link>
            <guid>https://velog.io/@shin-jaeheon/Vue.js%EC%9A%A9-%EB%84%A4%EC%9D%B4%EB%B2%84-%EC%A7%80%EB%8F%84-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-vue-naver-maps</guid>
            <pubDate>Mon, 14 Oct 2019 10:46:00 GMT</pubDate>
            <description><![CDATA[<h1 id="소개">소개</h1>
<p><code>vue-naver-maps</code>는 <code>Naver Maps JavaScript API v3</code>을 <code>Vue.js</code>에서 간편하게 이용하게 할 수 있는 라이브러리입니다.</p>
<blockquote>
<p>이 라이브러리는 MIT 라이선스로 배포되고 있습니다.</p>
</blockquote>
<p>2019년 10월 14일 기준으로 최신 버전은 v0.11.9입니다. 비록 0.x 버전의 라이브러리지만 충분히 사용이 가능한 수준입니다.
사용시에 오류가 발생하거나 궁금하신 점이 있으시다면 깃허브에 이슈를 남겨주시면, 감사하겠습니다.</p>
<h1 id="문서">문서</h1>
<p><a href="https://shin-jaeheon.github.io/vue-naver-maps/#/">한국어 문서</a></p>
<h1 id="특징">특징</h1>
<ul>
<li>자바스크립트의 기본 타입만으로도 사용이 가능합니다.</li>
<li><code>Nuxt.js</code>에서도 사용이 가능합니다.</li>
<li><code>@click</code>등 <code>Vue.js</code> 스타일로 코딩이 가능합니다.</li>
</ul>
<h1 id="계획">계획</h1>
<p>Vue.js 3.0이 출시가 되면, TypeScript 지원을 위한 개발을 시작할 예정입니다. 아마 TypeScript 지원을 시작하면 버전을 1.0.0으로 바꿀 수 있지 않을까 싶네요. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ES6로 문자열의 바이트(Byte) 수 구하기]]></title>
            <link>https://velog.io/@shin-jaeheon/ES6%EB%A1%9C-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%98-%EB%B0%94%EC%9D%B4%ED%8A%B8Byte-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@shin-jaeheon/ES6%EB%A1%9C-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%98-%EB%B0%94%EC%9D%B4%ED%8A%B8Byte-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 23 Mar 2019 10:34:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 필요 없는 부분이 일부 있습니다. 코드를 원하시면, &#39;함수&#39; 항목으로 이동하세요.</p>
</blockquote>
<h2 id="1-계기">1. 계기</h2>
<p>Share Links는 반응형 바둑판 레이아웃(항목의 가로길이는 고정, 세로길이는 유동적)를 사용합니다. 한마디로 말해서 핀터레스트(Pinterest)의 레이아웃입니다. <code>flex</code>나 <code>grid</code>로 하려했으나 실패해 결국에는 자바스크립트의 힘을 빌렸습니다. 처음에 핀터레스트는 어떻게 구현한건지 살펴보니 일일이 <code>top</code>과 <code>left</code>를 때려박아서(...) 만들어져있었습니다.</p>
<p>여하튼 한번 만들어놓고 잘 썼었습니다만, 태그 목록이 길어지면 <code>overflow:auto</code> 시켜서 가로스크롤로 표현하는 대신, 세로를 <code>height:auto</code>로 설정해 스크롤 없이 표현하는 것으로 레이아웃을 변경하려고 했습니다. 또한 제목이 길어지면 역시 태그처럼 스크롤을 생성하지 않게 레이아웃을 변경하려했습니다. 이제 auto로 늘어난 만큼을 계산해서 전체 카드의 <code>height</code>를 구하는 것이 관건이었습니다. </p>
<h2 id="2-문제점">2. 문제점</h2>
<p>자바스크립트에서 <code>.length</code>는 한글이나 영어나 한글자로 취급해 반환합니다. 하지만 렌더링상으로는 전각과 반각문자이기 때문에, 차지하는 넓이는 다릅니다.
저는 <code>&quot;와 문자열이다!&quot;.getLength()</code>의 길이가 <code>14</code>로 취급되는 것을 원했기 때문에, 바이트값으로 문자열의 길이를 측정할 방법이 필요하다고 생겼습니다.</p>
<p>물론 모노(Mono)글꼴을 사용하지 않으면 글자들이 각기 다른 넓이를 갖고 있지만 한글/한자 = 2, 반각문자 = 1, 정도로 계산해도 충분하기 때문에 넘어 갈 수 있습니다.</p>
<h2 id="3-함수">3. 함수</h2>
<blockquote>
<p>원본 코드는 <a href="https://programmingsummaries.tistory.com/239">https://programmingsummaries.tistory.com/239</a> 에 소개되어있는 코드 중 &#39;개선된 FOR문&#39;의 코드입니다.</p>
</blockquote>
<p>아래의 코드는 해당 코드를 map과 reduce를 대신하여 사용한 것입니다. 또한 바이트 수를 구하는 부분은 해당 글에 달려 있는 댓글 중 &#39;노예&#39;라는 분이 써주신 EUC-KR용(2바이트) 코드를 사용했습니다. 만약에 한글을 3바이트로 계산하는 코드가 필요하다면 아래에서 일부 코드를 &#39;개선된 FOR문&#39; 코드에서 따와서 고치면 됩니다.</p>
<h3 id="원리">원리</h3>
<p>원리는 아래와 같습니다.
먼저, map과 reduce를 쓰기 위해 문자열을 배열로 쪼갭니다.
그 다음으로, map으로 각 문자의 문자 코드 배열을 만듭니다. 이 과정을 생략하려면 charCodeAt(0)을 reduce 부분에 2번 해주어야합니다.
이제 계산식을 사용해서 reduce로 값을 구해주면 됩니다.</p>
<h3 id="코드">코드</h3>
<pre><code class="language-javascript">function getByte(str) {
  return str
    .split(&#39;&#39;) 
    .map(s =&gt; s.charCodeAt(0))
    .reduce((prev, c) =&gt; (prev + ((c === 10) ? 2 : ((c &gt;&gt; 7) ? 2 : 1))), 0); // 계산식에 관한 설명은 위 블로그에 있습니다.
}</code></pre>
<h2 id="4-여담">4. 여담</h2>
<p>여담으로, 이 글은 <a href="https://jaeheon.kr/123">https://jaeheon.kr/123</a> 에도 올라와있습니다. 하지만, 분명이 블로그 글이 원본임에도 불구하고 velog에 작성하면서 싹 고친것 + velog의 깔끔한 UI덕분에 velog가 훨씬 더 좋습니다. 물론 여기에 쓰면서 개선된 부분을 블로그에 다시 옮겨 붙이긴 했습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[velog에서 마크다운 문법의 코드가 작동하지 않는경우]]></title>
            <link>https://velog.io/@shin-jaeheon/2019-01-25-1201-%EC%9E%91%EC%84%B1%EB%90%A8-d5jrbhq9a1</link>
            <guid>https://velog.io/@shin-jaeheon/2019-01-25-1201-%EC%9E%91%EC%84%B1%EB%90%A8-d5jrbhq9a1</guid>
            <pubDate>Fri, 25 Jan 2019 03:36:24 GMT</pubDate>
            <description><![CDATA[<p>리스트에서는 `code`으로 표현해도 폰트는 바뀌지만, 장식은 생기지 않는다.
<img src="https://images.velog.io/post-images/shin-jaeheon/d6876cb0-2051-11e9-a505-e73ed337bbbb/image.png" alt="image.png">
한가지 더 실험해 보니, 코드 블럭은 정상적으로 동작한다.</p>
<ul>
<li><pre><code class="language-javascript">const a = 1;
const b = 2;
console.log(&#39;코드블럭은 잘 된다!&#39;);</code></pre>
</li>
<li><code>코드는</code> 폰트만 바뀐다.</li>
</ul>
<p>그리고 에디터에서도 무언가 이상하게 동작한다.</p>
<p><img src="https://images.velog.io/post-images/shin-jaeheon/593c4540-2052-11e9-b6c9-058365de6dc1/image.png" alt="image.png"></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] SSH 포트를 막고 연결을 끊었을 때 복구방법]]></title>
            <link>https://velog.io/@shin-jaeheon/AWS-SSH-%ED%8F%AC%ED%8A%B8%EB%A5%BC-%EB%A7%89%EA%B3%A0-%EC%97%B0%EA%B2%B0%EC%9D%84-%EB%81%8A%EC%97%88%EC%9D%84-%EB%95%8C-%EB%B3%B5%EA%B5%AC%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@shin-jaeheon/AWS-SSH-%ED%8F%AC%ED%8A%B8%EB%A5%BC-%EB%A7%89%EA%B3%A0-%EC%97%B0%EA%B2%B0%EC%9D%84-%EB%81%8A%EC%97%88%EC%9D%84-%EB%95%8C-%EB%B3%B5%EA%B5%AC%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Fri, 25 Jan 2019 03:30:57 GMT</pubDate>
            <description><![CDATA[<p>예를 들어 <code>ufw deny 22</code>같은 명령어를 칠 사람은 거의 없겠지만, 방화벽을 켜놓고 <code>ufw allow 22</code>를 안한 경우도 있습니다. 게다가 호스팅을 사용하는 경우에는 더욱 곤란할 수 밖에 없죠. 그렇지만, AWS를 사용할 때에는 좋은 방법이 있습니다.</p>
<ul>
<li>먼저 해당 EC2 인스턴스의 디스크를 복사해서 다른 ec2 인스턴스로 엽니다. 여기서 다른 ec2 인스턴스를 여는것은, 다른 추가 디스크로 열어야 합니다.</li>
<li>해당 인스턴스로 ssh 접속을 한다.</li>
<li><code>/etc/ufw/ufw.conf</code>를 편집기로 열고 <code>ENABLED=no</code>로 바꾼다. //방화벽 종료</li>
<li>그 다음 해당 디스크로 원래 쓰던 서버의 디스크 이미지를 교체한다.</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>