<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>uriyang_.log</title>
        <link>https://velog.io/</link>
        <description>개발자들에게 위로와 힘을 주고 싶습니다. 효율적인 시스템과 개발 문화에 관심이 많아요 ^_^</description>
        <lastBuildDate>Sun, 12 Dec 2021 16:31:42 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>uriyang_.log</title>
            <url>https://images.velog.io/profiles/uriyang_/thumbnails/1569086806.29.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. uriyang_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/uriyang_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[코드숨] 리액트 6기 - 2주차 주간회고]]></title>
            <link>https://velog.io/@uriyang_/%EC%BD%94%EB%93%9C%EC%88%A8-%EB%A6%AC%EC%95%A1%ED%8A%B8-6%EA%B8%B0-2%EC%A3%BC%EC%B0%A8-%EC%A3%BC%EA%B0%84%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@uriyang_/%EC%BD%94%EB%93%9C%EC%88%A8-%EB%A6%AC%EC%95%A1%ED%8A%B8-6%EA%B8%B0-2%EC%A3%BC%EC%B0%A8-%EC%A3%BC%EA%B0%84%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 12 Dec 2021 16:31:42 GMT</pubDate>
            <description><![CDATA[<h2 id="facts-사실-객관">Facts (사실, 객관)</h2>
<h3 id="2강-react">2강 React</h3>
<ul>
<li>react를 실습 했고, 컴포넌트를 나누고 props를 통해 값을 넘기는 방법을 실습했다.</li>
<li>react hook과 선언형 프로그래밍에 대해 배웠다.</li>
<li>관심사를 분리해서 재사용성과 확장성을 높였다.</li>
</ul>
<hr>
<h2 id="feelings-느낌-주관">Feelings (느낌, 주관)</h2>
<ul>
<li>react 코드를 오랜만에 하니 중간중간 조금씩 헷갈리는 문법들이 있었다. 빨리 익숙해지고 싶다.</li>
<li>장기 프로젝트의 주말 밤샘 배포를 마치고, 그동안 누적돼있던 피로감이 몰려와 급격한 컨디션 저조가 있었다. 1주차의 시련을 겪고 2주차에는 조금씩이라도 퇴근 후 강의를 들으려고 했는데, 개발 마지막 주다 보니 퇴근시간이 더 늦어져서 엄두를 낼 수가 없었다. 두통과 감기 기운 가운데 기존에 하고 있던 스터디 참석과 &quot;코드숨&quot; 강의를 듣고 실습까지는 했으나, 내일은 모니터링 때문에 일찍 출근해야 해서 과제까지는 손을 못 댈 것 같다.</li>
<li>다음 주에 밀린 과제들을 모두 해치워야겠다.</li>
<li>나 자신은 처음부터 참석 자체가 목적에 더 가까웠던지라 어느 정도 상황을 감수하고 있지만, 저조한 참여율 때문에 트레이너님들이 사기가 떨어지게 되면 어떨까 하는 염려가 들기 시작했다.</li>
</ul>
<hr>
<h2 id="findings-배운-점">Findings (배운 점)</h2>
<ul>
<li>좋은 수업을 듣고 좋은 기회를 만난다 하더라도, 결국 내가 준비되어 있지 못하면 그만큼 얻어 가지 못하는 법. 여러 가지 의미의 &quot;선택과 집중&quot;에 대해 생각해 보게 된다.</li>
<li>건강관리를 잘하자.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드숨] 리액트 6기 - 1주차 주간회고]]></title>
            <link>https://velog.io/@uriyang_/%EC%BD%94%EB%93%9C%EC%88%A8-%EB%A6%AC%EC%95%A1%ED%8A%B8-6%EA%B8%B0-1%EC%A3%BC%EC%B0%A8-%EC%A3%BC%EA%B0%84%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@uriyang_/%EC%BD%94%EB%93%9C%EC%88%A8-%EB%A6%AC%EC%95%A1%ED%8A%B8-6%EA%B8%B0-1%EC%A3%BC%EC%B0%A8-%EC%A3%BC%EA%B0%84%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 05 Dec 2021 11:35:08 GMT</pubDate>
            <description><![CDATA[<h2 id="facts-사실-객관">Facts (사실, 객관)</h2>
<h3 id="1강-jsx">1강 JSX</h3>
<ul>
<li><strong>개발 환경 구축</strong><ul>
<li>Node.js / NPM / Webpack Dev Server / ESLint 환경 설정</li>
<li>webpack-dev-server 버전 차이로 사용법이 일부 달라진 부분이 있었다.</li>
</ul>
</li>
<li><strong>웹 개발</strong><ul>
<li>JavaScript에서의 DOM 조작과 관련한 자세한 내용들을 알 수 있었다.</li>
</ul>
</li>
<li><strong>JSX</strong><ul>
<li>JSX를 JavaScript에서 직접 구현해 봄으로 React의 원리에 대해서</li>
</ul>
</li>
<li><strong>과제 1 (let을 제거해보자)</strong><ul>
<li>처음 PR 날린 후, 코멘트 달린 부분 보충했으나 늦게 요청해서 완료 어려울 것으로 예상</li>
</ul>
</li>
<li><strong>과제 2 (간단한 사칙 연산 계산기 구현)</strong><ul>
<li>우선 초기 작업한 부분까지 PR 날렸으나, 시간 안에 완성 제출 힘들 듯</li>
</ul>
</li>
</ul>
<hr>
<h2 id="feelings-느낌-주관">Feelings (느낌, 주관)</h2>
<ul>
<li><strong>준비의 부족</strong><ul>
<li>사실 코드숨에 프로그램에 대한 지인의 얘기를 듣고 이전부터 수강을 생각하고 있었다. 이번이 좋은 타이밍이라는 생각에, 개인적인 상황들이나 프로그램 방식에 대해 자세히 염두에 두지 않고, 덜컥 신청부터 했던 나 자신에 대해 반성을 하게 됐다.</li>
</ul>
</li>
<li><strong>시간 관리</strong><ul>
<li>트레이너님이 자주 PR 올려달라는 얘기를 했었는데, 업무 핑계로 주말에 몰아서 할 생각을 했었다. 사실상 경험해 보니 몰아서 하는 게 어려운 구조였고.. 다음주가 프로젝트의 마감이라 업무량이 걱정되기는 하지만, 10~20분이라도 코드에 투자하는 시간을 가져야겠다.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="findings-배운-점">Findings (배운 점)</h2>
<ul>
<li>개발자로서 경험이 있기는 하지만 좋은 개발 문화를 많이 접해보지 못했기 때문에, 코드숨을 통해서 그런 문화들을 경험해 보고 싶었다. 하지만 초반이기도 하고, 바쁜 업무에 너무 안일하게만 생각을 했던 것 같다. 다른 분들의 리뷰들을 읽어보면서, 그런 나의 태도에 대해서 반성하게 됐다. </li>
<li>결국 내가 하는 만큼 얻어 갈 수 있다는 것을 다시금 깨달으며.. 비록 한 주는 실패했다는 생각이 들지만, 이 경험을 디딤돌 삼아 다음주부터는 좀 더 의지를 가지고 집중해 봐야 겠다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Vue의 현실] methods, filter, computed]]></title>
            <link>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-filter-methods-computed</link>
            <guid>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-filter-methods-computed</guid>
            <pubDate>Mon, 16 Aug 2021 14:07:53 GMT</pubDate>
            <description><![CDATA[<p>지난 글에서는 목적과 구현을 분리했다. 그렇다면, 자연스럽게 함수가 꽤 많아졌을 것이다. 데이터에 대한 가공을 함수에 전부 위임했기 때문이다. 그렇지 않다면 유사한 로직들을 함수에 위임할 수 있도록 잘게 쪼개는 연습이 필요하다. 이는 리팩토링의 기초 단계이기도 하다. 코드는 리팩터링 책의 예제를 참고로 만들었다.</p>
<pre><code class="language-js">&lt;template&gt;
  &lt;div&gt;
    &lt;div&gt;청구 내역 (고객명: {{ invoice.customer }} )&lt;/div&gt;
    &lt;div&gt;{{ result }}&lt;/div&gt;
    &lt;div&gt;총액: {{ totalAmount / 100 }}&lt;/div&gt;
    &lt;div&gt;적립 포인트: {{ volumeCredits }} 점&lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      plays: {},
      invoice: {},
      totalAmount: 0,
      volumeCredits: 0,
      result: &#39;&#39;
    }
  },
  created () {
    this.init()
  },
  methods: {
    init() {
      this.plays = plays; // axios 통신 생략
      this.invoice = invoice; // axios 통신 생략

      for (let perf of this.invoice.performances) {
        const play = this.plays[perf.playID];
        let thisAmount = 0;
        switch (play.type) {
          case &quot;tragedy&quot;: //비극
            thisAmount = 40000;
            if (perf.audience &gt; 30) {
              thisAmount += 1000 * (perf.audience - 30);
            }
            break;
          case &quot;comedy&quot;: //희극
            thisAmount = 30000;
            if (perf.audience &gt; 20) {
              thisAmount += 1000 + 500 * (perf.audience - 20);
            }
            thisAmount += 300 * perf.audience;
            break;
          default:
            throw new Error(`알 수 없는 장르: ${play.type}`);
        }
        // 포인트를 적립한다.
        this.volumeCredits += Math.max(perf.audience - 30, 0);

        // 희극 관객 5명마다 추가 포인트를 제공한다.
        if (&quot;comedy&quot; === play.type) {
          this.volumeCredits += Math.floor(perf.audience / 5);
        }

        // 청구 내역을 출력한다.
        this.result += `${play.name}: ${thisAmount / 100} (${
          perf.audience
        }석)\n`;
        this.totalAmount += thisAmount;
      }
    }
  }
}
&lt;/script&gt;</code></pre>
<h2 id="함수-쪼개기">함수 쪼개기</h2>
<p>위의 예제를 쪼개보면 아래와 같이 바꿀 수 있을 것이다. 리팩터링 교제의 코드와는 약간의 차이가 있을 수 있다. 코드의 어떤 부분이 어떤 방식으로 바뀌었는지를 참고하면 될듯하다. 함수 쪼개기에 대한 자세한 내용은 생략하겠다. </p>
<pre><code class="language-js">&lt;script&gt;
export default {
  methods: {
    init() {
      this.plays = plays; // axios 통신 생략
      this.invoice = invoice; // axios 통신 생략

      let volumeCredits = 0;
      let total = 0;

      for (let perf of this.invoice.performances) {
        const play = this.getPlay(perf);

        // 청구 내역을 출력한다.
        this.result += `${play.name}: ${this.getAmount(perf) / 100} (${
          perf.audience
        }석)\n`;
        total += this.getAmount(perf);
        volumeCredits += this.setVolume(perf);
      }
      this.totalVolumeCredits = volumeCredits;
      this.totalAmount = total; 
    },
    setVolume(perf) {
      let result = 0
      // 포인트를 적립한다.
      result += Math.max(perf.audience - 30, 0);

      // 희극 관객 5명마다 추가 포인트를 제공한다.
      if (&quot;comedy&quot; === this.getPlay(perf).type) {
        result += Math.floor(perf.audience / 5);
      }
      return result;
    },
    getPlay(perf) {
      return this.plays[perf.playID]
    },
    getAmount(pert) {
      const { audience } = pert;
      const { type } = this.getPlay(pert);
      let result = 0;

      switch (type) {
        case &quot;tragedy&quot;: //비극
          result = 40000;
          if (audience &gt; 30) result += 1000 * (audience - 30);
          break;
        case &quot;comedy&quot;: //희극
          result = 30000;
          if (audience &gt; 20) result += 1000 + 500 * (audience - 20);
          result += 300 * audience;
          break;
        default:
          throw new Error(`알 수 없는 장르: ${type}`);
      }
      return result;
    }
  }
}
&lt;/script&gt;</code></pre>
<h2 id="filter">filter</h2>
<p>이렇게, 함수를 쪼개다보면 메소드가 많아질 수 있다. 이럴 때 메소드의 용도를 잘 구분하면, 코드의 복잡도를 줄일 수 있다. methods 외에 <a href="https://kr.vuejs.org/v2/guide/computed.html">computed</a>, <a href="https://kr.vuejs.org/v2/guide/filters.html">filter</a> 등이 있는데, filter는 사용해보지 않는 분들도 있을 것 같아서 소개를 해보려 한다.</p>
<p>filter는 주로 표시되는 포맷이 변경될 때, 사용이 가능하다. 주로 이런 경우에는 util을 만들어서 사용을 하는 경우가 많지만, 특정 페이지에서 사용이 많은 경우에는 methods로 만들기도 한다. 예제 코드에는 <code>totalAmount / 100</code>으로 나눠주는 형식으로 지정되어 있지만, 예를 들어 totalAmount 값이 0이 들어올 경우 해당 코드는 잘못된 값을 노출한다. 이럴 때 filter를 사용한다.</p>
<pre><code class="language-js">&lt;template&gt;
  &lt;div&gt;총액: {{ totalAmount | divide }}&lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  filters: {
    divide: function (value) {
      if (!value) return &#39;&#39;
      return value / 100 // return이 반드시 있어야 한다.
    }
  }
}
&lt;/script&gt;</code></pre>
<p>이렇게 사용하면 데이터의 단순 표시를 위한 가공 메소드를 줄일 수 있고, 데이터 표시할 때의 예외 처리도 쉬워진다.</p>
<p>vue3에는 지원하지 않으니, util을 만들거나 computed등을 활용하길 바란다.</p>
<h2 id="computed">computed</h2>
<p>공식 문서에는 computed와 watch가 묵여서 나오지만, 사실 methods와 비교해 봐야 한다. computed를 data에 대한 가공이 필요할 때 사용한다. computed는 사실 많이 사용할 테지만, 두 가지만 참고하면 될 것 같다.</p>
<blockquote>
<ul>
<li>parameter가 없어야 한다. parameter가 있을 때는 methods 사용 권장</li>
<li>값이 바뀌지 않으면 실행되지 않는다. (성능상 이점)</li>
</ul>
</blockquote>
<pre><code class="language-js">&lt;template&gt;
  &lt;div&gt;청구 내역 (고객명: {{ customer }} )&lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  computed: {
    customer() {
      return this.invoice.customer; // return이 반드시 있어야 한다.
    }
  }
}
&lt;/script&gt;</code></pre>
<p>사실 filter에서 예시든 경우에도 computed로 처리가 가능하다. 둘의 차이는 filter는 값을 넘긴다는 점, computed는 data를 직접 가능한다는 점이다. 잘 참고해서, 너무 많은 메소드로 인해 혼동되는 사례가 없으면 좋겠다.</p>
<h2 id="마무리">마무리</h2>
<p>글을 꾸준히 쓴다는 게 참 쉽지 않다. 일주일에 한 편씩 쓰려고 하는데, 글 쓰는데 투자하는 시간에 비해 검증해야 할 것들이 많아지고 있다. ㅠ_ㅠ.. 그래도 누군가에게는 도움을 줄 수 있겠지..</p>
<p>다음 글의 주제는 &quot;디렉토리 구조&quot;에 관한 글이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Vue의 현실] side effect no! no!]]></title>
            <link>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-side-effect-no-no</link>
            <guid>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-side-effect-no-no</guid>
            <pubDate>Sun, 08 Aug 2021 16:06:32 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/uriyang_/post/7fb52271-0d32-4cec-9bf7-4b3bc90e0579/icon-1379228_1280.png" alt=""></p>
