<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>the_boxer.log</title>
        <link>https://velog.io/</link>
        <description>안녕하세요</description>
        <lastBuildDate>Tue, 05 Apr 2022 15:28:21 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>the_boxer.log</title>
            <url>https://images.velog.io/images/the_boxer/profile/04b62fc0-a59f-4fcc-a0c7-fc90543cf974/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. the_boxer.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/the_boxer" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Javascript 모듈]]></title>
            <link>https://velog.io/@the_boxer/Javascript-%EB%AA%A8%EB%93%88</link>
            <guid>https://velog.io/@the_boxer/Javascript-%EB%AA%A8%EB%93%88</guid>
            <pubDate>Tue, 05 Apr 2022 15:28:21 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>개발을 하는 과정에서 어플리케이션의 크기가 커지면 공통적으로 사용되는 기능 혹은 파일을 여러개로 분리해야 합니다.</p>
</li>
<li><p>파일 단위로 분리된 소스코드를 <strong>모듈</strong>이라고 합니다.</p>
</li>
<li><p>자바스크립트에서 공통적인 기능 및 크기가 큰 파일을 여러개의 모듈로 분리하여 사용하는 소스코드에서 불러오는 방식으로 사용합니다.</p>
<h2 id="모듈의-scope">모듈의 scope</h2>
</li>
<li><p>모듈 내에서 선언된 변수들은 해당 모듈 내에서 접근 범위를 가집니다.</p>
</li>
<li><p>해당 변수들은 해당 모듈 내에서만 접근이 가능하며 다른 모듈에서 해당 변수에 접근하기 위해서는 모듈을 불러와야 합니다.</p>
</li>
</ul>
<h2 id="모듈의-평가">모듈의 평가</h2>
<ul>
<li>모듈을 사용하는 쪽에서 모듈을 로드하는 것으로 평가한다고 합니다.</li>
<li>여러 소스코드에서 하나의 모듈을 여러번 평가해도 모듈을 한번만 평가됩니다.</li>
<li>모듈을 평가하는 순간 해당 모듈내 모든 소스코드가 실행되며, 함수의 실행 및 변수 할당등이 실행됩니다.<blockquote>
<p>module.js</p>
</blockquote>
<pre><code class="language-javascript">// 해당 부분은 여러 소스코드에서 여러번 불러와도 한번만 출력됩니다.
console.log(&#39;foo&#39;)</code></pre>
</li>
</ul>
<h2 id="모듈-내보내기--불러오기">모듈 내보내기 / 불러오기</h2>
<ul>
<li>소스코드에서 다른 모듈에서 정의된 리소스(변수, 함수 등)에 접근하기 위해서는 해당 모듈에서 다른 소스코드에서 사용할 수 있도록 리소스를 내보내기 해줘야 합니다.</li>
<li>오직 모듈에서 내보내기로 지정된 리소스만 다른 소스코드에서 접근이 가능합니다.</li>
</ul>
<h2 id="모듈-시스템">모듈 시스템</h2>
<h3 id="1-commonjs">1. commonjs</h3>
<ul>
<li>서버사이드 어플리케이션(nodejs) 환경에서도 모듈을 로드할 수 있게 하는 방식입니다.</li>
<li><code>require</code> 키워드를 사용하여 모듈을 내보하며 <code>module.exports</code> 혹은 <code>exports</code> 키워드를 사용하여 모듈을 불러옵니다.</li>
<li>ES6 방식이 점점 늘어나는 추세지만 아직까지 일부 실행환경에서는 ES6 모듈 방식을 지원하지 않는 경우가 많습니다.</li>
</ul>
<h4 id="commonjs-모듈-내보내고-불러오기">commonjs 모듈 내보내고 불러오기</h4>
<ul>
<li><code>module.exports</code> 혹은 <code>exports</code> 키워드를 사용하여 모듈을 내보냅니다.</li>
<li><code>require</code> 키워드를 사용하여 지정된 모듈을 불러오며, 이는 로드한 모듈에서 내보내기된 리소스들을 <code>object</code> 형식으로 반환합니다.</li>
</ul>
<h4 id="exports-vs-moduleexports">exports vs module.exports</h4>
<ul>
<li><code>exports</code>: <code>module.exports</code> 의 숏컷 버전으로 사용하며, 실질적으로 module.exports를 가리킵니다.</li>
<li>참조 방향은 다음과 같습니다.</li>
</ul>
<pre><code>exports -&gt; module.exports -&gt; {}</code></pre><ul>
<li>실제로 <code>exports</code> 와 <code>moduel.exports</code> 를 출력해보면 빈 object가 출력됩니다.</li>
</ul>
<pre><code class="language-javascript">console.log(module.exports)
console.log(exports)

// 출력결과
{}
{}</code></pre>
<ul>
<li><code>exports</code> 는 <code>module.exports</code> 를 call by reference로 참조합니다.</li>
<li>즉, <code>exports</code>의 값을 수정하면, <code>module.exports</code> 의 값이 변하게 되지만, <code>module.exports</code> 의 값을 수정해도 <code>exports</code> 의 값은 변하지 않습니다.</li>
</ul>
<pre><code class="language-javascript">let foo = &#39;foo&#39;;

module.exports = { &#39;foo&#39;: foo };
console.log(module.exports)
console.log(exports)

// 출력 결과
{ foo: &#39;foo&#39; }
{}

let foo = &#39;foo&#39;;

exports.foo = foo;
console.log(module.exports)
console.log(exports)

// 출력 결과
{ foo: &#39;foo&#39; }
{ foo: &#39;foo&#39; }</code></pre>
<ul>
<li>다만, 내보내기시 최종적으로 리턴되는건 <code>module.exports</code> 입니다.</li>
</ul>
<blockquote>
<p>module.js</p>
</blockquote>
<pre><code class="language-javascript">let foo = &#39;foo&#39;;

module.exports = { bar: &#39;bar&#39; }
exports.foo = foo;</code></pre>
<blockquote>
<p>main.js</p>
</blockquote>
<pre><code class="language-javascript">const m = require(&#39;./module&#39;);
console.log(m);

// 출력 결과
{ bar: &#39;bar&#39; }</code></pre>
<ul>
<li><p>주의할 점으로 <code>exports</code> 를 직접 수정하면 <code>exports</code> 가 가리키는 <code>module.exports</code>가 수정되기 때문에 직접 수정하지 않습니다다.</p>
</li>
<li><p>따라서 다음의 상황에 따라 둘의 사용을 구분해서 사용한다</p>
</li>
</ul>
<blockquote>
<p>여러개의 객체를 각각 내보내는 경우 <code>exports</code> 를 사용한다.</p>
<p>하나의 객체를 내보내는 경우 <code>module.exports</code> 를  사용한다.</p>
</blockquote>
<h4 id="불러오기한-객체의-값을-수정한다면">불러오기한 객체의 값을 수정한다면</h4>
<ul>
<li>모듈에서  내보내기된 리소스들은 <code>require</code> 를 통해 반환된다고 했습니다.</li>
<li>이는 내보내기된 리소스들은 사실상 해당 값 자체가 반환되는게 아니라 복사된 값이 반환된다고 볼 수 있습니다.</li>
</ul>
<blockquote>
<p>module.js</p>
</blockquote>
<pre><code class="language-javascript">let foo = &#39;foo&#39;;

exports.foo = foo;

console.log(`module.exports in module.js: ${JSON.stringify(module.exports)}`);
console.log(`exports in module.js: ${JSON.stringify(exports)}`);

setTimeout(() =&gt; {
    console.log(`foo in module.js: ${foo}`);
}, 1000);</code></pre>
<blockquote>
<p>main.js</p>
</blockquote>
<pre><code class="language-javascript">const m = require(&#39;./module&#39;);

console.log(`before change: ${JSON.stringify(m)}`);

m.foo = &#39;testing&#39;;
console.log(`after change: ${JSON.stringify(m)}`);</code></pre>
<ul>
<li>foo 라는 변수를 정의하여 <code>module.js</code> 에서 내보내기 합니다.</li>
<li>그리고 1초 뒤에 foo를 출력합니다. 이는 <code>main.js</code> 에서 모듈을 평가하고 변수를 변경하는 시간을 기다리고 나서 출력하기 위함입니다.</li>
<li>그리고 <code>main.js</code> 에서는 모듈을 로드하고 불러오기한 변수를 수정합니다.</li>
<li>출력 결과는 다음과 같습니다.</li>
</ul>
<p><img src="https://velog.velcdn.com/cloudflare/the_boxer/d5b2f4ef-bd00-4c7d-bee3-aab8f9e0e4d0/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-04-05%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.01.37.png" alt=""></p>
<ul>
<li><code>export</code> 와 <code>module.exports</code>에는 <code>foo</code> 라는 이름으로 지정된 변수 foo가 내보내기로 지정됩니다.</li>
<li>이후 <code>main.js</code> 에서 foo 변수를 변경하면 <code>main.js</code> 에서는 변경된 값이 출력되지만, 원본 모듈에서는 변경되기 이전의 값이 출력되는 것을 볼 수 있습니다.</li>
<li>즉, 불러오기한 값은 내보내기된 값과 다른 값이며, 불러오기 하는 과정에서 해당 값이 복사되어 불러오기 된다는 것을 생각할 수 있습니다.</li>
</ul>
<h3 id="2-es6">2. ES6</h3>
<ul>
<li><code>exports</code> 키워드를 사용하여 내보내고, <code>import</code> 키워드를 사용하여 불러오기를 하는 모듈 시스템입니다.</li>
<li><code>commonjs</code> 에서는 <code>module.exports</code> 라는 객체에 내보내기할 리소스를 할당하는 방법을 사용했지만, <code>ES6</code> 에서는 해당 키워드로 내보내기할 리소스를 지정합니다.</li>
</ul>
<pre><code class="language-javascript">export const foo = &quot;foo&quot;;</code></pre>
<ul>
<li>내보내기된 리소스는 불러오는 소스측에서 <code>import</code> 키워드를 사용하여 불러오며, 내보내기된 리소스 중 사용할 리소스만 선택하여 불러옵니다.</li>
</ul>
<pre><code class="language-javascript">import { foo } from &#39;./module.js&#39;</code></pre>
<h4 id="이름을-지정하여-내보내고-불러오기">이름을 지정하여 내보내고 불러오기</h4>
<ul>
<li>내보내기 하는 리소스 명을 지정하여 내보내는 방법입니다.</li>
<li>리소스 명을 지정하며 해당 변수에 <code>export</code> 키워드를 붙입니다.</li>
</ul>
<pre><code class="language-javascript">export const foo = &quot;foo&quot;;
export const bar = () =&gt; &quot;bar&quot;;</code></pre>
<ul>
<li>혹은 여러 리소스 를 선언 후 한번에 export 할 수도 있습니다.</li>
</ul>
<pre><code class="language-javascript">const foo = &quot;foo&quot;;
const bar = () =&gt; &quot;bar&quot;;

export { foo, bar };</code></pre>
<ul>
<li>내보내기된 리소스는 <code>import</code> 키워드를 사용하여 불러올 리소스만 불러오기 할 수 있습니다.</li>
</ul>
<pre><code class="language-javascript">import { bar, foo } from &#39;./module.js&#39;;

console.log(foo);
console.log(bar());

// 출력 결과
foo
bar</code></pre>
<ul>
<li>불러오기시 모든 리소스를 가져오는 경우 <code>*</code> 을 사용하며 해당 모듈에 이름을 지정하여 불러옵니다.</li>
<li>이러한 방법으로 불러오기시, 내보내기된 모든 리소스는 object 형식으로 반환됩니다.</li>
</ul>
<pre><code class="language-javascript">import * as t from &#39;./module.js&#39;;

console.log(t.foo);
console.log(t.bar());

// 출력 결과
foo
bar</code></pre>
<h4 id="익명으로-내보내고-불러오기">익명으로 내보내고 불러오기</h4>
<ul>
<li><code>default</code> 키워드를 사용하며, 하나의 리소스를 반환하고자 하는 경우 사용합니다.</li>
</ul>
<pre><code class="language-javascript">export default function () {
    return &quot;foo&quot;;
};</code></pre>
<ul>
<li>내보내기된 리소스는 import시 이름을 지정하여 불러와 사용합니다.</li>
</ul>
<pre><code class="language-javascript">import foo from &#39;./module.js&#39;;
console.log(foo());

// 출력 결과
foo</code></pre>
<ul>
<li>오브젝트 형식으로 내보내고 불러오기</li>
</ul>
<pre><code class="language-javascript">export default {
    foo: () =&gt; &quot;foo&quot;,
    bar: () =&gt; &quot;bar&quot;,
}</code></pre>
<pre><code class="language-javascript">import baz from &#39;./module.js&#39;;
console.log(baz.foo());
console.log(baz.bar());

// 출력 결과
foo
bar</code></pre>
<ul>
<li>이 때, 내보내기 하는 모듈에서의 네이밍은 상관 없으며, 불러오기 하는 측에서 이름을 지정하여 사용합니다.</li>
</ul>
<pre><code class="language-javascript">let foo = &quot;foo&quot;;
export default foo;</code></pre>
<pre><code class="language-javascript">import bar from &#39;./module.js&#39;
console.log(bar);

// 출력 결과
foo</code></pre>
<h4 id="섞어서-사용하는-방법">섞어서 사용하는 방법</h4>
<ul>
<li>두 방식을 섞어서 하나의 리소스는 익명으로 나머지 리소스는 이름을 지정하여 내보낼 수 있습니다.</li>
</ul>
<pre><code class="language-javascript">let foo = &quot;foo&quot;;
let bar = () =&gt; &quot;bar&quot;;

export {
    foo,
    bar
}

export default &quot;baz&quot;;</code></pre>
<pre><code class="language-javascript">import testing, { bar, foo } from &#39;./module.js&#39;

console.log(foo);
console.log(bar());
console.log(testing);

// 출력 결과
foo
bar
baz</code></pre>
<ul>
<li>foo, bar 는 네이밍을 지정하여 내보내기 후 불러오기 하였으며, &quot;baz&quot; 라는 리소스는 익명으로 내보내기 후 testing 이란 네이밍으로 불러오는 상황입니다.</li>
<li>모든 리소스를 불러오는 경우 마찬가지로 <code>*</code> 을 사용하며, 이름을 지정하여 object 형식으로 불러옵니다.</li>
<li>이 때, 익명으로 반환된 리소스는 <code>default</code> 키워드로 접근합니다.</li>
</ul>
<pre><code class="language-javascript">import * as t from &#39;./module.js&#39;

console.log(t.foo);
console.log(t.bar());
console.log(t.default);</code></pre>
<h2 id="참고">참고</h2>
<ul>
<li><a href="https://www.daleseo.com/js-module-require/">https://www.daleseo.com/js-module-require/</a></li>
<li><a href="https://velog.io/@leobit/CommonJS">https://velog.io/@leobit/CommonJS</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[에러] Cannot write file ... because it would overwrite input file]]></title>
            <link>https://velog.io/@the_boxer/%EC%97%90%EB%9F%AC-Cannot-write-file-...-because-it-would-overwrite-input-file</link>
            <guid>https://velog.io/@the_boxer/%EC%97%90%EB%9F%AC-Cannot-write-file-...-because-it-would-overwrite-input-file</guid>
            <pubDate>Tue, 14 Dec 2021 15:48:57 GMT</pubDate>
            <description><![CDATA[<ul>
<li>가끔 nodejs로 된 프로젝트를 진행하다 보면 저런 에러가 발생한다.</li>
<li>nestjs를 사용하는 과정에서 에러가 발생해서 구글링을 통해 원인을 파악해 보았다.</li>
</ul>
<h3 id="outdir-옵션-관련">outDir 옵션 관련</h3>
<ul>
<li><a href="https://stackoverflow.com/questions/42609768/typescript-error-cannot-write-file-because-it-would-overwrite-input-file">overflow 링크</a></li>
<li><code>tsconfig</code>에서 <code>outDir</code>옵션을 설정했으나 빌드 폴더를 exclude 하지 않은 경우가 해당된다.</li>
<li>해당 이슈는 <code>exclude</code>에서 <code>js</code> 확장자를 제외하거나 빌드 폴더 자체를 제외시키면 해결이 된다.</li>
</ul>
<h3 id="내가-겪은-경우">내가 겪은 경우</h3>
<ul>
<li>다만 나의 경우는 <code>exclude</code>에서 빌드 폴더를 제외시키고 있었다.</li>
<li>원인을 파악해보니 간단한 문제... import 과정에서 <code>outDir</code>에 위치한 빌드된 <code>js</code>파일을 참조하고 있어서 문제가 되었다.</li>
<li>vscode에서 자동 완성시 해당 파일을 import해서 문제가 된 것으로 보인다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Promise 정리]]></title>
            <link>https://velog.io/@the_boxer/Promise-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@the_boxer/Promise-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 15 Nov 2021 15:20:24 GMT</pubDate>
            <description><![CDATA[<ul>
<li>javascript에서 Promise를 사용해 sleep 함수를 구현한다.</li>
<li>구현하면서 Promise에 대해 이해한 점을 정리해본다.<blockquote>
<p>Promise를 사용한 sleep 구현</p>
</blockquote>
</li>
</ul>
<pre><code class="language-typescript">const sleep = (time: number) =&gt; {
    return new Promise((res) =&gt; {
        setTimeout(res, time);
    })
}</code></pre>
<h3 id="promise">Promise</h3>
<ul>
<li><code>Promise</code>는 약속이다. javascript에서 시간이 오래 걸리는 로직(IO 작업)이 발생하면 이를 이벤트 큐에 삽입하고, 작업이 완료되면 결과를 받아볼 수 있게 한다.<ul>
<li><code>Promise</code>는 메인 쓰레드에게 말한다. &#39;시간이 오래 걸리는 작업이 있으니 이것은 이벤트 큐에 넣어 완료될 때 까지 기다릴게. 완료되면 너가 받아 볼 수 있게 해줄게&#39;</li>
<li>메인 쓰레드는 시간이 오래 걸리는 작업을 <code>Promise</code>에게 위임하고, 나중에 작업이 완료되면 <code>Promise</code>가 이를 메인 쓰레드에게 알려 결과를 받아볼 수 있게 한다.</li>
</ul>
</li>
<li>위 예시에서 setTimeout 시간이 오래 걸리는 로직이며, <code>Promise</code>는 이 작업이 완료되면 메인 쓰레드에게 알린다.<h4 id="해결하는-문제">해결하는 문제</h4>
</li>
<li>기존에 callback 방식은 함수를 실행하면서 함수의 로직이 종료된 이후에 실행될 로직을 함수로 받아 실행시켰다.</li>
<li>대부분 아는 이야기겠지만, 이는 callback 지옥을 생성하여 코드의 가독성이 낮아졌으며, 에러 처리도 어려웠다.</li>
<li><code>Promise</code> 는 이 두가지 문제를 해결한다<ul>
<li>callback 지옥을 없애는것</li>
<li>에러처리가 쉽도록 하는것</li>
</ul>
</li>
</ul>
<h3 id="기본-사용">기본 사용</h3>
<ul>
<li>간단한 Promise 구문을 살펴보자<pre><code class="language-typescript">function foo(flag: boolean) {
  return new Promise((res, rej) =&gt; {
      if(flag) {
          res(&#39;suc&#39;);
      } else {
          rej(&#39;fail&#39;);
      }
  })
}
</code></pre>
</li>
</ul>
<p>foo(true).then((res) =&gt; {
    console.log(res);
}, (rej) =&gt; {
    console.log(rej);
});</p>
<p>foo(false).then((res) =&gt; {
    console.log(res);
}, (rej) =&gt; {
    console.log(rej);
});</p>
<pre><code>#### resolve, reject
- Promise는 기본적으로 `2개의 인자를 받는 익명함수`를 생성자의 인자로 받는다.
- 인자로 들어가는 함수의 인자는 모두 함수이며,`resolve`, `reject`라고 지칭된다.
- 두 함수는 수행하는 역할이 다른데, Promise의 함수가 실행되는 도중 비정상적인 실행 혹은 실패할 경우 `reject`가 실행되며, 정상 실행의 경우 `resolve`가 실행된다.

#### then 구문
- Promise를 리턴하면 이를 호출하는 부분에서 `then` 구문을 사용하여 결과를 받아볼 수 있다.
- `then` 구문의 로직은 호출된 함수와 Promise 내부의 함수 로직이 모두 마무리 되면 실행된다.
- `then` 구문은 `onFulfilled`, `onRejected` 라는 2개의 함수를 인자로 받으며, 각 함수는 `하나의 인자`를 받는다.
- 각 함수는 수행하는 수행하는 역할이 다른데, 첫번째 인자로 들어가는 함수는 Promise에서 `resolve`가 호출되었을 때 실행되며, 두번째 인자로 들어가는 함수는 `reject`가 호출되었을 때 실행된다.
- 그리고 각 `resolve`와 `reject`가 실행될 때 input으로 들어가는 값은 `onFulfilled`, `onRejected`의 인자로 전달된다.

#### 위 예시의 결과
- 예시의 `foo` 함수에 true를 input으로 넣으면 함수 내부에서 flag 값에 의해 `res`로 지칭된 함수가 실행되며, false를 넣으면 `rej`가 실행된다.
- 각 `res`, `rej` 가 실행되면서 input으로 넣어지는 인자는 `then` 구문의 인자로 전달된다.
- 따라서, `foo`에 true를 전달하면 &#39;suc&#39;가 출력되며, false를 전달할 경우 &#39;fail&#39;이 출력된다.

### 에러처리
- 위 예시는 단순히 분기처리에 의해 `resolve`와 `reject`의 호출을 나뉘었다.
- Promise는 에러처리가 쉽도록 하는것을 해결한다고 했다. 다음 예시를 보자.
```typescript
function doError() {
    return new Promise((res, rej) =&gt; {
        throw new Error(&#39;throw error&#39;);
    });
}

doError().then((res) =&gt; {
    console.log(&#39;success&#39;);
}, (rej) =&gt; {
    console.log(&#39;catch error&#39;);
})</code></pre><ul>
<li><code>doError</code> 함수는 error를 throw하는 Promise를 반환한다.</li>
<li>그리고, 이를 호출하는 부분에서는 Promise의 결과에 따라 &#39;success&#39;나 &#39;catch error&#39;를 출력하게 된다.</li>
<li>기본 사용 예시에서 Promise 내부의 함수에서 에러가 발생하면 <code>reject</code>가 실행된다고 했다.</li>
<li>그리고, <code>reject</code>가 실행되면, <code>then</code> 구문에서는 <code>onRejected</code> 가 실행된다고 했다.</li>
<li>위 예시에서 Error를 던지는 순간 <code>reject</code>가 실행되며, 이를 호출하는 부분에서는 <code>onRejected</code>를 실행한다.</li>
<li>따라서, 위 예시에서 <code>catch error</code>가 출력된다.</li>
</ul>
<h3 id="sleep">sleep</h3>
<ul>
<li>이제 위의 sleep 함수를 다시 보자.<pre><code class="language-typescript">const sleep = (time: number) =&gt; {
  return new Promise((res) =&gt; {
      setTimeout(res, time);
  });
}
</code></pre>
</li>
</ul>
<p>sleep(3000).then((res) =&gt; {
    console.log(&#39;foo&#39;);
})</p>
<pre><code>- Promise의 인자로 time이라는 시간 뒤 res를 실행시키는 setTimeout을 전달한다.
- sleep 함수는 해당 Promise를 반환한다.
- sleep을 호출하는 부분에서 sleep의 인자로 시간을 전달하고, `then` 구문으로 결과를 받아본다.
- setTimeout이 `resolve`를 실행시키므로, `then` 구문에서는 `onFulfilled`를 실행하게 된다.
- 따라서, 위 예시에서 sleep에 전달된 시간 이후 `then` 구문의 `onFulfilled` 부분이 실행되며, 3초 후 &#39;foo&#39; 가 출력된다.


&gt; 틀린내용  혹은 수정이 필요한 부분이 있으면 말씀해 주시기 바랍니다.

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 모듈 관리]]></title>
            <link>https://velog.io/@the_boxer/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%AA%A8%EB%93%88-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@the_boxer/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%AA%A8%EB%93%88-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Mon, 09 Aug 2021 13:51:24 GMT</pubDate>
            <description><![CDATA[<h2 id="상황">상황</h2>
<ul>
<li>nestjs 8 버전으로 새로운 API를 개발하는 상황</li>
<li>공용 라이브러리에는 nest.js로 만든 interceptor가 있는데, 이 interceptor는 던져진 exception을 <code>instanceof</code>로 판별하여 종류에 따라 다르게 처리하고 있었다.</li>
</ul>
<h2 id="발생한-문제">발생한 문제</h2>
<ul>
<li>메인 프로세스에서 exception을 던져도 해당 interceptor에서 의도한 대로 작동하지 않는다.</li>
<li>던져진 exception은 <code>HttpException</code>으로 판별되어 처리가 돼야 했는데 <code>inctanceof</code>로 판별되지 않았다.</li>
<li>근데, console로 찍으면 <code>HttpException</code>으로 출력하는 상황</li>
</ul>
<h2 id="원인-파악">원인 파악</h2>
<ul>
<li>원인은 모듈간 다른 클래스를 사용하는 것에 있었다.</li>
<li>npm에서 의존성을 설치하는 과정에서 버전과 이름이 동일한 의존성이 설치되어 있다면, 중복으로 설치하지 않고 넘어간다.</li>
<li>API는 nest.js 8 버전이었고, 라이브러리는 nest.js 7버전으로 서로 다른버전이었기 때문에 라이브러리를 설치하는 과정에서 nest.js 7이 라이브러리의 하부 모듈로 설치되었다.</li>
<li>API에서 던져진 exception의 class는 nest.js 8에서 정의된 반면 interceptor에서 판별하는데 사용하는 exception의 class는 공용 라이브러리의 nest.js 7 버전에서 정의된 class여서 동일한 클래스명을 갖고 있지만 다른 클래스로 판별 한 것.</li>
</ul>
<h2 id="해결-방법">해결 방법</h2>
<ul>
<li>라이브러리 버전을 올려서 해결하는 방법을 생각했지만, 그렇게 하면 해당 라이브러리에 의존하는 다른 API의 호환이 깨질 수 있어서 일단은 다운그레이드를 하는 방향으로 해결하였다.</li>
<li>nest.js 7 -&gt; 8로 넘어가는 과정에서 추가되거나 변경된 기능이 많다. 언젠가 날잡고 라이브러리 버전을 올리기 전에 호환성이 맞춰지는지 확인하고 작업해야겠다...</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>