<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jinny's dev log</title>
        <link>https://velog.io/</link>
        <description>주니어 개발자의 기록</description>
        <lastBuildDate>Sun, 23 Jan 2022 13:49:16 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jinny's dev log</title>
            <url>https://images.velog.io/images/sjkim_jinnyk/profile/0683f573-f894-4833-abb8-acdc6262abf0/내사진동글.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jinny's dev log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sjkim_jinnyk" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[22.01.23 - TIL [ 면접 ]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/22.01.23-TIL-%EB%A9%B4%EC%A0%91</link>
            <guid>https://velog.io/@sjkim_jinnyk/22.01.23-TIL-%EB%A9%B4%EC%A0%91</guid>
            <pubDate>Sun, 23 Jan 2022 13:49:16 GMT</pubDate>
            <description><![CDATA[<h2 id="기술-면접-복기">기술 면접 복기</h2>
<ol>
<li><p>JS 지식</p>
<ul>
<li>클로저 설명</li>
<li>this 설명</li>
<li>var, const, let 차이점</li>
<li>프로토타입 설명</li>
<li>원시 값 종류가 무엇이 있나</li>
<li>함수 세 개에 모두 콘솔로그가 있고, 두 번째 함수에 만 settimeout이 선언되어 그 안에 콘솔로그가 있다.  이 때 자바스크립트 엔진이 작동하는 순서 설명...</li>
<li>null, undefined 차이점</li>
</ul>
</li>
<li><p>HTML, CSS</p>
<ul>
<li>웹 접근성이 무엇?</li>
<li>박스 모델 설명</li>
</ul>
</li>
<li><p>react</p>
<ul>
<li>virtual dom 설명</li>
<li>메모이제이션 설명</li>
</ul>
</li>
<li><p>기타</p>
<ul>
<li>웹 스토리지, 쿠키 차이</li>
<li>브라우저 랜더링 과정 설명</li>
<li>이벤트 버블링, 캡쳐링, 위임 ⇒ 위임을 하면 좋은점은?</li>
<li>CORS 설명 ⇒ CORS 대처한 경험, 백엔드쪽에서 대처하려면 어떻게 해야하나?</li>
<li>CSR, SSR 설명</li>
<li>SPA 설명</li>
<li>사용자가 무엇을 할 때마다 어떤 동작이 실행되고, 화면이 새로고침 된다면 이 때 무엇을 해서 해결할 수 있는가..? ⇒ 디바운스를 말하시는 것 같아 디바운스 얘기 ⇒ 디바운스를 안다면 쓰로틀링도 아시겠네요? ⇒  쓰로틀링은 무엇인가?</li>
<li>call by reference, call by value의 차이는?</li>
<li>바벨은 무엇인가요?</li>
<li>웹팩은 무엇인가요?</li>
<li>package.json에서 dependency, devDependency 차이</li>
<li>get, post 차이</li>
<li>Http와 Https 의 차이는?</li>
<li>최적화 방법 아는대로 다 말해달라</li>
<li>함수형 프로그래밍은 무엇인가?</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[22.01.22 - TIL [ react ]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/22.01.22-TIL-react</link>
            <guid>https://velog.io/@sjkim_jinnyk/22.01.22-TIL-react</guid>
            <pubDate>Sat, 22 Jan 2022 13:18:45 GMT</pubDate>
            <description><![CDATA[<h1 id="usestate-최신-값-유지">useState() 최신 값 유지</h1>
<blockquote>
<p>리액트가 state 업데이트를 즉각적으로 해주지 않기 때문에 마지막 업데이트가 최신 state 값에 적용되지 않을 수 있다. </p>
</blockquote>
<p>안 좋은 코드</p>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;

function test () {
  const [data, setData] = useState([]);

  function NewData(newData) {
    setData(data.concat(newData));
  }
}
</code></pre>
<p>좋은 코드
: 새 값을 직접 전달하는 것보다 함수를 전달하여 함수를 실행하게 만들자.</p>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;

function test () {
  const [data, setData] = useState([]);

  function NewData(newData) {
    setData((prevData)=&gt; {
      return prevData.concat(newData);
    })
  }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.01.21 - TIL [ react ]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.01.21-TIL-react</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.01.21-TIL-react</guid>
            <pubDate>Fri, 21 Jan 2022 05:31:22 GMT</pubDate>
            <description><![CDATA[<h1 id="react-router-dom-버전-업데이트">react-router-dom 버전 업데이트</h1>
<h2 id="usehistory--usenavigate">useHistory =&gt; useNavigate</h2>
<p>변경 전</p>
<pre><code class="language-js">import { useHistory } from &quot;react-router-dom&quot;;

const history = useHistory();

history.push(&quot;/&quot;);
history.replace(&quot;/&quot;);</code></pre>
<p>변경 후 </p>
<pre><code class="language-js">import { useNavigate } from &quot;react-router-dom&quot;;

const navigate = useNavigate();

navigate(&quot;/&quot;);
navigate(&quot;/&quot;, { replace:true });</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[22.01.18 - TIL [react]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/22.01.18-TIL-react</link>
            <guid>https://velog.io/@sjkim_jinnyk/22.01.18-TIL-react</guid>
            <pubDate>Tue, 18 Jan 2022 06:23:50 GMT</pubDate>
            <description><![CDATA[<h1 id="react">react</h1>
<h2 id="이벤트-연결">이벤트 연결</h2>
<blockquote>
<p>함수를 바인딩 할 때 () 괄호를 쓰면 자바스크립트가 코드를 계산할 때 같이 실행된다. 버튼을 클릭할 때 함수가 실행되도록 해야하니 () 괄호를 쓰면 안된다.  </p>
</blockquote>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;

function test() {
  const [click, setClick] = useState(false);

  function handler() {
    setClick(true);
  }

  return (
    &lt;button onClick={handler}&gt;이벤트&lt;/button&gt;
  )
}</code></pre>
<br>


<h2 id="삼항연산자">삼항연산자</h2>
<blockquote>
<pre><code>{ click ? &lt;Modal /&gt; : null }</code></pre></blockquote>
<pre><code>&gt; 클릭이 true일 때 `&lt;Modal /&gt;` 컴포넌트 바인딩, false일 때 null 바인딩
&gt;
&gt; &lt;br /&gt;
&gt;</code></pre><p>{ click &amp;&amp; <Modal /> }</p>
<pre><code>&gt; 컴포넌트 함수는 항상 true이기 때문에 논리곱 연산자에 의해 두 조건이 모두 true일 경우 마지막 조건이 반환
&gt;

```jsx
import { useState } from &quot;react&quot;;
import Modal from &quot;./components/Modal&quot;;

function test() {
  const [click, setClick] = useState(false);

  function handler() {
    setClick(true);
  }

  return (
    &lt;button onClick={handler}&gt;이벤트&lt;/button&gt;
    { click ? &lt;Modal /&gt; : null }
    { click &amp;&amp; &lt;Modal /&gt; } 
  )
}</code></pre><br>

<h2 id="props로-함수-전달">props로 함수 전달</h2>
<blockquote>
<p>props로 값을 키와 value 형태로 내려주는 것과 같이 사용하면 된다.
부모 컴포넌트에서 설정한 키 이름으로 자식 컴포넌트에서 사용 가능</p>
</blockquote>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;
import Modal from &quot;./components/Modal&quot;;

function test() {
  const [click, setClick] = useState(false);

  function handler() {
    setClick(true);
  }

  function closeModal() {
    setClick(false);
  }

  return (
    &lt;button onClick={handler}&gt;이벤트&lt;/button&gt;
    { click &amp;&amp; &lt;Modal onClose={closeModal}/&gt; } 
  )
}</code></pre>
<p><strong>Modal 컴포넌트</strong></p>
<blockquote>
<p>Modal 컴포넌트 부분을 클릭했을 때 부모 컴포넌트에서 내려온 onClose가 실행 </p>
</blockquote>
<pre><code class="language-jsx">function Modal(props) {
  return &lt;div className=&quot;modal&quot; onClick={props.onClose} /&gt;;
}</code></pre>
<h2 id="react-router-dom">react-router-dom</h2>
<blockquote>
<p>react-router-dom 버전이 업그레이드 되면서 
<strong>Switch -&gt; Routes</strong>
<strong>component -&gt; element={<code>&lt;component /&gt;</code>}</strong> 로 변경되었다. </p>
</blockquote>
<p><strong>변경 전</strong></p>
<pre><code class="language-jsx">import { Route, Switch } from &quot;react-router-dom&quot;;
import MeetUpPage from &quot;./pages/MeetUp&quot;;

function App() {
  return (
    &lt;div&gt;
      &lt;Switch&gt;
        &lt;Route path=&quot;/&quot;&gt;
          &lt;MeetUpPage /&gt;
        &lt;Route&gt;
      &lt;/Switch&gt;
    &lt;/div&gt;
  );
}

export default App;</code></pre>
<br>

<p><strong>변경 후</strong></p>
<pre><code class="language-jsx">import { Route, Routes } from &quot;react-router-dom&quot;;
import MeetUpPage from &quot;./pages/MeetUp&quot;;

function App() {
  return (
    &lt;div&gt;
      &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; exact element={&lt;MeetUpPage /&gt;} /&gt;
      &lt;/Routes&gt;
    &lt;/div&gt;
  );
}

export default App;</code></pre>
<p><strong>&#39;Switch&#39; is not exported from &#39;react-router-dom&#39; 에러가 난다면 버전이 업그레이드 됐으니 위와 같은 형식으로 바꿔야한다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[22.01.04 - TIL [ vue debounce ]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/22.01.04-TIL-vue-debounce</link>
            <guid>https://velog.io/@sjkim_jinnyk/22.01.04-TIL-vue-debounce</guid>
            <pubDate>Tue, 04 Jan 2022 01:22:10 GMT</pubDate>
            <description><![CDATA[<h1 id="vue-debounce-사용">vue debounce() 사용</h1>
<h3 id="debounce란">debounce란?</h3>
<p>: 특정시간이 지난 시점에서 이벤트가 하나만 발생하도록 제어하는 기술
 &nbsp; 연속적으로 호출되는 함수들 중 마지막 함수 또는 제일 처음만 호출하도록 하는 것</p>
<blockquote>
<p>data 값이 변경될 때 debounce()에 의해 1초 후에 콘솔에 바뀐 값이 찍힌다.
watch를 이용해 score의 값이 바뀌는 것을 인식하고 debounce() 실행!</p>
</blockquote>
<pre><code class="language-js">import debounce from &quot;lodash/debounce&quot;;

export default {
 data() {
    return {
      str: &quot;&quot;,
    };
  },
  watch: {
    str: debounce(function (newVal) {
      if (newVal.length &gt;= 2) {
        console.log(newVal)
      }
    }, 1000),
  },
}</code></pre>
<ul>
<li>str에 &quot;안녕하세요&quot;를 입력해서 넣으면 &quot;요&quot;까지 입력한 후 1초 뒤에 콘솔 창에 &quot;안녕하세요&quot;가 뜬다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.12.17 - TIL [면접 질문]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.12.17-TIL-%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.12.17-TIL-%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8</guid>
            <pubDate>Fri, 17 Dec 2021 08:10:13 GMT</pubDate>
            <description><![CDATA[<h1 id="프론트엔드-면접-질문">프론트엔드 면접 질문</h1>
<br>

<h2 id="웹-보안">웹 보안</h2>
<hr>
<h3 id="sop-same-origin-policy">SOP (Same Origin Policy)</h3>
<p>: 출처가 다를 경우 리소스 상호작용을 하지 못하도록 막는 보안 방식</p>
<ul>
<li>같은 출처는 리소스 상호작용이 자유롭다. 이때 프로토콜, 호스트, 포트가 같아야 같은 출처라고 할 수 있다. </li>
<li>태그로 embedding 하는 것은 외부 리소스(출처가 다른 경우)를 가져와도 상호작용이 가능하다. </li>
<li>잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여주기 때문에 사용한다.</li>
</ul>
<h3 id="cors-cross-origin-resource-sharing">CORS (Cross-Origin Resource Sharing)</h3>
<p>: 현재 출처에서 다른 출처의 리소스에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제</p>
<ul>
<li>SOP 정책을 우회해서 사용할 수 있는 방식이다. </li>
<li>cross-origin HTTP로 리소스를 요청한다면 SOP 정책에 의해 외부서버에 요청한 데이터를 브라우저에서 보안목적으로 차단된다. 
이 때 <code>Access-Control-Allow-Origin</code> 을 통해 cross-origin HTTP 요청을 허가하는 헤더를 추가해주면 된다. <pre><code class="language-js">app.use((req, res, next) =&gt; {
  res.header(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;); // 모든 도메인
  res.header(&quot;Access-Control-Allow-Origin&quot;, &quot;https://example.com&quot;); // 특정 도메인
});</code></pre>
<br>

</li>
</ul>
<h2 id="웹-브라우저">웹 브라우저</h2>
<hr>
<h3 id="브라우저가-웹-페이지를-랜더링하는-과정">브라우저가 웹 페이지를 랜더링하는 과정</h3>
<p>사용자가 페이지에 접속하면 HTML을 서버에서 내려받게 되고 브라우저 렌더링 엔진에서 파싱(처리)하며 <code>DOM 트리</code>를 만든다.
link 태그를 통해 CSS 파싱을 해서 <code>CSSOM 트리</code>를 만든다. 
DOM 트리와 CSSOM 트리를 결합한 것이 <code>렌더 트리</code>가 되고, 레이아웃 작업을 통해 사용자에게 그려줄 영역을 계산해서 화면에 뿌려준다. 이 과정을 진행하다가 자바스크립트 런타임 환경에 수행 권한을 넘겨 결과 값을 받으면 DOM 파싱은 중단된다.(때문에 대부분의 script 태그는 body 하단에 존재)
모든 노드 수치를 재계산해서 렌더 트리를 재생성하는 과정을 <code>reflow</code>라 하고, 이후 재생성된 렌더 트리를 다시 그리는 것을 <code>repaint</code>라 한다. 리페인트는 레이아웃 수치에 영향을 끼칠 때만 진행된다. </p>
<br>

<h2 id="css">CSS</h2>
<hr>
<h3 id="css-sprite">CSS Sprite</h3>
<p> : css에서 이미지를 사용할 때 여러 개의 이미지를 하나로 합쳐서 각 이미지를 background-position 속성을 통해 잘라서 사용하는 기법</p>
<ul>
<li>페이지의 첫 로딩속도를 줄여 서버로의 요청 횟수를 최소화하는 최적화기법중 하나이다.</li>
<li>요청 한번으로 사용할 이미지를 한번에 불러 올 수 있기때문에 로딩이 줄어든다. 즉 성능 최적화가 된다는 장점이 있다. </li>
<li>이미지를 합쳐서 사용하기 때문에 이미지가 많아지면 오히려 파일의 용량이 커져 로딩이 오래 걸리는 단점이 있다. </li>
<li>수정이 많은 이미지에는 사용하기가 어렵다는 단점이 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.12.11 - TIL [이벤트 버블링]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.12.11-TIL-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.12.11-TIL-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81</guid>
            <pubDate>Sat, 11 Dec 2021 00:09:10 GMT</pubDate>
            <description><![CDATA[<h1 id="이벤트-버블링">이벤트 버블링</h1>
<p>: 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미
<img src="https://images.velog.io/images/sjkim_jinnyk/post/73bb1eb3-3554-4a5d-b705-e2d8b49cd08a/image.png" alt=""></p>
<p>EX) &quot;클릭&quot; 부분을 클릭하면 console 창에 차례로 div, body, html이 뜬다. </p>
<pre><code class="language-html">&lt;html&gt;
&lt;body&gt;
  &lt;div&gt;클릭&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-js">const html = document.documentElement;
const body = document.body;
const div = document.querySelector(&quot;div&quot;);

body.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;body&quot;);
});
html.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;html&quot;);
});
div.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;div&quot;);
});</code></pre>
<p>가장 하위에 있는 div의 이벤트가 최상위에 있는 요소까지 이벤트가 전달됐다.
이것을 <strong>이벤트 버블링</strong>이라 한다. </p>
<h1 id="이벤트-캡쳐링">이벤트 캡쳐링</h1>
<p>: 이벤트 버블링과 반대 방향으로 진행되는 이벤트 전파 방식 </p>
<p>EX) <a href="https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener">이벤트리스너</a>의 마지막 매개변수에 boolean 값을 넣으면 capture 값이 할당된다. default 값은 false로, 캡쳐단계를 거치지 않는다는 것을 뜻함.
&quot;클릭&quot; 부분을 클릭하면 <code>html 캡쳐 -&gt; body 캡쳐 -&gt; div 캡쳐 -&gt; div -&gt; body -&gt; html</code>의 순서로 출력된다. </p>
<pre><code class="language-html">&lt;html&gt;
&lt;body&gt;
  &lt;div&gt;클릭&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-js">const html = document.documentElement;
const body = document.body;
const div = document.querySelector(&quot;div&quot;);

body.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;body&quot;);
});
html.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;html&quot;);
});
div.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;div&quot;);
});

body.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;body 캡쳐&quot;);
}, true);
html.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;html 캡쳐&quot;);
}, true);
div.addEventListener(&quot;click&quot;, () =&gt; {
  console.log(&quot;div 캡쳐&quot;);
},true);</code></pre>
<p>이벤트 대상을 찾아갈 때 가장 상위의 window 객체부터 document, body 순으로 DOM 트리를 따라 이벤트가 전달된다.
이것을 <strong>이벤트 캡쳐링</strong> 이라 한다. </p>
<h1 id="이벤트-위임">이벤트 위임</h1>
<p>이벤트 버블링과 캡쳐링을 통해 이벤트의 흐름을 알아보았다. 이러한 흐름을 이용해 이벤트 리스너가 없어도 마치 리스너가 있는 것 처럼 사용 할 수 있다. </p>
<p>EX) 부모 요소에만 이벤트 리스너를 주었지만 각 버튼을 누르면 버튼의 내용이 &quot;버튼4&quot;로 바뀐다. </p>
<pre><code class="language-html">&lt;html&gt;
&lt;body&gt;
  &lt;article class=&quot;parent&quot;&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;button class=&quot;btn-first&quot; type=&quot;button&quot;&gt;버튼1&lt;/button&gt;&lt;/li&gt;
      &lt;li&gt;&lt;button type=&quot;button&quot;&gt;버튼2&lt;/button&gt;&lt;/li&gt;
      &lt;li&gt;&lt;button type=&quot;button&quot;&gt;버튼3&lt;/button&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/article&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-js">const parent = document.querySelector(&#39;.parent&#39;);
parent.addEventListener(&#39;click&#39;, function (event) {
  if (event.target.nodeName === &quot;BUTTON&quot;) {
    event.target.innerText = &quot;버튼4&quot;;
  }
})</code></pre>
<p>하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트들을 제어하는 방식이다. 
이것을 <strong>이벤트 위임</strong>이라 한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.12.10 - TIL [CSR vs SSR]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.12.10-TIL-CSR-vs-SSR</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.12.10-TIL-CSR-vs-SSR</guid>
            <pubDate>Fri, 10 Dec 2021 06:42:53 GMT</pubDate>
            <description><![CDATA[<h1 id="csr-client-side-rendering">CSR (Client Side Rendering)</h1>
<p>: 데이터가 없는 HTML(이외에 static 파일들)만 받아오고, 데이터는 HTML문서와 여러 스테틱 파일들이 로드된 이후에 요청해서 받아오는 방식으로 진행된다.
<img src="https://images.velog.io/images/sjkim_jinnyk/post/deb6bce2-557e-461f-9b55-d82979041e1d/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/sjkim_jinnyk/post/f5a4d7dc-29b7-4deb-b84a-78df7758fcce/image.png" alt="">
Browser가 서버에 HTML과 static파일을 요청한 후 로드되면 사용자의 상호작용에 따라 JS가 동작하면서 데이터만을 주고 받아서 Rendering한다. </p>
<h2 id="장점">장점</h2>
<ol>
<li><p>첫 로딩에 HTML과 static파일들만 다 받으면, 동적으로 빠르게 Rendering하기 때문에 <strong>사용자 UX가 뛰어나다.</strong></p>
</li>
<li><p>필요하고 변경된 데이터만 받아올 수 있어 서버 측에서 전체 페이지를 다시 읽어 들이는 것보다 빠른 인터랙션이 가능하다. 즉 <strong>서버 부담이 덜하다.</strong></p>
<h2 id="단점">단점</h2>
</li>
<li><p>HTML 다운, JS 파일 등 각 종 자원(Resource)을 다운로드한 후에 브라우저에서 렌더링을 하기 때문에 <strong>초기 구동 속도가 느리다.</strong> </p>
</li>
<li><p>SEO(검색엔진 최적화) 문제가 발생할 수 있다.</p>
<ul>
<li>View를 생성하기 위해선 반드시 JavaScript를 실행시켜야 한다. 하지만, <strong>대부분 웹 크롤러 봇들은 JavaScript파일을 실행시키지 못하기 때문에</strong> HTML에서만 콘텐츠들을 수집하게 되고 CSR페이지를 빈 페이지로 인식하게 된다.</li>
</ul>
</li>
</ol>
<br>

<h1 id="ssr-server-side-rendering">SSR (Server Side Rendering)</h1>
<p>: 사용자가 웹 페이지에 접근할 때, 웹 서버에 각각의 페이지에 대한 요청을 하며 웹 서버에서 html, js 파일 등을 다 다운로드하여 화면에 렌더링하는 방식</p>
<p><img src="https://images.velog.io/images/sjkim_jinnyk/post/c269d15f-f330-4c9e-b151-2a9a8393237b/image.png" alt=""></p>
<p> 웹 서버에 요청할 때마다 웹 브라우저에서 새로고침이 일어나고 서버에 새로운 페이지에 대한 요청을 하는 방식이다.</p>
<h2 id="장점-1">장점</h2>
<ol>
<li>SEO(검색엔진 최적화) 가능</li>
<li>초기 로딩 속도가 빠르기 때문에 사용자가 컨텐츠를 빨리 볼 수 있다.<h2 id="단점-1">단점</h2>
<ol>
<li>매번 페이지를 요청할 때마다 새로고침 되기 때문에 사용자 UX가 다소 떨어진다.</li>
<li>서버에 매번 요청을 하기 때문에 트래픽, 서버 부하가 커진다.</li>
</ol>
</li>
</ol>
<blockquote>
<p><strong>SEO란?</strong>
Search Engine Optimization의 약어로 웹 페이지 검색엔진이 자료를 수집하고 순위를 매기는 방식에 맞게 페이지를 구성하여 *<em>검색 결과의 상위에 나올 수 있도록 하는 작업 *</em></p>
</blockquote>
<p><strong>웹 크롤러란?</strong>
 방대한 웹 페이지를 두루두루 방문하여, 각종 정보를 자동적으로 수집하는 일을 하는 프로그램</p>
<p><img src="https://images.velog.io/images/sjkim_jinnyk/post/749e5f1a-c6a7-46a9-93ae-a967aa9e0218/image.png" alt=""></p>
<br>

<blockquote>
<p>참고
<a href="https://velog.io/@namezin/CSR-SSR">CSR, SSR</a>
<a href="https://ivorycode.tistory.com/entry/SSRSever-Side-Rendering%EA%B3%BC-CSRClient-Side-Rendering">SSR(Sever Side Rendering)과 CSR(Client Side Rendering)</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.12.03 - TIL [nuxt.js]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.12.03-TIL-nuxt.js</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.12.03-TIL-nuxt.js</guid>
            <pubDate>Fri, 03 Dec 2021 02:02:09 GMT</pubDate>
            <description><![CDATA[<h1 id="nuxt-사용">Nuxt 사용</h1>
<p>프로젝트를 진행 시 vue로 시작했으나 <strong>메타 이미지</strong>와 <strong>SEO 최적화</strong>를 위해 nuxt 프레임워크를 도입해야했다. vue로 완성했지만 nuxt로 변환해주면서 생긴 문제들이 있었다.</p>
<h2 id="vue-vs-nuxt-디렉토리-구조-차이">Vue vs Nuxt 디렉토리 구조 차이</h2>
<hr>
<p><img src="https://images.velog.io/images/sjkim_jinnyk/post/40aa0d89-3c62-4b27-84c7-14cecec0a32e/IMG_31C859CCCB59-1.jpeg" alt=""></p>
<blockquote>
<p><strong>가장 큰 차이는 router 파일을 따로 안써도 된다는 점!!</strong></p>
</blockquote>
<br>


<h3 id="vue-router">Vue router</h3>
<p><strong>vue</strong>에서는 라우터 연결을 하려면 router 폴더에 js 파일을 만들어서 직접 연결을 해줘야했다.
<img src="https://images.velog.io/images/sjkim_jinnyk/post/0a798980-fea5-436e-8d54-8bc633308e64/%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-12-03%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2010.21.39.png" width="70%"></p>
<h3 id="nuxt-router">Nuxt router</h3>
<p>하지만 <strong>nuxt</strong>에서는 pages 폴더에 파일을 만들면 자동으로 라우터 연결을 시켜준다. <code>.nuxt</code> 폴더에 숨겨진 router.js에 자동으로 만들어준다.
pages에 <code>questions.vue</code>, <code>tutorial.vue</code>, <code>index.vue</code> 파일이 있는 것이다.
<img src="https://images.velog.io/images/sjkim_jinnyk/post/ed13efd2-51f8-4a10-a2d9-b4bca65b5171/IMG_1043.jpg" width="70%"></p>
<h3 id="이-때-발생한-문제점">이 때 발생한 문제점</h3>
<blockquote>
<p><strong>vue</strong>에서는 router.js 파일에 <code>props: true</code> 를 선언해두면 페이지가 넘어갈 때 <strong>params 값을 넘겨줄 수 있다.</strong></p>
</blockquote>
<pre><code class="language-js">this.$router.push({ name: &quot;Loading&quot;, params: { firstTest: true } } );

// Loading.vue
props: [&quot;firstTest&quot;]</code></pre>
<p>Loading이라는 이름을 가진 페이지로 넘어가면서 변수 firstTest의 값 true가 전달되어 사용 가능하다.</p>
<blockquote>
<p><strong>nuxt</strong>에서는 router.js가 자동 생성되기 때문에 <strong>vue처럼 params 값을 넘겨줄 수 없었다.</strong> 
<strong>그래서 찾은 방법은 쿼리로 넘겨주기!</strong></p>
</blockquote>
<pre><code class="language-js">this.$router.push({path: &quot;Loading?firstTest=true&quot;});

// Loading.vue
data() {
    return {
      firstTest: null,
    }
},
created() {
    if (this.$route.query.firstTest) {
      this.firstTest = this.$route.query.firstTest;
    }
}</code></pre>
<p>쿼리를 이용하면 페이지를 따로 만들지 않아도 Loading과 동일한 페이지지만 데이터를 넘겨받을 수 있다. 생각해보면 간단한데 이걸 이틀이나 서치하고 생각했다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.02 - TIL [nuxt.js]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.02-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.02-TIL</guid>
            <pubDate>Thu, 02 Dec 2021 13:23:18 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘의-nuxt">오늘의 Nuxt</h1>
<h2 id="nuxtconfigjs">nuxt.config.js</h2>
<hr>
<blockquote>
<p>Nuxt.js의 사용자 정의 설정을 포함하는 파일이다.
전역에서 사용될 head, script, css 태그들을 설정하는 곳이다.</p>
</blockquote>
<pre><code class="language-js">export default {
  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: &quot;nuxt&quot;,
    htmlAttrs: {
      lang: &quot;ko&quot;,
    },
    meta: [
      { charset: &quot;utf-8&quot; },
      { name: &quot;viewport&quot;, content: &quot;width=device-width, initial-scale=1&quot; },
      { hid: &quot;description&quot;, name: &quot;description&quot;, content: &quot;&quot; },
      { name: &quot;format-detection&quot;, content: &quot;telephone=no&quot; },
    ],
    link: [
      { rel: &quot;icon&quot;, type: &quot;image/x-icon&quot;, href: &quot;/favicon.ico&quot; },
      {
        rel: &quot;stylesheet&quot;,
        href: &quot;https://use.fontawesome.com/releases/v5.15.4/css/all.css&quot;,
        integrity:
          &quot;sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm&quot;,
        crossorigin: &quot;anonymous&quot;,
      },
    ],
    script: [
      {
        src: &quot;https://developers.kakao.com/sdk/js/kakao.js&quot;,
      },
  },

  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [&quot;@/assets/css/reset.css&quot;, &quot;@/assets/css/styles.css&quot;],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [
    // https://go.nuxtjs.dev/eslint
    &quot;@nuxtjs/eslint-module&quot;,
  ],

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    // https://go.nuxtjs.dev/axios
    &quot;@nuxtjs/axios&quot;,
  ],

  // Axios module configuration: https://go.nuxtjs.dev/config-axios
  axios: {},

};</code></pre>
<br>


<h3 id="오늘의-문제점">오늘의 문제점</h3>
<p>head 태그 안에 script 태그가 객체로 선언되었기 때문에 name과 value의 형태로 넣어야 했다. </p>
<blockquote>
<pre><code class="language-js">script: [
  {    
      name : &quot;value&quot;
  }
]</code></pre>
</blockquote>
<pre><code>```html
&lt;head&gt;
  &lt;script name=&quot;value&quot;&gt;&lt;/script&gt;
&lt;/head&gt;</code></pre><blockquote>
</blockquote>
<br>

<p>하지만 내가 넣어야하는 것은 <strong>스트립트 태그 안에 내용을 넣어야했다.</strong> 객체 형태를 유지해야 했기 때문에 이리저리 헤맸는데 알고 보니 엄청 간단한 문제였다.
<strong>바로 <code>innerHTML</code>을 이용하는 것!!!</strong></p>
<blockquote>
<pre><code class="language-js">script: [
  {    
      name : &quot;value&quot;
  },
  {
      innerHTML : &quot;텍스트&quot;
  }
]</code></pre>
</blockquote>
<pre><code>```html
&lt;head&gt;
  &lt;script name=&quot;value&quot;&gt;&lt;/script&gt;
  &lt;script&gt;텍스트&lt;/script&gt;
&lt;/head&gt;</code></pre><blockquote>
</blockquote>
<p>간단한 문제 해결 끝~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.12.01 - TIL [assets vs static]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.12.01-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.12.01-TIL</guid>
            <pubDate>Wed, 01 Dec 2021 14:35:28 GMT</pubDate>
            <description><![CDATA[<h1 id="assets-vs-static">assets vs static</h1>
<h2 id="assets">assets</h2>
<p>assets 폴더는 주로 css, style 등 리소스들이 위치한다. 이 디렉토리에 담긴 리소스는 빌드 시 Webpack이 처리한다. 파일 경로를 읽는 것이 아니라 파일을 문자열로 인코딩하여 코드에 삽입하는 방식이다. 
파일의 크기가 크다면 인코딩할 때 길이가 길어져 효율성이 떨어지는 단점이 있다. </p>
<h2 id="static">static</h2>
<p>static 폴더는 이미지, 폰트와 같은 정적 리소스들이 위치하게 된다. 이 디렉토리에 담긴 리소스는 Webpack을 거치지 않고 빌드 결과물 디렉터리인 dist 디렉터리로 옮겨진다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.29 - TIL [CSS]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.29-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.29-TIL</guid>
            <pubDate>Mon, 29 Nov 2021 14:26:45 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘의-css">오늘의 CSS</h1>
<h2 id="marker에-margin-값-주기">::marker에 margin 값 주기</h2>
<blockquote>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::marker">::marker mdn </a></p>
</blockquote>
<p> marker는 기본 margin 값을 갖고 있다. mdn에서 정의한 6가지 속성만 적용되기 때문에 직접적인 margin 값 조절이 안된다. li를 통해 margin 값을 변경할 수 있다.</p>
<pre><code class="language-html">&lt;ul&gt;
  &lt;li&gt;
    &lt;span&gt; 참을성이 많고 성실하다. &lt;/span&gt;
  &lt;/li&gt;
&lt;/ul&gt;</code></pre>
<pre><code class="language-css">li span {
  position : relative;
  margin : -10px;
}
</code></pre>
<img src="https://images.velog.io/images/sjkim_jinnyk/post/6f62bf1f-6500-4ee5-bfa0-f89d1004606a/%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-11-29%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.22.39.png" width="50%">

<img src="https://images.velog.io/images/sjkim_jinnyk/post/a8389d51-9592-4900-b616-f8467c22d06c/%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-11-29%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.20.04.png" width="50%">

<blockquote>
<p>marker의 margin을 직접 조절하는 것이 아니라 span 태그의 margin을 마이너스로 줘서 간격을 줄인 듯한 효과를 나타낸다.</p>
</blockquote>
<br>

<h1 id="회고">회고</h1>
<p>프로젝트 깃 꼬임을 두시간 넘게 풀었다. 간단한 꼬임이었는데 이렇게 오래 걸릴 줄 몰랐다..후 
내일은 nuxt.js를 적용해야한다....화이팅...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.26 - TIL [면접 질문]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.26-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.26-TIL</guid>
            <pubDate>Fri, 26 Nov 2021 11:24:05 GMT</pubDate>
            <description><![CDATA[<h1 id="프론트엔드-면접-스터디">프론트엔드 면접 스터디</h1>
<h2 id="javascript">JavaScript</h2>
<hr>
<h3 id="npm">npm</h3>
<p>Node Package Manager의 약자
자바스크립트 패키지 매니저이고 NodeJS에서 사용할 수 있는 모듈들을 패키지화하여 모아둔 저장소 
패키지를 설치/관리를 수행할 수 있는 CLI를 제공</p>
<blockquote>
<p><strong>package.json</strong>
 npm 패키지들을 관리하는 파일
 프로젝트의 정보와 프로젝트에서 사용 중인 패키지의 의존성을 관리하게 된다.</p>
</blockquote>
<ul>
<li><code>dependency</code>
라이브러리나 프레임워크 같이 실제 프로덕트에서 사용되는 것들이 담긴다.</li>
<li><code>devDependency</code><blockquote>
<p>개발을 편하게 해주는 도구들이 담긴다.
<img src="https://images.velog.io/images/sjkim_jinnyk/post/55e77279-7d1c-4f75-bccf-ef99f5cd73ff/%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-11-26%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.19.01.png" alt=""></p>
</blockquote>
</li>
</ul>
<br>

<h2 id="etc">ETC</h2>
<hr>
<h3 id="단위테스트unit-test">단위테스트(unit test)</h3>
<p>소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 가장 작은 단위의 테스트
즉, 모든 함수와 메소드에 대한 테스트 케이스(Test case)를 작성하는 절차</p>
<blockquote>
<h4 id="단위테스트를-하면-좋은점">단위테스트를 하면 좋은점</h4>
</blockquote>
<ol>
<li>연관 컴포넌트가 완성되지 않아도 구현 코드가 정상 작동하는지 알 수 있다. 
내가 작성한 구현 코드를 단위테스트를 통해 정확히 작동하는지 검증한다면 연관 컴포넌트가 완성되기 전에 개발이 완료 됐다는 것을 증명할 수 있다.<blockquote>
</blockquote>
</li>
<li>문제점을 빠르게 발견할 수 있다.
해당 부분만 독립적으로 테스트하기 때문에 빠르게 문제 여부를 확인할 수 있어 코드 리팩토링이 편해지고, 코드 품질을 향상시킬 수 있다. <blockquote>
</blockquote>
</li>
<li>코드에 대한 문서가 될 수 있다.
배포되는 코드와 일치하므로 항상 최신 상태로 유지되고 코드의 문서라고 볼 수 있다.<blockquote>
</blockquote>
</li>
</ol>
<blockquote>
<p>** 좋은 단위 테스트 FIRST 규칙**
Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.
Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다.
Repeatable: 어느 환경에서도 반복 가능해야 한다.
Self-Validating: 테스트는 성공 또는 실패로 boolean 값으로 결과를 내어 자체적으로 검증되어야 한다.
Timely: 적시에 사용해야한다. 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.</p>
</blockquote>
<br>

<h2 id="출처">출처</h2>
<hr>
<p><a href="https://sabarada.tistory.com/68">unit test</a>
Clean Code 책</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.24 - TIL [Vue - style scoped]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.24-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.24-TIL</guid>
            <pubDate>Wed, 24 Nov 2021 13:50:55 GMT</pubDate>
            <description><![CDATA[<h1 id="style-scoped">style scoped</h1>
<p><code>&lt;style scoped&gt;</code>를 사용하면 CSS는 해당 컴포넌트의 엘리먼트에만 적용된다. </p>
<blockquote>
</blockquote>
<p>soped를 적용하면</p>
<pre><code class="language-vue">&lt;template&gt;
  &lt;div class=&quot;example&quot;&gt;Hello World&lt;/div&gt;
&lt;/template&gt;
&gt;
&lt;style scoped&gt;
.example {
  color: blue;
}
&lt;/style&gt;</code></pre>
<blockquote>
<p>이런 식으로 자동 변환된다. </p>
</blockquote>
<pre><code class="language-vue">&lt;template&gt;
  &lt;div class=&quot;example&quot; data-v-f123ggf&gt;Hello World&lt;/div&gt;
&lt;/template&gt;
&gt;
&lt;style scoped&gt;
.example[data-v-f123ggf] {
  color: blue;
}
&lt;/style&gt;</code></pre>
<p>부모 컴포넌트에서 scoped를 사용하면 하위 컴포넌트까지 내려간다.
블럭 처리된 부분이 컴포넌트로 삽입된 부분인데 부모인 컨테이너의 scoped가
하위 컴포넌트인 블럭까지 내려간 것을 볼 수 있다. 
하위 컴포넌트에서도 style scoped를 사용하였기 때문에 data-v로 시작하는 명이 두개가 되는 것이다. 
<img src="https://images.velog.io/images/sjkim_jinnyk/post/c57d126d-21a5-4309-8a29-c90fc8471d4c/%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-11-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.54.28.png" alt=""></p>
<p>부모 style에서 태그를 이용해 스타일을 줬다면 하위 컴포넌트에 영향이 갈 가능성이 있으니 class,id를 이용해 스타일을 주는 것을 권장한다. 
<br></p>
<h1 id="회고">회고</h1>
<p>오늘은 오늘의 집 조은 개발자님의 특강을 들었다. 다른 사람과 차별되는 나만의 무기가 무엇이 있을까 진지하게 고민해야겠다. 지금으로선..전혀 없다..
그리고 이제부턴 가고 싶은 분야, 회사를 찾아서 분석해봐야겠다. 그 회사에서 무얼 요구하는지, 어떤 사람을 원하는지 지금부터 탐색해야 나중에 기회가 왔을 때 잡을 수 있을 것이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.23 - TIL [Linux]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.23-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.23-TIL</guid>
            <pubDate>Tue, 23 Nov 2021 13:50:14 GMT</pubDate>
            <description><![CDATA[<h1 id="linux">Linux</h1>
<h2 id="구름-ide로-실습하기">구름 IDE로 실습하기</h2>
<hr>
<h3 id="명령어">명령어</h3>
<pre><code class="language-shell">$ mkdir 폴더이름 : 폴더 생성
$ rmdir 폴더이름 : 폴더 제거
$ pwd : 현재 루트 확인
$ ls : 전체 폴더를 리스트로
$ touch test.txt : test.txt 파일 생성
$ mv 파일명 변경할파일명 : 이름 변경 명령어가 없기 때문에 현재 파일 지우고 다른 파일을 생성
$ cat : 파일 안 내용 읽음
$ more : 대용량 파일 안 내용 읽음(enter 누르면 한 줄씩 읽고, 스페이스는 한 페이지씩, b는 이전페이지, q는 종료)

$ vi test.txt : editing 가능
     i   : 입력모드
        esc : 명령모드
        :wq : 나가기
        dd  : 한 줄 삭제
        yy  : 복사
        p   : 붙여넣기(커서 밑으로)
        i   : 커서 앞으로 텍스트 추가
        a   : 커서 뒤로 텍스트 추가
        o   : 커서 밑 한 줄 추가
          shift + i : 커서를 맨 앞으로
        shift + a : 커서를 맨 뒤로
        shift + v : 여러 줄 선택 가능(이 상태에서 y는 복사, p는 붙여넣기, d는 삭제)
        /찾을 문자열(이 상태에서 n을 누르면 다음 찾은 문자열, N은 이전 문자열)</code></pre>
<br>

<h3 id="서버-실행">서버 실행</h3>
<p>구름 IDE에서 제공하는 도메인으로 연결되어 서버를 실행할 수 있다. </p>
<ol>
<li><p>깃 설치</p>
<pre><code class="language-shell">$ sudo apt-get install git</code></pre>
<p> sudo는 Super User Do
 apt-get은 패키지 매니저! 앱을 다운로드하는 google studio와 같은 역할</p>
</li>
<li><p>원하는 깃 주소 클론</p>
<pre><code class="language-shell">git clone https://github.com/paullabkorea/10000hour.git</code></pre>
</li>
<li><p>설치되어 있는 패키지들을 최신 버전으로 업데이트</p>
<pre><code class="language-shell">sudo apt-get update</code></pre>
</li>
<li><p>nginx 설치</p>
<pre><code class="language-shell">sudo apt-get install nginx</code></pre>
</li>
<li><p>해당 경로로 들어가 editing</p>
</li>
</ol>
<pre><code class="language-shell">vi /etc/nginx/sites-available/default</code></pre>
<ul>
<li><code>root /var/www/html;</code> 을 <code>root /workspace/컨테이너이름/web;</code> 으로 변경 (<code>:41 + enter</code> =&gt; 변경할 텍스트 위치로 이동)</li>
</ul>
<ol start="6">
<li>웹 서버 시작하기<pre><code class="language-shell">sudo service nginx start</code></pre>
</li>
<li>웹 서버 확인
프로젝트 -&gt; 실행 url과 포트를 들어가서 확인
<img src="https://images.velog.io/images/sjkim_jinnyk/post/6e88bd8a-20ed-4248-81ad-46b5438a7b5e/%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-11-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%202.19.13.png" alt=""></li>
<li>웹 서버 닫기<pre><code class="language-shell">sudo service nginx stop</code></pre>
</li>
</ol>
<br>

<h1 id="회고">회고</h1>
<p>터미널 명령어는 해도해도 까먹는다. 키보드로만 하는 연습을 해야 나중에 깃도 능숙하게 다룰 수 있을 것 같다. 깃 CLI도 맨날 까먹는...다..ㅎ 더 연습하고 자주 써봐겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.22 - TIL [Ngrok]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.22-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.22-TIL</guid>
            <pubDate>Mon, 22 Nov 2021 12:51:10 GMT</pubDate>
            <description><![CDATA[<h1 id="ngrok-사용하기">Ngrok 사용하기</h1>
<blockquote>
<p><a href="https://ngrok.com/">Ngrok 홈페이지</a></p>
</blockquote>
<h2 id="ngrok란">Ngrok란?</h2>
<p>외부(Public)에서 로컬에 접속할 수 있게 도와주는 터널링 프로그램이다. 
도메인을 등록한 척 해주는 프로그램!이라고 이해했다. </p>
<h2 id="mac에서-ngrok-실행하기">Mac에서 Ngrok 실행하기</h2>
<h3 id="1-norok에서-맥용-다운받기">1. norok에서 맥용 다운받기</h3>
<p><img src="https://images.velog.io/images/sjkim_jinnyk/post/43ae11bb-c1d2-4ad2-a2fc-ee381d4f1029/%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-11-22%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.24.29.png" alt=""></p>
<h3 id="2-다운받은-알집을-풀어서-사용자-폴더에-넣기">2. 다운받은 알집을 풀어서 사용자 폴더에 넣기</h3>
<p>맥은 보안상? 바로 실행이 안된다. 터미널을 이용해서 실행해야한다. </p>
<h3 id="3-터미널을-열어-다음-명령어를-입력">3. 터미널을 열어 다음 명령어를 입력</h3>
<p>우선 ngrok에 회원가입 후 <a href="https://dashboard.ngrok.com/get-started/your-authtoken">자신의 고유 토큰</a>을 부여받는다. </p>
<pre><code>./ngrok authtoken 자신 고유의 토큰 입력
./ngrok http 8080</code></pre><p><img src="https://images.velog.io/images/sjkim_jinnyk/post/674c4a5e-c522-4565-bdd7-991f6aac5dab/%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-11-22%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.30.52.png" alt=""></p>
<h3 id="4-forwarding에-있는-주소로-접속">4. Forwarding에 있는 주소로 접속</h3>
<p><a href="https://9b07-119~~.ngrk.io">https://9b07-119~~.ngrk.io</a> 라고 되어 있는 부분이 로컬에 접속할 수 있는 주소! 
8시간 유지된다. 이 후에는 다시 주소를 부여받으면 된다. 
저 주소를 입력하고 들어가면 외부에서도 나의 로컬주소에 접속이 가능하다. </p>
<h2 id="ngrok를-언제-사용하나">Ngrok를 언제 사용하나?</h2>
<p>사이트를 만들 때 실제 배포 전에 데모를 실행하는 용도로 사용!</p>
<br>

<h1 id="회고">회고</h1>
<p>프로젝트를 통해 알게되는 새로운 개념들이 많다.
팀원분이 이런거 공부하면 좋아요~하는 것들을 많이 알려주셔서 도움이 많이 된다. 경력있는 분이라 확실히 전문성이 높은게 느껴진다..얼른 취업하고 싶어진다ㅠㅠ</p>
<p>오늘은 멋사 스프린트 회고날! 
지난 번에 참여를 못했는데 많은 사람들이 빠지지 않고 참여하는 분위기였다. 잠깐이나마 같이 공부하는 사람들과 대화를 할 수 있어서 좋았다ㅎㅎ
첫 날의 계획이 얼마나 거창했는지 돌아볼 수 있었고, 지킬 수 있는 계획을 짜야겠다고 다짐했다 하하..
일단 이번 주 목표는 아침 or 저녁에 1시간 달리기 다시 시작하기! 추워도 4일 이상 나가기를 목표로!! 디스크가 도지기 전에 열심히 운동해야겠다..!
또 다른 하나의 목표는 코드 리뷰 받은 것 정리하기! 리뷰 받은 것을 토대로 리팩토링 하기! 두 목표는 꼭 지키리리ㅏ..화이팅팅</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.21 - TIL [Vue - clipboard]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.21-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.21-TIL</guid>
            <pubDate>Sun, 21 Nov 2021 14:38:43 GMT</pubDate>
            <description><![CDATA[<h1 id="클립보드에-현재-주소-복사">클립보드에 현재 주소 복사</h1>
<h2 id="라이브러리-vue-clipboard2-이용">라이브러리 vue-clipboard2 이용</h2>
<blockquote>
<p><a href="https://www.npmjs.com/package/vue-clipboard2">vue-clipboard2 가이드</a></p>
</blockquote>
<h3 id="1-vue-clipboard-설치">1. vue-clipboard 설치</h3>
<p>터미널에 아래와 같이 입력한 후 package.json에 설치되는 것을 확인한다.</p>
<pre><code>npm install --save vue-clipboard2</code></pre><h3 id="2-사용하기-위해-vue에-올린다">2. 사용하기 위해 Vue에 올린다.</h3>
<p>main.js에 vue-clipboard2를 통해 import 시켜준다.
import 해온 것을 Vue.use에 등록해주면 vue에서 사용 가능!
index.html에 스크립트 <code>vue.min.js</code>를 추가해준다.</p>
<pre><code class="language-js">import Vue from &#39;vue&#39;
import VueClipboard from &#39;vue-clipboard2&#39;

VueClipboard.config.autoSetContainer = true;
Vue.use(VueClipboard)</code></pre>
<pre><code class="language-html">&lt;script src=&quot;vue.min.js&quot;&gt;&lt;/script&gt;</code></pre>
<h3 id="3-함수-구현">3. 함수 구현</h3>
<p>버튼을 클릭했을 때 현재 주소가 복사되게 함수 구현
<code>window.location.href</code>를 통해 현재 주소를 homeLink 변수에 저장하여 사용</p>
<pre><code class="language-js">&lt;template&gt;
  &lt;div id=&quot;app&quot;&gt;
    &lt;button type=&quot;button&quot; @click=&quot;urlLink&quot;&gt;Copy!&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default { 
 data() {
    return {
      homeLink: window.location.href,
    };
 },
 methods: {
    urlLink() {
      this.$copyText(this.homeLink).then(function () {
        alert(&quot;복사되었습니다.&quot;);
      });
    },
 }, 
}
&lt;/script&gt;</code></pre>
<p><img src="https://images.velog.io/images/sjkim_jinnyk/post/8e0e0415-174f-4ff1-8e59-ec8bad661a49/%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-11-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.27.09.png" alt=""></p>
<br>

<h1 id="회고">회고</h1>
<p>진행 중인 프로젝트에서 사용해 본 기능이다. 
라이브러리를 이용하니깐 간단한 코드로도 클립보드 기능을 구현할 수 있어서 편했다. 예전에는 <code>document.execCommand</code>을 이용해 구현했지만 더이상 권장하지 않는 기능이라고 한다. 다음에는  <a href="https://clipboardjs.com/">clipboard.js</a>를 이용해서 구현해 봐야겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.19 - TIL [CSS]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.19-TIL-ulk7nacl</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.19-TIL-ulk7nacl</guid>
            <pubDate>Fri, 19 Nov 2021 10:42:27 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘의-css">오늘의 CSS</h1>
<h2 id="자식-요소를-가운데-정렬-시키는-법-2가지">자식 요소를 가운데 정렬 시키는 법 2가지</h2>
<pre><code class="language-html">&lt;div class=&quot;parent&quot;&gt;
  &lt;div class=&quot;child&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre>
<ol>
<li><code>display:flex</code> 이용</li>
</ol>
<p>부모 요소에 display: flex를 주고, justify-content와 align-items를 center를 주면 자식 요소가 가운데로 정렬된다. </p>
<pre><code class="language-css">.parent{
  position:relative;
  display:flex;
  justify-content:center;
  align-items:center;
  width:200px;
  height:300px;
  background: #000;
}

.child{
  width:50px;
  height:50px;
  background: pink;
}</code></pre>
<ol start="2">
<li><code>position</code> 이용</li>
</ol>
<p>자식 요소에 position:absolute를 주어 부모 요소를 기준으로 top,left를 50%를 준다. 이 때 가운데로 가는 것은 자식 요소의 꼭지점에 해당하는 부분이기 때문에 완전히 가운데로 가게 하려면 translate을 이용해 x축,y축으로 자식의 크기의 반만큼 움직여야 자식 요소가 완전히 가운데로 오게 된다. </p>
<pre><code class="language-css">.parent{
  position:relative;
  width:200px;
  height:300px;
  background: #000;
}

.child{
  width:50px;
  height:50px;
  position:absolute;
  top:50%;
  left:50%;  
  transform:translate(-50%, -50%);
  background: pink;
}</code></pre>
<p>  <img src="https://images.velog.io/images/sjkim_jinnyk/post/f261e599-85be-425f-9197-03aca6de32ce/%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-11-19%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.11.56.png" width="40%" alt="꼭지점이 가운데" align="left"> <img src="https://images.velog.io/images/sjkim_jinnyk/post/0d22b55b-fe6f-4952-8018-324e26691ca6/%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-11-19%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.04.00.png" width="40%" align="right"></p>
<hr>
<h2 id="웹-접근성-포커스-처리">웹 접근성 포커스 처리</h2>
<p>버튼이나 링크 태그 안에 들어간 이미지 태그의 위치를 잡을 때 이미지 태그에 하지 않고 버튼이나 링크 태그에 스타일을 줘서 포커스 놓치지 말기!
<code>:focus</code>를 이용해 포커스가 없는 곳은 포커스 주기</p>
<br>

<h1 id="회고">회고</h1>
<p>  웹 접근성을 고려하려면 마크업과 css가 생각보다 오래 걸리고 할게 많다.
  어제 클론 코딩한 코드 리뷰를 받았는데 웹 접근성을 고려하지 않은 부분도 있어서 아직 확실히 고쳐야할게 너무너무너무 많다. 주말동안 리뷰를 토대로 리팩토링 해서 다시 올려야겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.18 - TIL [클론코딩]]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.18-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.18-TIL</guid>
            <pubDate>Thu, 18 Nov 2021 10:20:07 GMT</pubDate>
            <description><![CDATA[<h1 id="클론-코딩-과제">클론 코딩 과제</h1>
<blockquote>
<p><a href="https://cola-clone.netlify.app/">자판기 클론 코딩</a></p>
</blockquote>
<p><img src="https://images.velog.io/images/sjkim_jinnyk/post/6681d7ac-24d2-43cf-86c6-0e1692b1c189/%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-11-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.10.15.png" alt=""></p>
<h2 id="새로-배운-부분">새로 배운 부분</h2>
<ol>
<li>스크린 리더가 읽을 수 있게 html에 파트마다 설명을 붙이고, css로 숨겨준다. </li>
</ol>
<blockquote>
<p>헤딩 태그로 각 파트마다 어떤 화면인지 설명을 붙인다. </p>
</blockquote>
<pre><code class="language-html">&lt;h1 class=&quot;tit-app ir&quot;&gt;cola cola&lt;/h1&gt;
&lt;h2 class=&quot;ir&quot;&gt;자판기 화면&lt;/h2&gt;
&lt;h2 class=&quot;ir&quot;&gt;나의 정보 화면&lt;/h2&gt;</code></pre>
<pre><code class="language-css">.ir {
    display: block;
    overflow: hidden;
    position: absolute;
    text-indent: -9999px;
    font-size: 1px;
    line-height: 0;
    color: transparent;
}</code></pre>
<br>

<ol start="2">
<li>몇 번째 자식부터 ~ li가 끝날 때 까지 선택하는 코드</li>
</ol>
<blockquote>
<p>3번째 자식부터 5번째 자식에게 margin을 줄 때 사용</p>
</blockquote>
<pre><code class="language-html">&lt;ul&gt;
  &lt;li&gt;1번째&lt;/li&gt;
  &lt;li&gt;2번째&lt;/li&gt;
  &lt;li&gt;3번째&lt;/li&gt;
  &lt;li&gt;4번째&lt;/li&gt;
  &lt;li&gt;5번째&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<pre><code class="language-css">.vending-machine .list-item li:nth-child(3)~li {
    margin-top: 12px;
}</code></pre>
<br>


<h1 id="오징어게임-프로젝트">오징어게임 프로젝트</h1>
<hr>
<p>결과 페이지를 모달 창으로 하려다가 재사용성을 고려해서 그냥 라우터로 연결했다. 
오늘은 결과 페이지들 html, css 수정하고 라우터 연결해줬다.</p>
<br>

<h1 id="회고">회고</h1>
<hr>
<p>아직도 시맨틱 태그 다는게 어렵지만 경험이 쌓이면 금방 늘 수 있을 것이라 생각한다. 
오늘은 한 페이지 만드는데 4시간이나 걸렸다..
익숙하게 사용할 때까지 열심히 연습해야쥐
오징어게임 프로젝트도 거의 다 끝나간다. 완벽하게 끝낼 수 있게 노력하쟈 아자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[21.11.17 - TIL]]></title>
            <link>https://velog.io/@sjkim_jinnyk/21.11.17-TIL</link>
            <guid>https://velog.io/@sjkim_jinnyk/21.11.17-TIL</guid>
            <pubDate>Wed, 17 Nov 2021 14:42:33 GMT</pubDate>
            <description><![CDATA[<h1 id="til">TIL</h1>
<blockquote>
<p><a href="https://www.addthis.com/">AddThis</a></p>
</blockquote>
<ol>
<li>웹이나 앱을 만들 때 공유 기능을 편리하게 만들어주는 사이트
<img src="https://images.velog.io/images/sjkim_jinnyk/post/6908958c-1ef2-4404-9acc-5d0a2bc73f27/%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-11-17%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.25.47.png" alt=""></li>
</ol>
<p>사진처럼 공유 버튼도 만들어주고 기능도 만들어준다. 
스크립트를 추가하고, html 태그를 추가해주면 공유 버튼이 완성된다. </p>
<pre><code class="language-html">&lt;!-- Go to www.addthis.com/dashboard to customize your tools --&gt; 
&lt;script type=&quot;text/javascript&quot; src=&quot;//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-6194aec8c8e5e3da&quot;&gt;&lt;/script&gt;
</code></pre>
<pre><code class="language-html">&lt;!-- Go to www.addthis.com/dashboard to customize your tools --&gt; 
&lt;div class=&quot;addthis_inline_share_toolbox_asz1&quot;&gt;&lt;/div&gt;</code></pre>
<hr>
<blockquote>
<p><a href="https://www.gabia.com/">가비아</a></p>
</blockquote>
<ol start="2">
<li>도메인을 저렴하게 살 수 있는 사이트
<img src="https://images.velog.io/images/sjkim_jinnyk/post/25e17de7-8acf-403f-8dcd-31fcfd1f79fe/%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-11-17%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.32.41.png" alt=""></li>
</ol>
<p>특정 도메인을 1년에 500원이라는 가격에 살 수 있다. </p>
<h1 id="회고">회고</h1>
<p>오늘은 쉬어가는 시간으로 유튜버 조코딩님의 특강을 들었다. 
어제 vue로 sns 공유 기능을 만들었는데 이걸 더 쉽게 만들어주는 사이트를 알게 됐다..!
물론 직접 코딩하는 것도 어렵진 않지만 만들어진 걸 사용해도 나쁘지 않을 것 같다. </p>
]]></description>
        </item>
    </channel>
</rss>