<h2 id="소프트웨어의-목적">소프트웨어의 목적</h2>
<p>Robert C. Martin의 <strong>클린 소프트웨어</strong>에서는 소프트웨어의 세 가지 목적에 대해 얘기한다.</p>
<blockquote>
<ul>
<li>실행 중에 오류 없이 제대로 동작해야 한다.</li>
<li>소프트웨어는 변경을 위해 존재한다.</li>
<li>코드를 읽는 사람과 의사소통해야 한다.</li>
</ul>
</blockquote>
<p>이것이 바로 모듈이 존재해야 하는 이유라고 한다. 그래서 우리는 모듈을 지원해 주는 Vue.js라는 프레임워크를 사용하고 있다. (front end 분야에서는 컴포넌트가 이러한 역할을 한다.) 그런데 왜 우리가 보고 있는 그 코드는, 무엇을 의미하는지 알 수 없을까? 단지 모듈의 사용만으로 바로 좋은 코드가 만들어지지 않기 때문이다.</p>
<p>우리의 적은 바로 &quot;소프트웨어의 정체성을 잃어버린 코드&quot;다. 이런 코드에게 정체성을 주는 건, 쉽지 않은 여정임을 알고 있다. 하지만 &quot;천 리 길도 한 걸음부터&quot;라는 속담이 있듯이, 조금씩 걸음을 내딛다 보면 좋은 코드와 만나지 않을까?</p>
<h2 id="watch-누구냐-넌">watch, 누구냐 넌?</h2>
<p>Vue.js로 짠 코드들 중 가장 많이 말썽을 부리며 예상치 못한 동작을 발생시키며, 코드 파악에 어려움을 주는 기능이 있다. 알만한 사람들은 아마 다 알 것이다. 바로 <a href="https://kr.vuejs.org/v2/guide/computed.html#watch-%EC%86%8D%EC%84%B1">watch</a>이다.</p>
<p>Vue.js는 다양한 기능들을 제공한다. watch 속성도 그중 하나다. watch는 데이터 변경을 관찰하고 이에 반응하는 속성이다. 기능을 제공한다는 것 자체가 필요가 있다는 말인데, 이런 문제가 발생한다는 건 사용을 잘못하고 있다는 반증이다. 바로 watch를 잘못 만들어진 기능을 메꾸기 위한 용도로 사용하기 때문이다. watch가 있는 이유는 데이터의 흐름이 양방향 바인딩이기 때문에, watch를 통해 감시하지 않으면 변화를 감지하기 어려운 상황들이 있기 때문이다.</p>
<p>그런데 watch와 결합해, Vue.js에서 함께 문제를 일으키는 특성이 있다. 바로 Vue.js의 데이터 변경 방식이다. Vue.js는 data 속성 등 다양한 방식으로 <a href="https://kr.vuejs.org/v2/guide/reactivity.html">변경 내용을 추적</a>한다. 속성의 추가 제거와 같이 변경 감지가 불가능한 요소들이 있지만, 실제 이 동작에 대한 코드 작성은 가능하다. 보통 이렇게 변경/감지가 제대로 일어나지 않는 현상이 발생할 때, 동작에 이해가 명확하지 않은 누군가가 watch를 추가하는 불상사를 만든다. 특히 deep, immediate과 같은 속성을 추가하고, 호출하는 함수 동작 안에 다시금 해당 값을 변경하는 코드라도 있으면, 개발자는 이미 이 코드의 제어권을 잃었다 해도 무방할 정도다.</p>
<h2 id="목적과-구현을-분리">목적과 구현을 분리</h2>
<p><a href="https://ko.reactjs.org/">React</a>에는 <a href="https://ko.reactjs.org/docs/state-and-lifecycle.html">setState</a>라는 함수가 있다. React에 setState라는 함수가 있어서, 이 함수를 통해서만 state가 변경이 가능하다.  state를 변경하기 까지의 제어 흐름이 일관적으로 이어질 수 있다. 잘못 구성된 Vue.js와 비교를 해볼까?</p>
<h3 id="vuejs">Vue.js</h3>
<pre><code class="language-js">&lt;script&gt;
export default {
  data() {
    return {
      testVal: {}
    }
  },
  created () {
    this.init()
  },
  methods: {
    init() {
      this.setA()
      this.setB()
    },
    setA() {
      this.testVal.a = &quot;a&quot; // 이거 가능
      this.setC()
    },
    setB() {
      this.testVal.b = &quot;b&quot; // 이거 가능
    },
    setC() {
      this.testVal.c = &quot;c&quot; // 이거 가능
    }
  }
}
&lt;/script&gt;</code></pre>
<p>결국 testVal의 a,b,c 속성에 값을 대입해 줘야 하는 상황인데, 코드가 여기저기 분리되어 있다. </p>
<h3 id="react">React</h3>
<pre><code class="language-js">init() {
  const tempVal = this.setTest()
  this.setState({ testVal: tempVal})
},
setTest() {
  return { a: &quot;a&quot;, b: &quot;b&quot;, c: &quot;c&quot; }
}</code></pre>
<p>React로 하면 setState라는 함수를 사용해야 하기 때문에, 변경되는 값을 한 번에 처리하게 된다. (사실, react 다 까먹음.. ㅠ.ㅠ) 그리고 state의 특정 값 자체를 대체해버리기 때문에, observer에서 변화감지가 확실하게 된다.</p>
<p>그러면 Vue.js에서 어떻게 해야 할까? 우선 <strong>목적과 구현을 분리</strong>해야 한다. 실제 데이터 <strong>조작과 관련된 함수</strong>들은 특정 함수(대체로 초기화 함수)에게 <strong>책임을 가져가고</strong>, <strong>가공이 필요한 값은</strong>는 가공과 관련된 함수에게 위임하는 것이다. 여기서 중요한 건, 그리고 초기화 데이터의 구조가 명확해야 하고, 가공과 관련된 함수는 side effect가 없어야 한다는 것이다. (가공된 값을 그대로 리턴) 그래야만 제어 흐름이 일정해질 수 있다. side effect에 관한 내용은 <a href="https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D">함수형 프로그래밍</a>이나 <a href="https://ko.wikipedia.org/wiki/%EB%B6%80%EC%9E%91%EC%9A%A9_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)">side effect</a>/순수함수/부수효과 키워드로 검색하면 많이 나온다.</p>
<blockquote>
<ul>
<li>초기화 데이터의 구조가 명확해야 한다.</li>
<li>데이터 조작과 관련된 함수와 가공하는 함수는 분리한다.</li>
<li>가공과 관련된 함수는 side effect가 없어야 한다.</li>
</ul>
</blockquote>
<h3 id="refectoring">refectoring</h3>
<p>아까의 코드를 그럼 간단히 바꿔보자. </p>
<pre><code class="language-js">&lt;script&gt;
export default {
  data() {
    return {
      testVal: {
        a: null,
        b: null,
        c: null
      }
    }
  },
  created () {
    this.init()
  },
  methods: {
    init() {
      this.testVal = { a: this.getA(), b: this.getB(), c: this.getC() }
      // 변수나 상수에 대입도 가능
    },
    getA() {
      return &quot;a&quot;
    },
    getB() {
      return &quot;b&quot;
    },
    getC() {
      return &quot;c&quot;
    }
  }
}
&lt;/script&gt;</code></pre>
<p>대략 이런 형태로 나올 것이다.</p>
<h2 id="마무리">마무리</h2>
<p>예시나 설명이 적절한지 잘 모르겠지만, 우선은 내가 사용하는 코드들에 값을 직접 변경하는 부분들이 흩어져있는지 확인해보고 값을 return 하는 형태로 변경을 해보자. 그게 너무 어려우면 가능한 부분만 함수로 분리하는 방법도 있다. 그러면 자연스럽게 깔끔해지고 알아보기 쉬워지는 코드를 경험할 것이다. 일단 해보자!!! </p>
<p>다음 글에는 함수와 관련해서, Vue.js의 지원 기능 하나에 대해 얘기해보려 한다. 부족한 글을 읽어주셔서 감사합니다. ^_^</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Vue의 현실] API Interface 만들기]]></title>
            <link>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-API-inteface-2</link>
            <guid>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-API-inteface-2</guid>
            <pubDate>Sun, 01 Aug 2021 13:29:04 GMT</pubDate>
            <description><![CDATA[<p>약 한 달 전쯤부터 이 글의 내용을 구상하고 있었는데, 얼마 전에 소속된 커뮤니티에서 우연히 오늘 주제에 관한 얘기가 나와 속으로 굉장히 신기해했던 경험이 있다. 생각보다 많은 사람들이 관심을 보이는 주제였는데, 나와 비슷한 생각을 하고 있음에 굉장히 반가웠다.</p>
<p>이제부터 <strong>API Interface</strong>를 구성할 예정이다. 사실 오늘 구성하려는 구조에 대한 명칭이 따로 있는지는 모르겠다. API Interface라는 명칭은 내가 용어정리를 위해 붙인 이름인데, 잘못된 명칭이라면 알려주시면 감사하겠습니다. 개인적인 경험을 통한 방법을 제시하는 것이니, 꼭 정답은 아니면 더 좋은 방법이 있을 경우 제보 주시면 반영해보도록 할게요 ^_^; (부담 부담)</p>
<h2 id="config와-api-list-만들기">config와 API list 만들기</h2>
<p>API를 호출하는 URL 설정값은 프로젝트 구조에 따라 조금씩 다를 텐데, 보통은 config directory나 env 파일로 설정되어 있을 것이다. 우리는 우선 이 설정된 URL과 조합하여 API url list를 만들 것이다. 준비물로 <strong>swagger UI</strong>등의 API 목록이 필요하다.</p>
<p>단, url 리스트는 api.js를 좀 더 편하게 만들기 위한 과정이라서, 실무에서 API 변동이 많거나(API 바뀌는 건 실제로는 지양해야 할 일) API list가 많지 않아 관리가 쉽다면 작성하지 않아도 무관하다. 예시로 든 경로는 사용자의 편의에 따라 얼마든지 변경 가능하다.</p>
<h3 id="apiconfigjs">api/config.js</h3>
<pre><code class="language-js">export const API_URL = process.env.BASE_URL // 추후 api list에서 API URL을 쉽게 불러오기 위한 용도
// 혹은 export const API_URL = &quot;https://test.com/api/v1/&quot;
// 이렇게 직접 넣는 경우도 있을 것이다.

export const API = {
  users: &#39;users&#39;, // API list의 구조를 나열해주세요.
  user: (args) =&gt; `users/${args.userId}`
  ...
}

export const ETC_API = {
  tests: &#39;tests&#39;,
  test: (args) =&gt; `users/${args.args1}/depth1/${args.args2}/depth2/${args.args3}`
  ...
}</code></pre>
<blockquote>
<ul>
<li>API_URL은 추후 api list에서 API URL을 쉽게 불러올 용도로 만들어뒀다. 구조에 따라 필요 없으면 생략은 가능할 것이다.</li>
<li>const API와 ETC_API 같은 경우는 주로 swagger controller 별로 구분하는 것이 좋은듯하다. 하지만 양이 많지 않은 경우에 구분하지 않아도 무관하다.</li>
<li>각 상수 안에는 parameter 값을 제외한 API list를 나열한다. 이 경우에는 API 호출 시 경로 안에 들어가는 값들을 정리하기가 손쉬워진다.</li>
<li>전역에 있는 값을 반복적으로 넣어주는 구조가 있을 경우, 이 단계에서 참조해도 무관하다. (ex: 사용자 정보..)</li>
<li>다른 메소드로 동일한 경로가 있을 경우에는 한 번만 적어준다.</li>
</ul>
</blockquote>
<h3 id="apiservicejs">api/service.js</h3>
<p>axios 호출에 관한 Interface를 만드는 파일이다. 해당 코드는 axios를 직접 설정하는 기준에 맞춰져 있어서, <a href="https://www.npmjs.com/package/vue-axios">vue-axios</a>나 <a href="https://www.npmjs.com/package/@nuxtjs/axios">nuxt/axios</a>를 사용하는 경우에는 사용법이 달라질 수 있다.</p>
<pre><code class="language-js">import axios from &#39;axios&#39;

// 프로젝트 설정에 맞게, 기본적인 정보를 넣어주세요
const service = axios.create({
  baseURL,
  timeout,
  withCredentials,
  ...
})

// axios 요청 시 필요한 정보를 넣어주세요
service.interceptors.request.use(
  (config) =&gt; {
    config.headers = {}
  }
)

// 응답에 필요한 처리를 넣어주세요.
service.interceptors.response.use(
  (res) =&gt; {},
  (error) =&gt; Promise.reject(error)
)

// 각 메소드별 함수를 생성해 주세요.
export default {
  async get(...options) {
    try {
      const res = await service.get(...options)
      return res
    } catch (e) {
      return printError(e)
    }
  },

  async post(...options) {
    // 공통
  },

  async put(...options) {
    // 공통
  },

  async delete(...options) {
    // 공통
  },
}</code></pre>
<p>참조: <a href="https://xn--xy1bk56a.run/axios/guide/config-defaults.html#%EA%B8%80%EB%A1%9C%EB%B2%8C-axios-%EA%B8%B0%EB%B3%B8-defaults-%EC%84%A4%EC%A0%95">axios.create</a>, <a href="https://xn--xy1bk56a.run/axios/guide/interceptors.html">axios.interceptors</a></p>
<blockquote>
<ul>
<li>구조에 따라, create 안에 baseURL이 들어갈 수도 있다.</li>
<li>service.js는 api 호출할 때 공통적으로 발생하는 처리들을 담당한다.</li>
<li>request에는 주로 header와 token 관련 설정들을 처리해 준다.</li>
<li>reponse에서도 token 처리나 응답에 대한 공통 로직을 처리해 준다.</li>
<li>get, post, put, delete는 각각 API 호출 시에 직접 호출될 함수들이다. API 호출 시의 option을 전달하며, 공통적인 에러 처리를 한다.</li>
<li>메소드별 공통 로직은 경우에 따라 함수로 분리할 수 있다.</li>
</ul>
</blockquote>
<h3 id="apiapijs">api/api.js</h3>
<p>대망의 마지막 작업이다. 이제 이렇게 만들어진 service와 url list를 묶어 진짜 호출되는 api 함수를 만드는 작업이다.</p>
<pre><code class="language-js">import service from &#39;./service
import { API_URL, API, ETC_API } from &#39;./config&#39;

export const api = {
  getUser() {
    return service.get(`${API_URL}${API.users}`)
  },
  setUser(args) {
    return service.post(`${API_URL}${API.user(args)}`)
  },
  updateUser(args, param) { // args와 param이 동시 존재하는 경우
    return service.put(`${API_URL}${API.user(args)}`, param)
  }
}

export const testApi = {
  getTests() {
    return service.get(`${API_URL}${API.tests}`)
  },
  /* test 등록하기
   * @param { Object } args
   * @param { string } args.args1 - 이것
   * @param { string } args.args2 - 저것
   * @param { string } args.args3 - 그것
   */
  setTest(args) {
    return service.post(`${API_URL}${API.test(args)}`)
  }
}</code></pre>
<blockquote>
<ul>
<li>함수 이름은 메소드와 관련한 값을 붙혀주는 것이 좋다. ex) user 정보일 때, getUser</li>
<li>메소드별 어울리는 이름 (get: get, post: set, put: update, delete: delete - 축약 가능)</li>
<li>메소드 다음은 보통 swagger에 있는 이름을 그대로 사용해 주면 된다.</li>
<li>함수 위에는 <a href="https://jsdoc.app/">js doc</a>을 이용하여, parameter 정보를 표시해 주는 것이 좋다.</li>
</ul>
</blockquote>
<h2 id="호출해볼까">호출해볼까?</h2>
<p>자 이제 interface는 다 만들었다. 우선은 각 메소드 별로 복잡도가 있는 API를 하나씩 골라, 코드에 직접 적용해서 테스트해보고 호출에 성공하면 적용 가능하다. 그러면 어떻게 적용을 해볼 것인가? </p>
<h3 id="호출할파일vue">[호출할파일].vue</h3>
<pre><code class="language-js">import { api } from &#39;@/api/api&#39;

methods: {
  async init() {
    await api.getUser().then(res =&gt; {
      this.setUser(res)
    })
  }
}</code></pre>
<p>자 얼마나 편한가? 그런데 API 호출이 너무 많아서 적용할 때 검증이 어려워서 고민일 수 있다. 각 메소드별 검증은 끝난 후니, 페이지 수정이 있을 때마다 작업을 하면서 점진적으로 적용해나가면 된다. API interface는 서버 환경과 같은 문제를 제외하고는 동일한 동작을 하므로, 오타나 잘못된 파라미터가 아닌 이상 문제가 생길 여지는 적다. 그 외의 문제는 interface 자체의 설정을 잘못 넣은 케이스니 수정이 필요하다. </p>
<p>좋은 점 하나 더! 짜잔 API 목록의 자동완성이 가능하다는 것이다. 우리는 swagger UI와 이름을 맞춰서 작성했기 때문에, 쉽게 호출할 API를 찾을 수 있다.</p>
<img src="https://images.velog.io/images/uriyang_/post/6eb8e189-e695-4836-b7fc-f13a8a1845df/%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%202021-08-01%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.33.15.png" width="100">
<img src="https://images.velog.io/images/uriyang_/post/941b25e1-36e3-45ff-a38b-6be58947684a/%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%202021-08-01%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.34.17.png" width="150">
메소드 자동완성은 더 좋다.

<h2 id="다음은">다음은..</h2>
<p>열심히 설명해보려고 했으나, 사람들이 쉽게 이해할 수 있을지 모르겠다. ㅠ_ㅠ</p>
<p>이번에는 API를 수정했으니, 다음에는 컴포넌트 내의 코드에 손을 대야 하지 않을까? 다음 글은 컴포넌트 내의 <strong>method</strong>에 관한 내용이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Where_am_I] 벚꽃 엔딩]]></title>
            <link>https://velog.io/@uriyang_/WhereamI</link>
            <guid>https://velog.io/@uriyang_/WhereamI</guid>
            <pubDate>Sun, 01 Aug 2021 03:52:41 GMT</pubDate>
            <description><![CDATA[<h1 id="prologue">Prologue</h1>
<p>몇 개의 블로그 포스팅을 하다, 꽤 오랫동안 글쓰기를 중단했다.
개인적으로 코드의 방향에 관한 글을 쓰는 것에 대해, 글을 쓰면서 무거운 책임을 실감했고 내 실력으로는 아직 그런 글들을 써내기에는 부족하다고 생각했다.
글로 내 생각을 풀어내면서 행복감을 느끼는 나에겐, <strong>&quot;내 생각과 스토리들을 나열하는 것이 좀 더 어울리지 않을까?&quot;</strong>라는 생각이 들었다.</p>
<p>그래도 내가 썼던 글을 좋아해 주시는 분들이 계시고, 종종 <strong>&quot;글을 더 쓰지 않느냐?&quot;</strong>고 질문해 주신 분들도 계셔서 참 감사하다는 마음이 들었다.
그 계기로 얼마 전 한 세미나에서 <strong>&quot;Where am I&quot;</strong>라는 주제로 발표를 했었고, 많은 분들이 좋은 피드백을 해주셔서 참 의미가 있었다.</p>
<p>이 글은 그때의 발표 내용들에 대한 연장선이 될 것 같다.
개발 문화와 개발자들에 대한 내 생각들을 풀어놓음으로써, 누군가에게 다시금 도움이 되기를 바라며..
<strong>평소에 머랏속에 갖고 있던 쉽게 꺼내지 못했던 생각들</strong> / <strong>꽤 오랜 시간을 개발자로 살아가면서 느낀 점</strong>등을 글을 통해서 다시 한번 꺼내보려고 한다.</p>
<h1 id="벚꽃-스팟">벚꽃 스팟</h1>
<p>제목을 왜 <strong>벚꽃 엔딩</strong>으로 정했을까?
벚꽃이 절정일 때, 벚꽃 스팟으로 인스타에서 유명한 두 장소를 갔었다.
그런데 끝내 내게 남은 사진은 이 정도뿐이었다.
<img src="https://velog.velcdn.com/images/uriyang_/post/35ee0673-31fb-48a0-b825-67dd33312472/image.jpeg" alt=""></p>
<p>그때 당시 인스타에 &quot;롯데월드&quot;, &quot;석촌호수&quot;, &quot;벚꽃&quot; 등의 태그를 검색해 보면 멋진 사진들이 많이 나왔다.
내가 찍었던 장소랑 같은 장소에서 찍은 사진들도 정말 많았다.
&quot;같은 장소, 다른 사진!!&quot;
내 사진은 왜 이런 결과일까?</p>
<p>생각해 보면 이런 이유들이 있었다.</p>
<blockquote>
<ul>
<li>예상보다 벚꽃이 절정으로 피지 않았다. (벚꽃이 많이 핀 장소를 pick)</li>
<li>벚꽃이 예쁘게 핀 장소는 사람들이 줄을 서서 기다리고 있었다. (나는 기다리지 않았다)</li>
<li>많은 사람들이 좋은 사진을 위해 부끄러움(사람들의 시선)을 감수하며, 다양한 포즈를 시도하며 사진을 찍었다.</li>
<li>좋은 사진이 나올 때까지 여러 번 반복했다.</li>
<li>예쁜 사진을 위한 복장과 장비(ex: 좋은 카메라, 포즈)를 준비해왔다.</li>
</ul>
</blockquote>
<p>이상적인 사진이 나오기까지는 생각보다 많은 노력을 필요로 한다.
사진이 찍힌 내가 멋진 그들과 다르다는 이유도 있을 것이다.
이미 위의 내용들만 봐도 많은 키워드들이 나왔다.</p>
<blockquote>
<p>준비, 사전 조사(자료 조사), 기다림, 용기, 다양한 시도, 연습, 반복, 비용..</p>
</blockquote>
<p>이 얘기를 꺼낸 이유는, 어떤 거울을 통해 바라본 세상과 현실이 다를 수 있음을 얘기하고 싶었다.
그리고 그 거울에 비친 모습들은, <strong>보이지 않는 어떠한 노력</strong>들을 동반한다는 것이다.</p>
<p>실제로 수많은 개발자들이 개인 시간도 없이 공부를 하고, <strong>보이지 않는 번아웃</strong> 속에 살아간다.
내가 바라는 멋있고 뭐든 다 할 수 있을 것 같은 유명한 개발자도, 남모르게 힘들고 외로워하고 있을 수도 있을 것이다.</p>
<p>유명했던 글이라 아시는 분들이 많겠지만..
다시 한번 redux의 창시자인 dan abramov의 &quot;<a href="https://overreacted.io/ko/things-i-dont-know-as-of-2018/">2018년,내가 모르는 기술들</a>&quot;이라는 글을 공유해 본다.</p>
<h1 id="평균의-함정">평균의 함정</h1>
<p>비교적 최근에는 개발자들에게 좋은 회사들이 점점 많아지고 있다.
사람들이 많이 얘기하는 &quot;네카라쿠배당토야&quot; 뿐만 아니라, 개발자가 자유롭고 좋은 조건으로 일할 수 있는 회사들이 많아지고 있다.
&quot;맥북 제공&quot;, &quot;점심 제공&quot;, &quot;자율출근&quot;, &quot;재택근무&quot;, &quot;스톡옵션&quot; 등의 혜택들은 어느새 우리에게 이러한 기준들이 너무 당연한 것들이 되어있지 않은가?</p>
<ul>
<li>요즘엔 <strong>스타트업의 겨울</strong>이라고 무거워진 분위기가 느껴진다. 그래서 앞으로 분위기가 조금은 달라질 수도 있지 않을까 하는 생각도 든다. (이미 달라졌나? ?_?)</li>
</ul>
<p>아래 두 개의 기업이 있다.</p>
<blockquote>
<p>A기업: 평균 연령 31세, 평균 연봉 9,000만원
B기업: 평균 연령 34세, 평균 연봉 6,000만원</p>
</blockquote>
<p>어떤 기업이 더 좋아 보이는가?
A기업이 더 좋아 보인다.</p>
<p>위의 회사의 내부 구성이 아래와 같다고 생각해 보자.</p>
<h4 id="a사">A사</h4>
<table>
<thead>
<tr>
<th align="left">A사</th>
<th align="center">연령</th>
<th align="right">연봉(만원)</th>
</tr>
</thead>
<tbody><tr>
<td align="left">직원1</td>
<td align="center">27</td>
<td align="right">3800</td>
</tr>
<tr>
<td align="left">직원2</td>
<td align="center">23</td>
<td align="right">2900</td>
</tr>
<tr>
<td align="left">직원3</td>
<td align="center">22</td>
<td align="right">2600</td>
</tr>
<tr>
<td align="left">직원4</td>
<td align="center">31</td>
<td align="right">4200</td>
</tr>
<tr>
<td align="left">임원</td>
<td align="center">52</td>
<td align="right">31500</td>
</tr>
<tr>
<td align="left">평균</td>
<td align="center">31</td>
<td align="right">9000</td>
</tr>
</tbody></table>
<h4 id="b사">B사</h4>
<table>
<thead>
<tr>
<th align="left">B사</th>
<th align="center">연령</th>
<th align="right">연봉(만원)</th>
</tr>
</thead>
<tbody><tr>
<td align="left">직원1</td>
<td align="center">31</td>
<td align="right">5000</td>
</tr>
<tr>
<td align="left">직원2</td>
<td align="center">32</td>
<td align="right">6450</td>
</tr>
<tr>
<td align="left">직원3</td>
<td align="center">33</td>
<td align="right">6300</td>
</tr>
<tr>
<td align="left">직원4</td>
<td align="center">31</td>
<td align="right">5350</td>
</tr>
<tr>
<td align="left">임웜</td>
<td align="center">43</td>
<td align="right">6900</td>
</tr>
<tr>
<td align="left">평균</td>
<td align="center">34</td>
<td align="right">6000</td>
</tr>
</tbody></table>
<p>위에서 보여줬던 <strong>평균 연봉</strong> 같은 가공된 정보는 회사 홍보 문구로 쓰일법한 정보로 보여진다.
하지만 자세히 들여다보면 일반적인 지원 입장에서는 B기업이 훨씬 유리하다.</p>
<p>요즘은 기업을 평가할 수 있는 다양한 매체들이 있지만, 그럼에도 얻을 수 있는 정보는 아주 구체적이지는 못할 것이고 제한적일 수밖에 없다.
채용과 서비스를 해야 하는 기업 입장에서는 굳이 문제를 드러낼 필요는 없기 때문이다.
내부 사정에 대한 정보를 얻을 수 있으면 그래도 비교적 많고 구체적인 정보를 얻을 수는 있을 것이다.
하지만 큰 규모의 회사라면 팀이나 조직 구성에 따라 분위기가 천차만별로 달라질 수 있을 것이다.
그리고 개인의 성향에 따라서 같은 상황이라도 다르게 받아들일 수 있기 때문에, 이렇게 얻은 정보도 나와 맞는지에 대한 기준으로 판단할 때는 100% 장담할 수 없다.</p>
<p>결국 겪어봐야 알 수 있는 경우가 많다.</p>
<h1 id="결론">결론</h1>
<p>생각보다 우리는 원하는 조건을 얻기 위해 더 많이 노력해야 하고, 그럼에도 불구하고 원하는 것보다 좋은 대우를 받지 못할 수도 있다. 하지만, 개발자라는 직업 혹은 개발이라는 일 자체는 근무 조건 외에도 많은 의미로 좋은 편이라는 생각이 든다.</p>
<p>지금 내 현실과 맞지 않은 너무 먼 위만 바라보고 있는 건 아닌지?
원하는 기준에 합당한 노력을 하며 살아가고 있는 것인지? 
차곡차곡 쌓여가는 내 것에 만족하는 방법을 알면 더 행복하게 개발할 수 있지 않을까?</p>
<p>참고: <a href="https://www.beusable.net/blog/?p=3298">https://www.beusable.net/blog/?p=3298</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Vue의 현실] 컴포넌트마다 하나씩은 있는 그것!]]></title>
            <link>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-API-inteface-1</link>
            <guid>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4-API-inteface-1</guid>
            <pubDate>Fri, 30 Jul 2021 17:33:49 GMT</pubDate>
            <description><![CDATA[<h2 id="velog-메인에-떴어요">velog 메인에 떴어요!</h2>
<p>조회수가 생각보다 잘 나와서 기분이 너무 좋았는데, 알고 보니 메인에 떴더라고요. 기대도 안 했는데, 이렇게 관심 가져주셔서 <strong>정말 감사합니다</strong> ◟( ˘ ³˘)◞ ♡
<img src="https://images.velog.io/images/uriyang_/post/c615742b-8278-4e14-96af-2593404103ac/%E1%84%8C%E1%85%A6%E1%84%86%E1%85%A9%E1%86%A8%E1%84%8B%E1%85%A5%E1%86%B9%E1%84%8B%E1%85%B3%E1%86%B7.png" alt=""></p>
<h2 id="가장-고치고-싶은-눈에-가시">가장 고치고 싶은 눈에 가시</h2>
<p>사실 스파게티 코드를 Refactoring 하려고 접근하면, 가장 처음 개발자들 눈에 가시는 바로 <strong><a href="https://eslint.org/">Lint</a></strong> 이슈일 것이다. 하지만 개인적으로는 처음부터 Lint를 수정할 것을 권하지는 않는다. 그 이유는 이미 개발물이 만들어진 상태에서의 Lint 관련 수정은, 범위가 너무 광범위해지기 때문이다. 또한 일괄적으로 수정한 경우 git log를 추적하는데 불편함을 줄 수도 있다.</p>
<p>물론 <strong>auto fix</strong> 기능도 있다. 하지만 스파게티 코드 / Lint 설정이 잘못 구성된 코드에서 auto fix는 완벽한 수정이 지원되지 않을뿐더러, 너무 많은 코드가 수정되어 기존 서비스와 동일한 동작을 하는지 검증하기 어려워진다. 특히나 테스트 코드가 만들어지지 않은 경우에는 수동으로 검증해 줘야 하고, 그러면서 실수가 나올 확률이 높기 때문이다. 그래서 Lint 같은 경우에는 오히려 점진적으로 수정하는 것을 권하고 싶다. </p>
<pre><code>&lt;template&gt;
    &lt;div&gt;
        4space 참을 수 없어요!
    &lt;/div&gt;
&lt;/template&gt;</code></pre><h2 id="그래서-뭘-고칠까">그래서 뭘 고칠까?</h2>
<p>코드를 정리하려면, 우선은 길어진 코드 길이를 줄여 <strong>가독성을 높여야</strong> 한다. 그래서 반복되는 부분을 줄이면서 정리하는 과정이 필요하다. 하지만 무방비한 수정은 기존 동작의 오류를 야기하기 때문에, <strong>안정성 있는 수정</strong>을 해야 한다. 위에서 린트 수정을 추천하지 않았던 이유도 그렇다. </p>
<p>지난 글에서 <strong>가장 흔하게 반복되는 중복</strong>을 줄이는 방법을 알려준다고 했는데, 사실은 약간의 흥미 유발을 위한 어그로였다. (<em>주제가 기대에 못 미치더라도 양해 부탁드립니다</em> (•‿• )) 개인적으로 Frontend를 작업에서 가장 많이 반복되는 부분이라 생각하고, 사실상 중복의 문제가 없으면 사실상 Best 케이스다. 바로 <strong>API 호출</strong>이다.</p>
<p>대부분의 Frontend 작업은 화면의 형태를 만들고, API 통신을 통해 받아온 데이터를 가공해서 요구 사항대로 화면을 구성한다. (참고: 캡틴판교님의 <a href="https://joshua1988.github.io/vue-camp/front-dev.html#%ED%94%84%EB%9F%B0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90%EA%B2%8C-%ED%95%84%EC%9A%94%ED%95%9C-%EC%97%AD%EB%9F%89">프론트엔드 개발자에게 필요한 역량</a>) 그래서 컴포넌트당 1회 이상의 API 호출이 들어가는 경우가 많고, 컴포넌트가 쪼개지지 않은 경우에는 한 파일 안에 여러 번의 API 호출이 들어가는 경우들도 있다. 대부분 통신과정과 에러 처리에 반복된 패턴을 가지고 있는데, 그 부분을 <strong>interface로 만드는 것이 첫 번째 제안</strong>이다.</p>
<h3 id="api-call-interface-만들기">API call interface 만들기</h3>
<p>Server API interface는 만들 경우 아래와 같은 장점이 생긴다.</p>
<blockquote>
<ul>
<li>안정성 있고 동일한 API 호출 환경을 제공한다</li>
<li>통일성 있는 에러 처리가 가능하다.</li>
<li>method 구분이 쉬워진다. (api url 관리도..)</li>
<li>(동일한) API 호출 작업에 쓰는 비용이 줄어든다.</li>
<li>API 호출과 관련한 코드 라인수가 줄어든다.</li>
</ul>
</blockquote>
<p>그리고 API를 호출하는 코드가 잘못 구성된 경우(ex: 예외 처리 미비)에 대한 교정 효과도 있을 수 있다.</p>
<p>API 통신은 주로 <a href="https://github.com/axios/axios">axios</a>라는 라이브러리를 사용하며, 대략 아래와 같은 방식으로 호출을 한다. <em>(axios의 자세한 <a href="https://xn--xy1bk56a.run/axios/">사용법</a>은 검색해보면 많이 나온다.)</em></p>
<pre><code class="language-js">axios({
  method: [method],
  url: [url],
  data: {}
}).then(response =&gt; {
  if (response.status === &#39;ok&#39;) {
    console.log(&#39;response를 처리합니다.)
  }
}.catch(Error =&gt; {
  console.log(error)
};</code></pre>
<p>API interface를 만들지 않았을 때는 아래와 같은 패턴을 계속 반복하며 호출을 하지만, interface를 만들면 변경되는 최소한의 정보만으로 API 호출할 수 있어서 훨씬 효율적이다. 이제 어떻게 API interface를 만들면 되는지 소개를 할 예정이다. API 분량에 따라, 약간의 <strong>노가다</strong>를 할 수 있다는 점과 <strong>swagger UI 등의 API 문서</strong>에 대한 준비가 필요하다.</p>
<p>우리가 구성할 파일들은 다음과 같다.</p>
<blockquote>
<ul>
<li>api url이 있는 config 파일</li>
<li>axios를 관리할 service.js</li>
<li>api url 리스트 (api.js와 하나의 파일로 관리해도 무관)</li>
<li>api list를 관리할 api.js</li>
</ul>
</blockquote>
<p>코드 구성에 대한 자세한 내용은 글이 길어질 것 같아, 다음 회차로 넘긴다. 업데이트는 최대한 빠르게 할 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Vue의 현실] 현실편..]]></title>
            <link>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4.-%ED%98%84%EC%8B%A4%ED%8E%B8</link>
            <guid>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4.-%ED%98%84%EC%8B%A4%ED%8E%B8</guid>
            <pubDate>Sun, 25 Jul 2021 15:10:46 GMT</pubDate>
            <description><![CDATA[<h2 id="vue를-쓰는-이유와-현실">Vue를 쓰는 이유와 현실</h2>
<p>Frontend 분야에는 <strong>React, Angular, Vue.js</strong>. 이렇게 프레임워크 3대장이 존재한다. 각각 특징들은 <a href="https://www.google.com/search?q=%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C+%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC&amp;newwindow=1&amp;sxsrf=ALeKk03VOgDfsqqC_51Hu70SbIdWjLAIdw%3A1627223067033&amp;ei=G3T9YJiwAZH10ASX6J2oAg&amp;oq=%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C+%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC&amp;gs_lcp=Cgdnd3Mtd2l6EAMyAggAMgIIADIHCAAQhwIQFDICCAAyAggAMgIIADICCAAyAggAMgIIADICCABKBAhBGABQtp4MWIKoDGC1xQxoA3AAeAKAAXqIAeILkgEEMC4xM5gBAKABAaoBB2d3cy13aXrAAQE&amp;sclient=gws-wiz&amp;ved=0ahUKEwjYqYWntv7xAhWROpQKHRd0ByUQ4dUDCA4&amp;uact=5">구글</a>에 검색해보면 많이 나온다. Vue를 검색해보면 나오는 키워드들은 대부분 <strong>&quot;쉽다&quot;</strong>,<strong>&quot;지원하는 라이브러리가 많다&quot;</strong>,<strong>&quot;문서화가 잘 되어있다&quot;</strong> 정도이다.</p>
<p>최신 트렌드를 따라가는 흐름에 Vue.js를 사용하는 곳도 늘어나기 시작했지만, 사실상 Frontend 프레임워크 점유율은 React가 가장 많다. Vue.js는 쉬운 접근성을 내세워 주로 빠르게 결과를 내야 하는 소규모/신생 스타트업이나 정부 프로젝트, 기존 jQuery의 대체재로 사용되는 곳이 많아졌다. 그러다 보니 막상 Vue.js로 만들어진 서비스들은 Frontend 개발자 없이 시작했거나, 이제 막 입문한 신입 개발자에 의해서 만들어진 경우들이 꽤 많다.</p>
<h2 id="vue-개발자는-힘들다">Vue 개발자는 힘들다</h2>
<p>서비스를 오픈한 기업들은, 운영을 하며 자연스럽게 다양한 요구사항들이 늘어나게 되고 화면에 적용해야 할 기획요소도 늘어나게 된다. 그러면서 초반에 서비스를 개발한 개발자(백엔드/디자이너/신입 개발자)는 점차 한계를 느끼기 시작한다. 그때 회사에 Frontend 개발자를 뽑아야 한다고 요구하기 시작한다. 그리고 그렇게 입사한 <strong>&quot;Frontend 개발자&quot;</strong>가 바로 이 글을 읽고 있는 <strong>여러분</strong>이다.</p>
<p>우선 처음으로 맞닥뜨리는 상황은 문서가 없는 경우들이 많다. 그래서 기존 코드를 분석하기 위해 코드를 열어보는 순간, 의도를 알 수 없는 괴상한 코드들이 머릿속에 혼란을 주기 시작한다. 주변의 개발자들에게 코드 의도에 대해 질문해봐도 대부분 잘 모르는 경우가 많다. 그리고 Frontend 개발자가 입사하는 순간부터는 <strong>&quot;이제 담당할 사람이 왔으니, 알아서 잘하겠지&quot;</strong> 그분들은 이제 본 업무에 최선을 다한다. 이제 <strong>&quot;이 막막함을 어떻게 해소해야 할까?&quot;</strong> 고민되기 시작할 때, 요구사항이 쏟아지기 시작한다. 우선 일은 해야 하니, 자연스럽게 엉망진창인 코드에 숟가락을 하나 더 얹고 만다.</p>
<p>그리고 그러한 상황이 반복될수록 개발자에겐 이런 점들이 점점 불어난다.</p>
<blockquote>
<ul>
<li>Frontend 개발자로서의 앞으로 커리어에 대한 걱정!</li>
<li>코드에 대한 분노와 코드의 라인 수</li>
<li>원래의 방식에 대한 망각과 이제 무슨 코드가 좋은건지 모르겠는 혼란 지수!</li>
<li>덕지덕지 붙은 코드의 스파게티 지수!</li>
</ul>
</blockquote>
<p>이 글은 지금 고개를 끄덕이고 있는 &quot;우리&quot;와 같은 개발자들을 위해 시작했다. 개발하다 이런 상황의 코드를 만났을 때, 어디서부터 응급처치를 해야 할 지 직접 했던 고민들과 고민을 통해 얻는 인사이트를 공유하기 위한 글이다. 물론 개인적인 경험을 토대로 쓴 글이니, 모든 상황에 들어맞지 않을 수 있다. 그렇다면 제보해주면, 피드백을 통해 조금씩 고쳐나갈 생각이다.</p>
<h2 id="그래서">그래서..</h2>
<p>세상에 좋은 환경에서 좋은 코드만 보면서 일하는 개발자들도 많을 것이다.(정말 부럽다) 하지만 잘하고 싶고 열심히 하고 싶은데도, 현실의 벽에 부딪혀서 막막한 개발자들도 많이 있을 것이다. 이런 개발자들에게 도움이 되는 글을 쓰고 싶다.</p>
<p>글이 길어져 진짜 코드에 대한 이야기는 다음 글부터 올릴 예정이다. 다음 주제를 상상해보시길 바라며, 살짝 덧붙여보자면 가장 흔하게 반복되는 <strong>중복을 줄이는 방법</strong>이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Vue의 현실] prolog..]]></title>
            <link>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4</link>
            <guid>https://velog.io/@uriyang_/Vue%EC%9D%98-%ED%98%84%EC%8B%A4</guid>
            <pubDate>Wed, 21 Jul 2021 17:22:06 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/uriyang_/post/3272a46e-685a-49a8-b909-0a4696ae5274/coding-1853305_1920.jpg" alt=""></p>
<h2 id="frontend-개발자의-부푼-꿈">Frontend 개발자의 부푼 꿈</h2>
<p>최근 들어 개발자를 꿈꾸는 사람들이 많아졌다. 처음 개발을 시작하는 개발자들에게는 막연히 스타벅스에서 코딩하고 세미나에서 발표하는 그런 개발자들에 대한 이미지를 꿈꾸며 시작할 수 있다. 특히 <strong>frontend</strong>라는 분야는 비교적 두각을 나타내기 시작한 지 오래되지 않아서, 다른 개발 분야보다 더 멋지고 세련된 느낌도 든다.</p>
<p>내 경우에는 기존에 업무 분야의 기술이 사장되면서, 자연스럽게 가장 유사한 분야인  Frontend를 접했다. 그러면서 기존에 딱딱하고 경직된 분위기의 기업들보다는 자연스럽게 자유롭고 멋있는 방식으로 일하는 이상적인 <strong>스타트업</strong>에서 일하기를 꿈꾸게 되었다.</p>
<h2 id="vue를-만나기까지">Vue를 만나기까지..</h2>
<p>처음 frontend를 시작할 때는 <a href="https://ko.reactjs.org/">React</a>로 시작을 했다. 경력자라는 점만 믿고 무모하게 새로운 분야에 뛰어들었었는데, 감사하게도 이런 나에게 기회를 준 곳이 있었다. </p>
<p>당시의 상황을 회상해 보자면 이렇다.</p>
<blockquote>
<ul>
<li>ES6가 막 뜨기 시작했을 때..</li>
<li>React에서 jsx가 도입되기 시작했을 때..</li>
<li>Redux가 생긴 지 얼마 안 돼서 파격적으로 이슈가 될 때..</li>
<li>구글에서 한글로 된 React 자료를 찾아보면 Velopert님의 글 밖에 나오지 않을 때..</li>
<li><a href="https://nodejs.org/ko/">node.js</a>나 <a href="https://webpack.js.org/">webpack</a>에 관한 자료들은 공식문서 외에 찾아보기 힘들었을 때..</li>
</ul>
</blockquote>
<p>그때 당시 react로 개발한 서비스가 나름 신규서비스로 런칭도 했지만, 당시 WEB이라는 분야에서 jQuery까지밖에 몰랐던 내가 react를 접하면서 느낀 생소한 개념들(es6, node.js, sass, webpack..)은 너무 큰 장벽으로만 다가왔다. 그리고 퇴사 후, 이직의 기회를 맞이한 나는 주변의 엄청난 실력자들과 빠른 생태계 발전을 보면 자신감이 바닥까지 내려가 버렸다. 그리고 실력을 키워 좋은 곳으로 이직하겠다는 핑계를 대며 막연히 공부했다. 그러던 중 커뮤니티 활동을 통해 <a href="https://kr.vuejs.org/v2/guide/index.html">Vue.js</a>라는 새로운 라이브러리에 대한 정보를 얻고, 스터디를 통해 만나게 되었다.</p>
<h2 id="다시-frontend로-그리고-마주한-현실">다시 Frontend로.. 그리고 마주한 현실</h2>
<p>그렇게 나는 다른 스타트업에 입사하게 되었고, Vue.js를 사용하는 Frontend 개발자의 길을 걷게 되었다. 글을 쓰면서 개발자로서의 정체성에 대해 불안했던 과거의 심정과 기억들이 새록새록 떠오른다. 이대로 개발자의 길을 포기하지 않고, 다시금 기회를 가질 수 있게 해준 Vue.js에게 감사의 마음을 돌려본다.</p>
<p>그러나 현실은 녹록치 않았다. </p>
<blockquote>
<p>코드 상태가..
생각했던 것과 많이 다른데..</p>
</blockquote>
<p>이제 그 이야기들을 조금씩 풀어가 보려 한다.</p>
]]></description>
        </item>
    </channel>
</rss>