<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jayce_k.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Fri, 20 May 2022 14:22:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jayce_k.log</title>
            <url>https://velog.velcdn.com/cloudflare/jayce_k/340fb2a4-3d5c-4cd5-a77f-dc5e3b8f1fb9/KakaoTalk_Photo_2022-04-08-17-26-01.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jayce_k.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jayce_k" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Mordern JavaScript Tutorial] Part 1.2.2. 코드 구조]]></title>
            <link>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.2.2.-%EC%BD%94%EB%93%9C-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.2.2.-%EC%BD%94%EB%93%9C-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Fri, 20 May 2022 14:22:36 GMT</pubDate>
            <description><![CDATA[<h1 id="코드-구조">코드 구조</h1>
<p>코드 블록 만들기</p>
<h2 id="문statement">문(Statement)</h2>
<p>어떤 작업을 수행하는 문법구조와 명령어</p>
<ul>
<li><p>문은 원하는 만큼 작성 가능</p>
</li>
<li><p>서로 다른 문은 세미콜론 ; 으로 구분</p>
</li>
<li><p>가독성을 위해 다른 문은 다른 줄에 작성하는 것이 좋음</p>
<pre><code>  alert(&#39;Hello, world!&#39;); // Hello, world!

  alert(&#39;Hello&#39;); alert(&#39;World!&#39;); // 따로 실행됨

  alert(&#39;Hello&#39;);
  alert(&#39;World!&#39;); // 가독성 UP</code></pre></li>
</ul>
<h2 id="세미콜론">세미콜론</h2>
<p>줄바꿈이 있다면 세미콜론 생략 가능</p>
<ul>
<li>대부분의 경우 줄바꿈은 자동으로 세미콜론 삽입</li>
<li>하지만 줄바꿈 = 세미콜론 이 아니거나, 세미콜론이 필요하지만 자동으로 추가하지 못하는 경우 존재</li>
</ul>
<pre><code>    [1, 2].forEach(alert) // 정상작동

    alert(&quot;에러가 발생합니다.&quot;)
    [1, 2].forEach(alert) // 에러

    // 배열은 앞에 세미콜론이 있을 것이라 가정하지 않아 아래 코드와 같음
    alert(&quot;에러가 발생합니다.&quot;)[1, 2].forEach(alert) </code></pre><h2 id="주석">주석</h2>
<ul>
<li><p>한줄 주석</p>
<pre><code>//</code></pre></li>
<li><p>구간 주석</p>
<pre><code>  /* 
  ...
  */</code></pre></li>
<li><p>중첩 주석은 불가능</p>
<pre><code>  /*
      /* 중첩 주석 ?!? */
  */ // 에러</code></pre></li>
</ul>
<p>주석은 배포 전 빌드 도구들이 자동으로 제거함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Mordern JavaScript Tutorial] Part 1.2.1. Hello, world!]]></title>
            <link>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.2.1.-Hello-world</link>
            <guid>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.2.1.-Hello-world</guid>
            <pubDate>Fri, 20 May 2022 14:21:11 GMT</pubDate>
            <description><![CDATA[<h1 id="hello-world">Hello, world!</h1>
<p>실행 환경에 독립적인 코어 자바스크립트 학습</p>
<h2 id="script-태그">&#39;script&#39; 태그</h2>
<p>html 문서 아무 위치에나 자바스크립트 프로그램을 위한 <script> 태그 삽입 가능</p>
<pre><code>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
    &lt;body&gt;
        &lt;script&gt;
            alert( &#39;Hello, world!&#39; );
        &lt;/script&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><h2 id="모던-마크업">모던 마크업</h2>
<p>과거에는 <script> 태그 내에 Type이나 Language같은 속성이 포함됨</p>
<p>현재는 사용할 이유 없음</p>
<h2 id="외부-스크립트">외부 스크립트</h2>
<ul>
<li><p>자바스크립트 코드의 양이 많은 경우 파일로 따로 저장 가능</p>
</li>
<li><p>src 속성을 통해 삽입</p>
</li>
<li><p>복수의 <script> 태그 사용 가능</p>
<pre><code>  &lt;script src=&quot;/path/script.js&quot; /&gt; // 절대 경로 위치

  &lt;script src=&quot;script.js&quot; /&gt; // 같은 폴더

  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js&quot; /&gt; // url</code></pre></li>
<li><script> 태그 내에 src 속성을 사용했다면 내부 스크립트 코드는 작성 불가능
```
  // 이건 안됨
  <script src="file.js">
      alert(1);
  </script> 

<p>  // 이렇게 써야함</p>
  <script src="file.js"></script>
  <script> alert(1); </script> 
<pre><code></code></pre></li>
</ul>
<h4 id="-html-안에-script-태그를-사용해-직접-스크립트를-작성하는-것은-피하는-게-좋음">* HTML 안에 <script> 태그를 사용해 직접 스크립트를 작성하는 것은 피하는 게 좋음</h4>
<p>스크립트를 별도로 사용하면 브라우저가 캐시에 스크립트를 저장하고, 여러 페이지에서 동일한 스크립트를 사용할 때마다 캐시에서 스크립트를 가져와 사용하므로 트래픽이 절약되고 성능이 향상될 수 있음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Mordern JavaScript Tutorial] Part 1.1.2 매뉴얼과 명세서]]></title>
            <link>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.2.-%EB%A7%A4%EB%89%B4%EC%96%BC%EA%B3%BC-%EB%AA%85%EC%84%B8%EC%84%9C</link>
            <guid>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.2.-%EB%A7%A4%EB%89%B4%EC%96%BC%EA%B3%BC-%EB%AA%85%EC%84%B8%EC%84%9C</guid>
            <pubDate>Fri, 20 May 2022 14:19:24 GMT</pubDate>
            <description><![CDATA[<h1 id="메뉴얼과-명세서">메뉴얼과 명세서</h1>
<p>자바스크립트 자료 찾기</p>
<h2 id="명세서">명세서</h2>
<ul>
<li>공식문서: ECMA-262 명세서 
<a href="https://www.ecma-international.org/publications-and-standards/standards/ecma-262/">https://www.ecma-international.org/publications-and-standards/standards/ecma-262/</a></li>
</ul>
<h2 id="매뉴얼">매뉴얼</h2>
<ul>
<li>MDN JavaScript Reference(Mozilla)
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference</a></li>
<li>MSDN(MicroSoft)
<a href="http://msdn.microsoft.com/">http://msdn.microsoft.com/</a></li>
</ul>
<h2 id="호환성-표">호환성 표</h2>
<p>새로운 기능이 특정 브라우저나 엔진에서 지원하는 지 확인하는 사이트</p>
<ul>
<li><a href="http://caniuse.com">http://caniuse.com</a></li>
<li><a href="https://kangax.github.io/compat-table">https://kangax.github.io/compat-table</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Mordern JavaScript Tutorial] Part 1.1.1. 자바스크립트란? ]]></title>
            <link>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.1.-Introduction</link>
            <guid>https://velog.io/@jayce_k/Mordern-JavaScript-Tutorial-Part-1.1.-Introduction</guid>
            <pubDate>Fri, 20 May 2022 14:15:49 GMT</pubDate>
            <description><![CDATA[<h1 id="자바스크립트란">자바스크립트란?</h1>
<p>자바스크립트가 언어로서 지닌 특징, 무엇을 만들 수 있고, 어떻게 활용하고 있는지.</p>
<h2 id="정의">정의</h2>
<h3 id="자바스크립트">자바스크립트</h3>
<p>웹페이지에 생동감을 불어넣기 위해 만들어진 언어</p>
<ul>
<li>스크립트: 자바스크립트로 작성한 프로그램</li>
<li>웹페이지의 HTML 안에서 작성하면, 웹페이지를 불러올때 실행됨</li>
<li>컴파일 필요 없이 작성&amp;실행 가능</li>
<li>자바스크립트 엔진이 있는 모든 환경에서 동작</li>
<li><blockquote>
<p>다양한 환경에서 쓰이고 있음</p>
</blockquote>
</li>
</ul>
<h3 id="자바스크립트-엔진">자바스크립트 엔진</h3>
<p>자바스크립트 가상 머신</p>
<h4 id="종류">종류</h4>
<ul>
<li>V8: chrome, opera</li>
<li>SpiderMonkey: FireFox</li>
<li>Trident/Chakra: IE</li>
<li>ChakraCore: Edge</li>
<li>SquirrelFish: Safari</li>
</ul>
<h4 id="작동-원리">작동 원리</h4>
<ol>
<li>엔진이 스크립트를 읽음</li>
<li>읽은 스크립트를 기계어로 컴파일</li>
<li>기계어 코드 실행</li>
</ol>
<p>컴파일 각 단계마다, 컴파일이 끝난 후 실행중인 코드를 분석,감시,최적화</p>
<h2 id="브라우저에서-할-수-있는-일">브라우저에서 할 수 있는 일</h2>
<ul>
<li>모던자바스크립트는 안전한 언어</li>
<li>메모리, CPU 등 로우레벨 접근 불가능</li>
<li>실행환경에 영향을 많이 받음</li>
</ul>
<h4 id="nodejs-파일-입출력-네트워크-요청-함수-지원-등">Node.js: 파일 입출력, 네트워크 요청 함수 지원 등</h4>
<h4 id="브라우저-웹페이지-조작-클라이언트-서버-상호작용-등">브라우저: 웹페이지 조작, 클라이언트-서버 상호작용 등</h4>
<ul>
<li>페이지에 새로운 HTML을 추가하거나 기존 HTML, 혹은 스타일 수정하기</li>
<li>마우스 클릭이나 포인터의 움직임, 키보드 키 눌림 등과 같은 사용자 행동에 반응하기</li>
<li>네트워크를 통해 원격 서버에 요청을 보내거나, 파일 다운로드, 업로드하기(AJAX나 COMET과 같은 기술 사용)</li>
<li>쿠키를 가져오거나 설정하기. 사용자에게 질문을 건네거나 메시지 보여주기</li>
<li>클라이언트 측에 데이터 저장하기(로컬 스토리지)</li>
</ul>
<h2 id="브라우저에서-할-수-없는-일">브라우저에서 할 수 없는 일</h2>
<ol>
<li>파일 입출력, 복사, 실행 제약</li>
<li>Same Origin Policy: 데이터 교환에 동의한 특수한 코드 없이 탭이나 창끼리 접근 불가</li>
<li>HTTP 등을 통한 승인 없이 다른 도메인 통신 불가</li>
</ol>
<h2 id="자바스크립트-강점">자바스크립트 강점</h2>
<ol>
<li>HTML/CSS와 완전히 통합 가능</li>
<li>간단한 일은 간단하게 처리 가능</li>
<li>모든 브라우저에서 기본 언어로 지원</li>
</ol>
<h2 id="자바스크립트-너머의-언어들">자바스크립트 ‘너머의’ 언어들</h2>
<p>작성 후 실행 전 자바스크립트로 변환을 지원하는 언어들</p>
<ol>
<li>CoffeeScript</li>
<li>TypeScript</li>
<li>Flow</li>
<li>Dart</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[
[MySql / MariaDB] Procedure만 Dump하기]]></title>
            <link>https://velog.io/@jayce_k/MySql-MariaDB-Procedure%EB%A7%8C-Dump%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@jayce_k/MySql-MariaDB-Procedure%EB%A7%8C-Dump%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 20 May 2022 07:05:41 GMT</pubDate>
            <description><![CDATA[<h3 id="dump">Dump</h3>
<pre><code>$ mysqldump [database_name] &gt; [file_name].sql</code></pre><h3 id="procedure만-dump">Procedure만 dump</h3>
<pre><code>$ mysqldump --routines --no-create-info --no-data --no-create-db --skip-opt [database_name] &gt; [procedure_file_name].sql</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Electron 앱 다른 OS의 실행 파일로 빌드하기]]></title>
            <link>https://velog.io/@jayce_k/Electron-%EC%95%B1-%EB%8B%A4%EB%A5%B8-OS%EC%9D%98-%EC%8B%A4%ED%96%89-%ED%8C%8C%EC%9D%BC%EB%A1%9C-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@jayce_k/Electron-%EC%95%B1-%EB%8B%A4%EB%A5%B8-OS%EC%9D%98-%EC%8B%A4%ED%96%89-%ED%8C%8C%EC%9D%BC%EB%A1%9C-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 11 May 2022 08:43:29 GMT</pubDate>
            <description><![CDATA[<h2 id="issue">Issue</h2>
<p>현재 장비 내 PC에서 실행되는 로컬 서버를 Electron-builder를 통해 앱 형태로 배포하여 Electron으로 제작된 앱과 같은 형태로 배포 및 관리하려고 한다</p>
<p>장비는 윈도우 운영체제로 동작하지만 개발은 맥OS 환경에서 진행하고 있기 때문에 그냥 빌드하면 MacOS 용 dmg 패키지가 생성된다</p>
<p>만약 프로젝트의 package.json 내에 빌드 환경을 구성하고 스크립트를 통해 빌드를 진행할 때 <code>--win --x64</code> 등의 옵션을 걸어 윈도우용 실행 파일로 빌드할 수 있었다면 좋았겠지만, 이 프로젝트의 경우 배포 환경 문제로 <code>builder.js</code> 내에 옵션을 구성하고 이를 실행시켜 빌드를 진행했기 때문에 이 방법을 사용할 수 없었다</p>
<pre><code>// ./src/builder.js

const { build } = require(&#39;app-builder-lib&#39;);
const builder = require(&#39;electron-builder&#39;);

const config = {
    extraMetadata: {
      //빌드할 electron
      main: main
    },
    productName: &#39;Server-App&#39;,
    //installer 이름
    artifactName: &#39;${productName}-Setup-${version}.${ext}&#39;,

    //...

  }

builder.build({config});// 빌드</code></pre><h2 id="해결">해결</h2>
<p><code>build()</code> 함수에서 config내에 플랫폼을 설정할 수 있는 옵션이 있을 것이라 생각하고 electron-builder 모듈을 뒤적거리다가 <code>createTargets()</code> 함수를 찾았다</p>
<pre><code>// builder.d.ts

export declare function createTargets(platforms: Array&lt;Platform&gt;, type?: string | null, arch?: string | null): Map&lt;Platform, Map&lt;Arch, Array&lt;string&gt;&gt;&gt;;
</code></pre><p>build() 함수에서 target 속성을 통해 타켓 플랫폼을 설정할 수 있는데, 이 인자의 타입인 <code>Map&lt;Platform, Map&lt;Arch, Array&lt;string&gt;&gt;&gt;</code> 을 생성해 주는 함수가 바로 이 함수였다. 그리고 이 <code>createTargets()</code> 함수에서 platforms로 전달해야할 인자의 타입인 <code>Array&lt;Platform&gt;</code>는 <code>builder.Platform</code> 내에 선언되어 있으므로 빌드하고자하는 플랫폼을 불러와 배열로 만들어 전달하면 된다.</p>
<h3 id="결과">결과</h3>
<pre><code>// ./builder.js

//builer.build(); // 기존
builder.build({ targets:builder.createTargets([builder.Platform.WINDOWS], &#39;nsis&#39;, &#39;x64&#39;), config }) // 변경</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[ReactNative] Reactotron으로 디버깅 환경 구성하기]]></title>
            <link>https://velog.io/@jayce_k/React-Native-Reactotron%EC%9C%BC%EB%A1%9C-%EB%94%94%EB%B2%84%EA%B9%85-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@jayce_k/React-Native-Reactotron%EC%9C%BC%EB%A1%9C-%EB%94%94%EB%B2%84%EA%B9%85-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 18 Apr 2022 14:34:42 GMT</pubDate>
            <description><![CDATA[<p>리액트 네이티브로 앱 개발을 진행할 때 기본적으로 사용할 수 있는 크롬 개발자 도구로도 불편함을 느끼지 못했다면 모르겠지만, 제공해 주는 정보가 빈약하고, 에뮬레이터에서 개발자 도구를 띄워서 사용하기는 불편하기 때문에 추가적으로 디버깅 환경을 구성할 필요가 있다.</p>
<p>오늘 설치할 Reactotron은 ReactJS에서도 사용할 수 있다. 
이를 사용하면 RN에서도 콘솔을 사용할 수 있고, 코드 상에서 에러가 발생한 위치를 알려주는 등 다양한 기능을 지원하기 때문에 이를 사용해 디버깅 환경을 구성할 것이다.</p>
<h4 id="reactotron이-제공하는-기능">Reactotron이 제공하는 기능</h4>
<ul>
<li>애플리케이션 상태 보기</li>
<li>API 요청&amp; 응답 표시</li>
<li>빠른 성능 벤치마크</li>
<li>애플리케이션 상태의 일부를 subscribe</li>
<li>console.log와 유사한 메시지 표시 기능</li>
<li>saga 스택 추적을 포함한 source-mapped 스택 추적으로 전역 오류 추적</li>
<li>dispatch actions like a government-run mind control experiment</li>
<li>Redux 또는 mobx-state-tree를 사용하여 상태를 핫스왑</li>
<li>sagas를 추적</li>
<li>React Native에서 이미지 오버레이 표시</li>
<li>React Native에서 비동기 저장소 추적</li>
</ul>
<h2 id="reactotron-설치">Reactotron 설치</h2>
<p>터미널에 아래 명령어를 입력하여 reactotron 어플리케이션을 설치할 것이다.</p>
<p>OS는 맥, homebrew는 3.4.6버전 기준으로 진행했으며, --cask 옵션을 통해 gui 어플리케이션을 설치할 수 있다.</p>
<pre><code>brew install --cask reactotron</code></pre><p>정상적으로 설치되었다면 어플리케이션 폴더에 Reactotron.app이 생성되었을 것이다.</p>
<h2 id="reactotron-적용">Reactotron 적용</h2>
<p>Reactotron이 정상적으로 설치되었다면, 이제 프로젝트에 Reactotron을 연동할 것이다.</p>
<p>아래 명령어를 실행하여 React Native와 Reactotron을 연동하기 위한 패키지를 설치하자.</p>
<pre><code>npm i --save-dev reactotron-react-native</code></pre><p>패키지가 설치가 완료 되었다면 프로젝트 내에 <code>ReactotronConfig.js</code> 파일을 생성한다.</p>
<p>Reactotron 공식문서에는 다음과 같이 작성하라고 적혀있다.</p>
<pre><code>import Reactotron from &#39;reactotron-react-native&#39;;

Reactotron.configure() // AsyncStorage would either come from `react-native` or `@react-native-community/async-storage` depending on where you get it from // controls connection &amp; communication settings
    .useReactNative() // add all built-in react native plugins
    .connect(); // let&#39;s connect!</code></pre><p>이후 <code>App.js</code>나 <code>index.js</code>와 같은 루트 소스에 <code>ReactotronConfig.js</code>를 불러와 적용시키면 끝이다.</p>
<pre><code>import Reactotron from &#39;reactotron-react-native&#39;;

if (__DEV__) {
    import(&#39;./ReactotronConfig&#39;).then(() =&gt; Reactotron.log(&#39;Reactotron Configured&#39;));
}</code></pre><p>위 코드를 모두 적용한 후 앱을 빌드한 후 실행하고 Reactotron도 동시에 실행시켜준다.
Reactotron에 
<code>&#39;Reactotron Configured&#39;</code>
이라는 문구가 표시된다면 정상적으로 연동된 것이다.</p>
<p>하지만 안드로이드 앱 빌드 시에 틀린 부분 없이 설정을 완료했음에도 연동이 되지 않는다면 안드로이드 에뮬레이터와 Reactotron이 사용하는 9090포트로 연결되지 않았을 가능성이 있다.</p>
<p>이때는 <code>package.json</code>에서 다음과 같이 작성한다.</p>
<pre><code>&quot;scripts&quot;: {
    &quot;android&quot;: &quot;adb reverse tcp:9090 tcp:9090 &amp;&amp; react-native run-android&quot;,
    ...
</code></pre><p>이후 <code>npm run android</code> 명령어로 안드로이드로 빌드해 실행하면 정상적으로 연동될 것이다.</p>
<h2 id="reactotron과-redux-연동하기">Reactotron과 Redux 연동하기</h2>
<p>내가 현재 진행하고 있는 프로젝트는 store로 redux를 사용하고 있다.
Reactotron에서는 이 redux 스토어에서 일어나는 action과 같은 state의 변경을 확인할 수 있다.</p>
<p>이를 연동하기 위해서는 먼저 Reactotron과 Redux 연동 패키지를 프로젝트에 설치한다.</p>
<pre><code>npm i --save-dev reactotron-redux</code></pre><p>설치가 완료되었다면 <code>ReactotronConfig.js</code>를 아래처럼 수정한다.</p>
<pre><code>import Reactotron from &#39;reactotron-react-native&#39;;

import { reactotronRedux } from &#39;reactotron-redux&#39;;

const reactotron = Reactotron
    .configure() // AsyncStorage would either come from `react-native` or `@react-native-community/async-storage` depending on where you get it from // controls connection &amp; communication settings
    .use(reactotronRedux()) // set Redux(추가)
    .useReactNative() // add all built-in react native plugins
    .connect(); // let&#39;s connect!

export default reactotron;</code></pre><p>다음은 redux store를 생성하는 <code>createStore(...)</code>가 작성된 코드로 이동해 아래처럼 수정하면 된다.
이 프로젝트의 경우는 <code>./store/index.js</code>에 위치해 있다.</p>
<pre><code>//before
import { createStore, applyMiddleware } from &#39;redux&#39;;
import thunk from &#39;redux-thunk&#39;;

import rootReducer from &#39;./modules&#39;;

const store = createStore(rootReducer, applyMiddleware(thunk));

export default store;

//after
import { createStore, applyMiddleware, compose } from &#39;redux&#39;; //compose 추가
import thunk from &#39;redux-thunk&#39;;
import Reactotron from &#39;../../ReactotronConfig&#39;; //added

import rootReducer from &#39;./modules&#39;;

const store = createStore(rootReducer, compose(applyMiddleware(thunk), Reactotron.createEnhancer())); // create store with reactotron

export default store;</code></pre><p>만약 thunk와 같은 추가적인 미들웨어를 redux에 적용하고 있었다면, <code>compose</code>를 redux에서 import해 위의 코드처럼 여러 미들웨어를 하나로 묶어 생성할 스토어에 적용할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 스킬 체크 레벨 1 합격 😅]]></title>
            <link>https://velog.io/@jayce_k/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%82%AC-%EC%B2%B4%ED%81%AC-%EB%A0%88%EB%B2%A8-1-%ED%95%A9%EA%B2%A9</link>
            <guid>https://velog.io/@jayce_k/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%82%AC-%EC%B2%B4%ED%81%AC-%EB%A0%88%EB%B2%A8-1-%ED%95%A9%EA%B2%A9</guid>
            <pubDate>Tue, 12 Apr 2022 09:18:48 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/jayce_k/post/73e27fd7-2a6d-47cc-82a0-70542864f5ae/image.png" alt=""></p>
<p>코딩테스트를 준비해보기로 했다. 
백준으로 시작하려 했는데 범위가 너무 방대해서 어디서부터 시작해야할지 모르겠어서 프로그래머스로 일단 맛부터보고 가려고 한다.</p>
<p>스킬 체크라는 단계별 테스트가 있길래 도전해 봤는데 결과는 그래도 한번에 합격.
그런데 이걸 좋아해야 하나? 백점이 아니었다면 오히려 부끄러울 기초적인 수준의 문제였는데..
대학교 1학년 때로 돌아간 기분이 들었다.</p>
<p>근데 이렇게 쉽다고 말하기에는 시간이 평균보다 오래 걸리기도 했고
오랜만에 이런 문제를 푸려고 하니까 처음엔 어... 하고 머리가 멍해져서 시간을 좀 날렸다.
코드를 쓰다 보니 어찌어찌 기억을 더듬고 쓴 느낌?</p>
<p>알고리즘 공부도 시작하고 코테도 조금씩 풀어봐야겠다.
다음 레벨을 풀기 전에 레벨 2에 적힌 알고리즘들은 공부하고 포스팅도 해야지</p>
<p>조만간 아이디어가 생기면 토이 프로젝트도 시작할 예정이다.
지금까지 열심히 놀았으니까 앞으로 바쁜건 업보라고 생각하자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 비동기 코드를 "잘" 쓰는 방법]]></title>
            <link>https://velog.io/@jayce_k/JavaScript-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%9E%98-%EC%93%B0%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@jayce_k/JavaScript-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%9E%98-%EC%93%B0%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Mon, 11 Apr 2022 14:40:56 GMT</pubDate>
            <description><![CDATA[<p>블로그 첫 포스팅을 뭘 올릴까 고민 중에 커리어리에서 자바스크립트에 관한 글을 읽게 되었다.
본문이 영어로 작성되어 있기도 하고, 알아두면 자주 써먹을 지식인 것 같아 해석과 함께 잘 정리해 두려고 한다.
출처: <a href="https://maximorlov.com/linting-rules-for-asynchronous-code-in-javascript/">14 Linting Rules To Help You Write Asynchronous Code in JavaScript
</a></p>
<h1 id="javascript에서-비동기-코드를-작성하는-데-도움이-되는-14가지-규칙">JavaScript에서 비동기 코드를 작성하는 데 도움이 되는 14가지 규칙</h1>
<p>모든 항목은 EsLint에서 제공되는 기능이며, 이를 사용하지 않더라도 비동기 코드를 더 잘 이해하는데 도움이 될 것이다.</p>
<h2 id="1-async-함수를-new-promise-생성자-안에서-사용하지-않기">1. async 함수를 new Promise 생성자 안에서 사용하지 않기</h2>
<pre><code>// ❌
new Promise(async (resolve, reject) =&gt; {});

// ✅
new Promise((resolve, reject) =&gt; {});</code></pre><p> Promise 생성자 안에서 async 함수를 쓰는 것은 문법적으로는 문제가 없지만 다음과 같은 두가지 문제를 야기한다.</p>
<blockquote>
<ol>
<li>async 함수가 던진 에러는 Promise에 reject 되지 않는다.</li>
<li>후에 다시 코드를 보았을 때 new Promise 생성자가 불필요해 보이며 제거할 수도 있다.</li>
</ol>
</blockquote>
<h2 id="2-반복문-안에서-await-사용하지-않기">2. 반복문 안에서 await 사용하지 않기</h2>
<pre><code>// ❌
for (const url of urls) {
  const response = await fetch(url);
}

// ✅
const responses = [];
for (const url of urls) {
  const response = fetch(url);
  responses.push(response);
}

await Promise.all(responses);</code></pre><p> 매 반복이 순차적으로 수행되어야 할 수도 있지만, 그렇지 않은 경우에는 매우 비효율적으로 매 작업을 기다려야한다. 비동기함수를 통해 병렬적으로 수행시켜 성능을 향상시키자.</p>
<h2 id="3-promise-생성자-안에서-return-사용하지-않기">3. Promise 생성자 안에서 return 사용하지 않기</h2>
<pre><code>// ❌
new Promise((resolve, reject) =&gt; {
  return result;
});

// ✅
new Promise((resolve, reject) =&gt; {
  resolve(result); 
  //or 
  reject(error);
});</code></pre><p> Promise 생성자 안에서는 return을 통해 값을 반환할 필요가 없다. 값을 전달해야 할 때는 resolve, 에러가 발생했다면 reject를 사용하자.</p>
<h2 id="4-변수의-변경은-한번에-하나씩-진행하기">4. 변수의 변경은 한번에 하나씩 진행하기</h2>
<pre><code>// ❌
let totalPosts = 0;

async function getPosts(userId) {
  const users = [{ id: 1, posts: 5 }, { id: 2, posts: 3 }];
  await sleep(Math.random() * 1000);
  return users.find((user) =&gt; user.id === userId).posts;
}

async function addPosts(userId) {
  totalPosts += await getPosts(userId);
}

await Promise.all([addPosts(1), addPosts(2)]);
console.log(&#39;Post count:&#39;, totalPosts);</code></pre><p> 처음 5가 더해지고, 3이 더해져 8이 될 것 같지만, 결과는 3이나 5가 출력될 것이다. 변수에 값이 쓰여지는 시점보다 두번째 함수가 변수를 읽는 시점이 더 빠르기 때문이다.</p>
<pre><code> // ✅
async function addPosts(userId) {
  const posts = await getPosts(userId);
  totalPosts += posts; // variable is read and immediately updated
}</code></pre><p> 변수를 읽어 오는 동시에 업데이트해 문제를 피할 수 있다. 경쟁 조건이 발생할 경우 잘 처리하자.</p>
<h2 id="5-중첩-콜백에-주의하기">5. 중첩 콜백에 주의하기</h2>
<pre><code>// ❌
async1((err, result1) =&gt; {
  async2(result1, (err, result2) =&gt; {
    async3(result2, (err, result3) =&gt; {
      async4(result3, (err, result4) =&gt; {
        console.log(result4);
      });
    });
  });
});

// ✅
const result1 = await asyncPromise1();
const result2 = await asyncPromise2(result1);
const result3 = await asyncPromise3(result2);
const result4 = await asyncPromise4(result3);
console.log(result4);</code></pre><p>끝도 없이 이어지는 콜백의 중첩을 콜백 지옥이라 하고, 이는 코드의 가독성이나 유지관리를 힘들게 한다. 애초에 콜백보다 async/await을 활용하자.</p>
<h2 id="6-async-함수에서-await을-리턴하지-않기">6. async 함수에서 await을 리턴하지 않기</h2>
<pre><code>// ❌
async () =&gt; {
  return await getUser(userId);
}

// ✅
async () =&gt; {
  return getUser(userId);
}</code></pre><p>어짜피 async 함수의 리턴은 promise에 래핑되므로, promise를 반환하는 비동기 함수를 굳이 await 하지 않아도 promise를 직접 반환할 수 있다. 단 try/catch 문에서는 promise의 reject를 catch할 수 없으므로 예외이다.</p>
<h2 id="7-promise에서-reject-시-error-객체를-사용하기">7. Promise에서 reject 시 Error 객체를 사용하기</h2>
<pre><code>// ❌
Promise.reject(&#39;An error occurred&#39;);

// ✅
Promise.reject(new Error(&#39;An error occurred&#39;));</code></pre><p>에러 객체를 사용하면 에러 추적 스택에 저장되기 때문에 오류가 발생한 위치를 더 쉽게 알 수 있다.</p>
<h2 id="8-nodejs---콜백-내에서-에러를-처리하기">8. Node.js - 콜백 내에서 에러를 처리하기</h2>
<pre><code>// ❌
function callback(err, data) {
  console.log(data);
}

// ✅
function callback(err, data) {
  if (err) {
    console.log(err);
    return;
  }

  console.log(data);
}</code></pre><p>콜백에 전달되는 에러는 미루거나 떠넘기지 말고 콜백 함수의 맨 처음에서 처리하고 넘어가야 한다.</p>
<h2 id="9-nodejs---콜백의-첫번째-prop은-에러">9. Node.js - 콜백의 첫번째 prop은 에러</h2>
<pre><code>// ❌
cb(&#39;An error!&#39;);
callback(result);

// ✅
cb(new Error(&#39;An error!&#39;));
callback(null, result);</code></pre><p>콜백의 첫번째 인수는 에러라는 규칙을 명심하자. 에러를 String으로 전달하거나, 에러를 전달할 필요가 없는 경우에 그 자리에 다른 prop를 전달하지 말고 null이나 undefinded를 사용하여 자리를 채워주어야 한다.</p>
<h2 id="10-nodejs---비동기-method-위주로-사용하기">10. Node.js - 비동기 Method 위주로 사용하기</h2>
<pre><code>// ❌
const file = fs.readFileSync(path);

// ✅
const file = await fs.readFile(path);</code></pre><p>fs.readFileSync는 fs.readFile와 같은 작업을 수행하는 동기 메소드이다. 문제는 Node.js에서 I/O 작업에 동기 메서드를 사용 하면 이벤트 루프가 차단된다. 꼭 동기 메소드를 사용해야 하는 경우가 아니라면 비동기 메소드를 사용하자.</p>
<h4 id="typescript에서는-promise의-타입을-확인할-수-있기-때문에-javascript에서-허용되는-여러-실수에-대해-더-상세한-eslint-규칙-설정이-가능하다">TypeScript에서는 Promise의 타입을 확인할 수 있기 때문에 JavaScript에서 허용되는 여러 실수에 대해 더 상세한 eslint 규칙 설정이 가능하다!</h4>
<h2 id="11-typescript---비동기가-아닌-함수에-await-쓰지-못하게-설정">11. TypeScript - 비동기가 아닌 함수에 await 쓰지 못하게 설정</h2>
<pre><code>// @typescript-eslint/await-thenable

// ❌
function getValue() {
  return someValue;
}

await getValue();

// ✅
async function getValue() {
  return someValue;
}

await getValue();</code></pre><p>이 규칙은 JavaScript에서는 단순히 코딩 실수로 분류되는 Promise가 아닌 함수를 await 하는 것을 허용하지 않는다.</p>
<h2 id="12-typescript---promise에서-항상-에러를-catch하도록-설정">12. TypeScript - Promise에서 항상 에러를 catch하도록 설정</h2>
<pre><code>// @typescript-eslint/no-floating-promises

// ❌
myPromise()
  .then(() =&gt; {});

// ✅
myPromise()
  .then(() =&gt; {})
  .catch(() =&gt; {});</code></pre><p>이 규칙은 Promise 이후에 반드시 .catch() 구문을 추가하게 함으로써 잠재적인 오류를 항상 처리하도록 한다.</p>
<h2 id="13-typescript---promise를-처리할-수-없는-구문에-작성하지-못하도록-설정">13. TypeScript - Promise를 처리할 수 없는 구문에 작성하지 못하도록 설정</h2>
<pre><code>// @typescript-eslint/no-misused-promises

// ❌
if (getUserFromDB()) {}

// ✅ 👎
if (await getUserFromDB()) {}

// ✅ 👍
const user = await getUserFromDB();
if (user) {}</code></pre><p>이 규칙은 조건문의 조건절과 같은 Promise를 처리할 수 없는 구문에 Promise가 위치하지 못하도록 설정한다. await 을 추가하여 Promise가 반환한 값을 기다리도록 하는 것은 가능하지만, 코드의 가독성을 생각한다면 그 이전에 변수에 반환된 결과값을 저장한 후 이를 사용하는 것이 좋을 것이다.</p>
<h2 id="14-typescript---promise를-반환하는-함수에-async를-붙이도록-설정">14. TypeScript - Promise를 반환하는 함수에 async를 붙이도록 설정</h2>
<pre><code>// @typescript-eslint/promise-function-async

// ❌
function doSomething() {
  return somePromise;
}

// ✅
async function doSomething() {
  return somePromise;
}</code></pre><p>이 규칙은 Promise를 반환하는 함수를 비동기 함수로 선언하도록 설정한다. JavaScript에서 비동기 함수에 async를 깜빡하고 적지 않아 Promise 객체 자체가 반환되어 전달받은 함수에서 에러가 발생하게끔 코드를 작성하는 경우도 잦은데, 문법 상의 오류가 아니어서 찾기 힘들 수도 때문에 유용하다고 생각한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[블로그 시작]]></title>
            <link>https://velog.io/@jayce_k/%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@jayce_k/%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Fri, 08 Apr 2022 09:56:04 GMT</pubDate>
            <description><![CDATA[<h1 id="시작하기전에">시작하기전에</h1>
<p>개발자로써 일을 시작한지 8개월 만에 (개발 공부를 시작한지는 몇년만에..) 미루고미루다 드디어 블로그를 개설함
발전도 성장도 없이 정체된 채로 시간만 보내고 있는 것 같아서 내 자신에게 변화의 계기를 주기 위해서임</p>
<p>이왕 시작한 거 개인적으로 공부한 내용들, 아님 어디서 본 흥미롭거나 나중에 보고 싶은 글, 지식들을 하나두개씩 꾸준이 올려보고자 함</p>
<p>간단하게 올릴 주제들을 몇가지 정리하고 가겠음</p>
<h2 id="1-careerly커리어리">1. Careerly(커리어리)</h2>
<p> 요즘 내가 제일 빠져있는 SNS(?)
 배민, 네이버 등 경력과 실력이 뛰어나신 현업 개발자분들이나 다양한 개발 관련 전문가분들께서 다양한 개발 지식이나 이슈, 자신의 경험, 가져야할 마음가짐 등 정말 양질의 컨텐츠를 올려주셔서 시간날 때마다 읽으려고 노력하고 있음 
 매일 아침마다 이 글 하나 읽어보라고 알림도 울려서 출근해서 업무 시작하기 전에 읽기 좋음
 그런데 이 좋은 글들을 그냥 읽기만 하고 잊고 스쳐지나가는 것이 아쉬워서 이곳에 정리하여 하나씩 남겨두고 천천히 흡수하려고 함
 <img src="https://velog.velcdn.com/cloudflare/jayce_k/862c3f0c-0172-4a85-95a0-675d5f0a8da2/IMG_6269.PNG" alt=""></p>
<h2 id="2-코딩-테스트">2. 코딩 테스트</h2>
<h4 id="boj백준--httpswwwacmicpcnet">BOJ(백준) : <a href="https://www.acmicpc.net/">https://www.acmicpc.net/</a></h4>
<h4 id="프로그래머스--httpsprogrammerscokr">프로그래머스 : <a href="https://programmers.co.kr/">https://programmers.co.kr/</a></h4>
<h4 id="sql-레벨-테스트기업-코테용-아님--solvesqlcom">sql 레벨 테스트(기업 코테용 아님) : <a href="solvesql.com">solvesql.com</a></h4>
<h4 id="swea--httpsswexpertacademycom">SWEA : <a href="https://swexpertacademy.com/main/main.do">https://swexpertacademy.com/</a></h4>
<p> 사실 이미 개발자로 취직하기도 했고, 나름 이 업계도 급여나 업무 환경이나 프로세스들이 많이 좋아졌다고 들어서 굳이 네카라쿠배같은 큰 기업을 목표로 살아야 하나..? 생각했음
 그런데 막상 겪어보니 왜 스타트업에서 더 높은 연봉을 받다가도 네카라로 이직하려는 개발자들이 있는지 알 것 같음
 지금도 뭐 네카라에 꼭 가야겠어!!는 아니지만, 적어도 도전이라도 해보고, 기회가 왔을 때 잡을 수 있는 실력과 지식은 갖춰야겠다고 생각함
 지금까지는 손 놓고 있었지만 앞으로는 조금씩 시간내서 알고리즘, 코테 공부도 꾸준히 해서 하반기나 내년 상반기 공채나 이직을 노려볼 생각</p>
<h2 id="3-개발-지식개인-공부">3. 개발 지식/개인 공부</h2>
<h4 id="nodejs-javascript-typescript-sql-git-design-pattern-java-spring-oop-functional-programming-">Node.js, Javascript, Typescript, SQL, Git, Design Pattern, Java, Spring, OOP, Functional Programming, ....</h4>
<p> 요즘 개발자 친구들이 하고 있는 얘기들을 듣고 있자면 사실 무슨 소리를 하는지 이해하기 힘들때가 있음
 워낙 내가 프로젝트 경험도 별로 없고 혼자 공부하면서 개발해오기도 했고, 지금 회사도 개발 프로세스가 워낙 구식이라 (없다고 봐도 무방...), 뭔가를 배우면서 일하기 보다는 그때그때 필요한 지식을 찾아서 적용하기 급급함
 이러다간 이직이고 뭐고 성장은 커녕 도태되겠다 싶어서 알아서 열심히 배워야겠음
 일단 지금 쓰는 언어인 Node.js부터 제대로 하자!</p>
<h2 id="4-에러-히스토리">4. 에러 히스토리</h2>
<h4 id="이미-해결한-에러-특-다시-만나면-어떻게-했는지-까먹음">이미 해결한 에러 특) 다시 만나면 어떻게 했는지 까먹음</h4>
<p> 매번 다시 찾고 고치고 찾고 고치고 찾고 고치고..
 처음에는 회사 슬랙에다가 개인 메세지로 올렸는데 보기도 힘들고 정리도 안되서 해도 안보니까 점점 안하게 되더라..
 블로그도 만들었겠다 좀 체계적으로 관리해야겠음</p>
<h2 id="5-생각나면-추가해야지">5. 생각나면 추가해야지</h2>
<p> 하여튼 열심히 하자!</p>
]]></description>
        </item>
    </channel>
</rss>