<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hyunwlee-dev.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Fri, 01 Mar 2024 18:11:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. hyunwlee-dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyunwlee-dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[React-Beautiful-dnd와 Next.js에서의 트러블슈팅]]></title>
            <link>https://velog.io/@hyunwlee-dev/React-Beautiful-DnD%EC%99%80-Next.js%EC%97%90%EC%84%9C%EC%9D%98-%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85</link>
            <guid>https://velog.io/@hyunwlee-dev/React-Beautiful-DnD%EC%99%80-Next.js%EC%97%90%EC%84%9C%EC%9D%98-%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85</guid>
            <pubDate>Fri, 01 Mar 2024 18:11:59 GMT</pubDate>
            <description><![CDATA[<h2 id="issue-1-ssr과-react-beautiful-dnd의-호환성">issue 1: SSR과 react-beautiful-dnd의 호환성</h2>
<p>Next.js의 서버 사이드 렌더링(SSR)과 react-beautiful-dnd(@hello-pangea/dnd)의 호환성 문제로 초기 렌더링 시에 <code>data-rbd-draggable-context-id did not match.</code>경고가 발생했다.</p>
<ul>
<li>solution</li>
</ul>
<pre><code class="language-jsx">import dynamic from &#39;next/dynamic&#39;;
const Droppable = dynamic(
  () =&gt; import(&#39;@hello-pangea/dnd&#39;).then(mod =&gt; mod.Droppable),
  { ssr: false }
);

const Draggable = dynamic(
  () =&gt; import(&#39;@hello-pangea/dnd&#39;).then(mod =&gt; mod.Draggable),
  { ssr: false }
);</code></pre>
<p><code>next/dynamic</code>을 사용하여 Droppable과 Draggable 컴포넌트를 동적으로 임포트하고, { ssr: false } 옵션을 통해 이들이 클라이언트 사이드에서만 로드되도록 설정했다. 이 방법으로 서버와 클라이언트 사이의 불일치 문제를 해결하였다.  </p>
<ul>
<li>동적로딩을 하면 클라이언트 사이드에서만 로드되는 이유</li>
</ul>
<p>Next.js 같은 서버 사이드 렌더링을 지원하는 프레임워크에서 dynamic 함수를 사용하여 컴포넌트를 동적으로 로드하는 경우, 이 로드 과정은 브라우저가 페이지를 불러온 후, 클라이언트에서 발생한다.  </p>
<ul>
<li><code>getServerSideProps</code> 를 적용하지 않았는데도 서버 사이드 렌더링을 하는 이유  </li>
</ul>
<p>Next.js는 페이지를 방문하는 첫번째 요청에 대해 자동으로 서버에서 페이지를 렌더링한다.  </p>
<hr>
<h2 id="issue-2-input-요소가-포함된-컴포넌트에서-drag--drop이-잘-작동하지-않는-상황">issue 2: input 요소가 포함된 컴포넌트에서 drag &amp; drop이 잘 작동하지 않는 상황</h2>
<p>사용자가 li 태그의 전체 영역이 아니라, 일정부분에서만 드래그를 할 수 있었다. input 요소가 drag &amp; drop 동작을 방해한 것으로 판단했다.</p>
<ul>
<li>solution</li>
</ul>
<p>todo-list안의 todo-item은 props로 disabled 속성을 전달했었고, 이들은 input 요소로서 쓰일 필요가 없기 때문에 span 태그로 대체하였다.</p>
<pre><code class="language-jsx">export default function TodoItem({
  checked,
  handleCheckboxChecked,
  className,
  children,
  ...props
}: IProps) {
  return (
    &lt;div
      className={clsx(styles.item, className)}
    &gt;
      &lt;CheckboxButton
        className={styles[&#39;checkbox-button&#39;]}
        checked={checked}
        onChange={handleCheckboxChecked}
      /&gt;
      {
        props.disabled ?
          &lt;span
            className={clsx(
              {
                [styles.checked]: checked,
                [styles.disabled]: props.disabled
              }, styles.input)}
          &gt;
            {props.value}
          &lt;/span&gt;
          :
          &lt;input
            className={clsx(
              {
                [styles.checked]: checked,
                [styles.disabled]: props.disabled
              }, styles.input)}
            {...props}
          /&gt;
      }
      {children}
    &lt;/div&gt;
  );
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[FLUX 아키텍처]]></title>
            <link>https://velog.io/@hyunwlee-dev/FLUX-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98</link>
            <guid>https://velog.io/@hyunwlee-dev/FLUX-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98</guid>
            <pubDate>Fri, 23 Feb 2024 12:20:51 GMT</pubDate>
            <description><![CDATA[<h1 id="flux-아키텍처란-무엇인가요">FLUX 아키텍처란 무엇인가요?</h1>
<p>사용자의 행위 <code>action</code>은 <code>dispatcher</code>에 의해 통제됩니다. <code>dispatcher</code>가 <code>store</code>를 업데이트하고 변경된 <code>store</code>에 대한 <code>view</code>를 리렌더링합니다. <code>view</code>에서는 <code>store</code>에 직접 접근하지 않으며, <code>dispatcher</code>로 다시 액션을 보내고 <code>store</code>를 업데이트한 뒤, 다시 <code>view</code>를 리렌더링하는 단방향적 구조를 가집니다.  </p>
<p><code>FLUX</code> 패턴은 이러한 단방향적인 데이터 흐름 구조를 통해 어떤 액션이 디스패처에 의해 어떤 결과를 낳고 변화되는지 명확히 파악하고 알아볼 수 있습니다.</p>
<hr>
<h2 id="overview">Overview</h2>
<p>페이스북은 왜 Flux 패턴이 필요했는지 가장 잘 알려져 있는 것은 알림(notification) 버그이다.  </p>
<p><img src="https://bestalign.github.io/static/79ef489156c8d6979a03014b20ed1d6f/0a47e/01.png" alt=""></p>
<p>로그인 했을 때 화면 위의 메시지 아이콘에 알림이 떠 있지만, 그 메시지 클릭해서 들어가 보면 아무 메시지가 없던 적이 있었다. 이 버그를 고치고 얼마 동안은 괜찮았지만 곧 다시 나타났다.   </p>
<p>그래서 Facebook은 시스템을 더욱 예측 가능하게 만들어서 문제점을 없애길 원했다.   </p>
<h3 id="mvc-패턴의-근본적인-문제점">MVC 패턴의 근본적인 문제점</h3>
<p><img src="https://velog.velcdn.com/images/andy0011/post/4a1f159f-6972-4028-8a18-9a383cf5e44d/image.png" alt=""></p>
<p>근본적인 문제점은 데이터가 애플리케이션을 흐르는 방법에 있었다.  </p>
<p>MVC는 Model, View, Controller의 약자로, 데이터를 저장하고 관리하는 Model, 사용자에게 보여지는 View, 그리고 이 둘을 중개하는 Controller로 구성된다. 사용자가 View를 통해 데이터를 입력하면 이는 Controller를 통해 Model을 업데이트하고, Model의 변경은 View에 반영된다. 하지만 애플리케이션이 커지고 복잡해지면, 이러한 양방향 데이터 흐름이 예측하기 어려워진다.  </p>
<h3 id="단방향-데이터-흐름">단방향 데이터 흐름</h3>
<p>그래서 Facebook은 다른 종류의 아키텍처를 시도하기로 결정했다. 
flux 아키텍처의 데이터는 단방향으로만 흐르고, 새로운 데이터를 넣으면 처음부터 흐름이 다시 시작된다. 이러한 단방향적인 데이터 흐름 구조를 통해 어떤 액션이 dispatcher에 의해 어떤 결과를 낳고 변화되는지 명확히 파악하고 알아볼 수 있게 되었다.</p>
<p><img src="https://haruair.github.io/flux/img/flux-simple-f8-diagram-with-client-action-1300w.png" alt="flux-diagram"></p>
<hr>
<h3 id="action">Action</h3>
<ul>
<li>데이터를 변경하는 행위로서 Dispatcher에게 전달되는 객체를 말한다.</li>
</ul>
<h3 id="action-creator">Action Creator</h3>
<ul>
<li>모든 변경사항과 사용자와의 상호작용이 거쳐가야 하는 action의 생성을 담당하고 있다. 언제든 애플리케이션의 상태를 변경하거나 view를 업데이트하고 싶다면 action을 생성해야만 한다.</li>
<li>action creater는 새로 발생한 action 타입(type)과 새로운 데이터(payload)를 묶어 dispatcher에게 전달한다.</li>
</ul>
<pre><code class="language-json">{
  type: &#39;ADD_TODO&#39;,
  text: &#39;블로그 쓰기&#39;
}</code></pre>
<h3 id="dispatcher">Dispatcher</h3>
<ul>
<li><p>모든 데이터는 중앙 허브인 dispatcher를 통해 흐른다.</p>
</li>
<li><p>기본적으로 콜백(callback)이 등록되어 있는 곳이다. action을 보낼 필요가 있는 모든 store를 가지고 있고 action creator로부터 action이 넘어오면 여러 store에 action을 보낸다.</p>
</li>
<li><p>동기적으로 처리 되기 때문에 하나를 다른 것보다 먼저 업데이트해야 한다면, waitFor()을 사용하여 dispatcher가 적절히 처리하도록 할 수 있다. 또한 action type과 관계없이 등록된 모든 store로 action을 보내기 때문에 store가 특정 action만 구독하지 않고 모든 action을 받고 처리를 결정할 수 있다.</p>
</li>
</ul>
<h3 id="store">Store</h3>
<ul>
<li>애플리케이션 내의 모든 상태와 그와 관련된 로직을 가지고 있다.</li>
<li>모든 상태 변경은 반드시 store에 의해서 결정되어야한다. store에 직접 상태변경 요청을 전달할 수 없다. 무조건 action creator/dispatcher 파이프라인을 거쳐서 액션을 보내야만 한다. Dispatcher로부터 전달받은 Action에 따라 데이터를 업데이트한다.</li>
<li>store의 내부에서는 보통 switch statement를 사용해서 받은 모든 액션 중 처리할 액션과 무시할 액션을 결정하고 상태를 변경하게 된다.</li>
<li>상태 변경 완료 후 컨트롤러 뷰에 상태가 변경했다는 것을 알려준다.</li>
</ul>
<h3 id="view">View</h3>
<ul>
<li>리액트 컴포넌트로 생각하면 된다.</li>
</ul>
<h3 id="controller-view">Controller View</h3>
<ul>
<li>store와 view 사이의 중간관리자같은 역할을 한다.</li>
<li>상태가 변경되었을 때 store가 그 사실을 controller-view에게 알려주면, controller-view는 자신의 아래에 있는 모든 view에게 새로운 상태를 넘겨준다.</li>
</ul>
<hr>
<blockquote>
<p>ref</p>
<ul>
<li><a href="https://github.com/junh0328/prepare_frontend_interview/blob/main/react.md#flux%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%95%84%EB%82%98%EC%9A%94">https://github.com/junh0328/prepare_frontend_interview/blob/main/react.md#flux%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%95%84%EB%82%98%EC%9A%94</a></li>
<li><a href="https://bestalign.github.io/translation/cartoon-guide-to-flux/">https://bestalign.github.io/translation/cartoon-guide-to-flux/</a></li>
<li><a href="https://haruair.github.io/flux/docs/overview.html">https://haruair.github.io/flux/docs/overview.html</a></li>
</ul>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Tree shaking이란?]]></title>
            <link>https://velog.io/@hyunwlee-dev/Tree-shaking%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94</link>
            <guid>https://velog.io/@hyunwlee-dev/Tree-shaking%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94</guid>
            <pubDate>Fri, 16 Feb 2024 14:01:14 GMT</pubDate>
            <description><![CDATA[<h1 id="tree-shaking이란-무엇인가요">Tree shaking이란 무엇인가요?</h1>
<ul>
<li><p>실제로 사용되지 않는 코드를 제거하는 기법입니다.</p>
</li>
<li><p>최종 번들의 크기를 줄이고, 애플리케이션의 로딩 속도와 성능을 향상시켜줍니다.</p>
</li>
<li><p>ES2015 모듈 구문은 <a href="http://exploringjs.com/es6/ch_modules.html#static-module-structure">정적 구조</a>에 의존합니다.</p>
</li>
<li><p>이름과 개념은 ES2015 모듈 번들러의 <a href="https://github.com/rollup/rollup">rollup</a>에 의해 대중화되었습니다.</p>
</li>
</ul>
<h1 id="tree-shaking의-필요한-이유는-무엇입니까">Tree shaking의 필요한 이유는 무엇입니까?</h1>
<ul>
<li><p>어떤 응용 프로그램에서도 코드 크기를 상당히 줄일 수 있습니다.</p>
</li>
<li><p>즉, 보낼 코드가 적을수록 애플리케이션이 더 성능적으로 우수해집니다.</p>
</li>
<li><p><code>Tree shaking</code>은 주로 Rollup과 Webpack 번들러에서 구현되어 있습니다.</p>
</li>
</ul>
<h2 id="tree-shaking은-어떻게-동작하나요">Tree shaking은 어떻게 동작하나요?</h2>
<ul>
<li><p>모듈 번들러가 애플리케이션의 모든 모듈을 분석하고, 사용되지 않는 코드를 식별하여 제거하는 과정입니다.</p>
</li>
<li><p>이 과정에서 모듈 간의 종속성을 분석하여 사용되지 않는 코드 경로를 찾고, 이를 제거하여 최종 번들의 크기를 줄입니다.</p>
</li>
</ul>
<h2 id="tree-shaking을-위해-어떤-종류의-코드가-효과적으로-최적화될-수-있나요">Tree shaking을 위해 어떤 종류의 코드가 효과적으로 최적화될 수 있나요?</h2>
<ul>
<li><p>주로 함수, 클래스, 변수 등의 정적 코드를 최적화합니다.</p>
</li>
<li><p>특히, 사용되지 않는 함수, 클래스, 변수 등이 포함된 모듈은 효과적으로 제거될 수 있으며, 이는 최종 번들의 크기를 크게 줄일 수 있습니다.</p>
</li>
</ul>
<h2 id="tree-shaking을-실패할-수-있는-상황은-무엇인가요">Tree shaking을 실패할 수 있는 상황은 무엇인가요?</h2>
<ul>
<li><p>주로 정적 코드에 적용되므로 동적으로 생성되는 코드나 eval() 함수를 사용하는 코드에는 적용되지 않습니다. </p>
</li>
<li><p><code>Tree shaking</code>을 위해 사용되는 모듈 시스템이 정확하게 지원되지 않는 경우에도 효과적으로 동작하지 않을 수 있습니다.</p>
</li>
</ul>
<h2 id="최적화-부분에서-tree-shaking과-code-spliting-차이">최적화 부분에서 Tree shaking과 Code spliting 차이</h2>
<p><code>요약</code>: Tree shaking과 Code splitting은 모두 웹 애플리케이션의 성능을 향상시키기 위한 최적화 기법입니다만, 그 방향성과 작동 원리에서 차이가 있습니다. Tree shaking은 번들 크기를 줄이는 데 중점을 두고 있으며, 사용되지 않는 코드를 제거하는 데 초점을 맞춥니다. 반면에 Code splitting은 애플리케이션을 더 작은 조각으로 나누어 초기 로딩 시간을 최적화하는 데 중점을 두고 있습니다.</p>
<p><code>Tree shaking</code>은 번들에 포함된 코드 중에서 사용되지 않는 코드를 제거하여 번들 크기를 줄이는 기술입니다. 일반적으로 JavaScript 프로젝트에서 사용되며, 모듈 시스템(예: ES6의 import/export)을 통해 코드를 구성할 때 효과적으로 적용됩니다. 예를 들어, 애플리케이션에서 특정 함수나 변수를 사용하지 않을 경우, Tree shaking은 해당 코드를 식별하고 제거하여 번들 크기를 최소화합니다. 이는 사용자가 앱을 더 빨리 다운로드하고 실행할 수 있도록 도와줍니다.</p>
<p><code>Code splitting</code>은 애플리케이션을 여러 개의 작은 번들로 분할하는 기술입니다. 이를 통해 초기 페이지 로드 시 필요한 최소한의 코드만 다운로드하여 애플리케이션의 초기 로딩 시간을 최소화할 수 있습니다. 예를 들어, 사용자가 특정 기능이나 라우트에 접근할 때 해당 부분에 필요한 코드만 다운로드하여 불필요한 코드를 제거하고 성능을 향상시킵니다. 이는 대규모 애플리케이션의 경우 특히 유용하며, 사용자 경험을 향상시키는 데 중요한 역할을 합니다.</p>
<h2 id="rollup-webpack-차이점">rollup, webpack 차이점</h2>
<p><code>요약</code>: Rollup과 Webpack은 모두 JavaScript 애플리케이션의 번들링 도구로 널리 사용되지만, 목표와 사용 사례에서 약간의 차이가 있습니다. Rollup은 주로 라이브러리나 패키지를 개발할 때 사용되며, Tree shaking과 간단한 설정이 주요 장점입니다. 반면에 Webpack은 웹 애플리케이션의 번들링 및 빌드에 사용되며, 다양한 기능과 유연성을 제공하여 복잡한 애플리케이션을 구성하는 데 적합합니다.</p>
<p><code>Rollup</code>: Rollup은 ES6 모듈 번들링을 위한 주로 JavaScript 라이브러리나 패키지를 빌드할 때 사용됩니다. Rollup은 간단하고 빠르며, Tree shaking을 효과적으로 지원하여 번들 크기를 최소화할 수 있습니다. 주로 라이브러리나 패키지를 개발할 때 사용되며, 불필요한 코드를 제거하여 최적화된 결과물을 생성합니다.</p>
<p><code>Webpack</code>: Webpack은 Rollup과 비슷하게 JavaScript 애플리케이션의 번들링을 수행하지만, 보다 다양한 기능을 제공합니다. Webpack은 모듈 번들링 뿐만 아니라 다양한 리소스(이미지, CSS 등)도 번들링할 수 있으며, 로더(loader)를 통해 다양한 전처리 작업을 수행할 수 있습니다. 또한 Code splitting, Hot Module Replacement(HMR) 등의 기능을 포함하여 더 많은 유연성과 확장성을 제공합니다. 주로 웹 애플리케이션의 번들링 및 빌드에 사용되며, 다양한 설정 옵션을 통해 원하는 대로 커스터마이징할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[IIFE란?]]></title>
            <link>https://velog.io/@hyunwlee-dev/IIFE%EB%9E%80</link>
            <guid>https://velog.io/@hyunwlee-dev/IIFE%EB%9E%80</guid>
            <pubDate>Fri, 02 Feb 2024 12:50:56 GMT</pubDate>
            <description><![CDATA[<h1 id="면접-iife-패턴이란-무엇입니까">(면접) IIFE 패턴이란 무엇입니까?</h1>
<p>IIFE(즉시 실행 함수 표현식)이란 무엇입니까?</p>
<p>IIFE(Immediately Invoked Function Expression)는 정의되자 마자 실행되는 JavaScript 함수입니다.  </p>
<pre><code class="language-javascript">(function () {
  // login here
})();</code></pre>
<h2 id="꼬리-질문-iife-사용-예시">(꼬리 질문) IIFE 사용 예시</h2>
<h4 id="1-전역-이름공간을-오염시키는-것을-방지">1. 전역 이름공간을 오염시키는 것을 방지</h4>
<p>애플리케이션은 다양한 소스 파일의 많은 함수와 전역 변수를 포함할 수 있기 때문에, 전역 변수의 수를 제한하는 것이 중요합니다.  </p>
<p>필요 없는 초기화 코드가 있는 경우, IIFE 패턴을 사용할 수 있습니다. 코드를 다시 재사용하지 않을 것이기 때문에 이 경우 IIFE를 사용하는 것이 함수 선언 또는 함수 표현식을 사용하는 것보다 더 좋습니다.</p>
<pre><code class="language-javascript">(() =&gt; {
  // 초기화 코드
  let firstVariable;
  let secondVariable;
})();

// firstVaribale과 secondVariable은 이 함수 실행 후에 사용할 수 없습니다.</code></pre>
<h4 id="2-비동기-함수-실행">2. 비동기 함수 실행</h4>
<p><code>async</code> IIFE를 사용하면 <code>top-level await</code>이 없는 이전 브라우저 및  JavaScript 런타임에서도 <code>await</code> 및 <code>for-await</code>를 사용할 수 있습니다.  </p>
<pre><code class="language-javascript">const getFileStream = async(url) =&gt; {
  // 구현  
};

(async() =&gt; {
  const stream = await getFileStream(&quot;https//domain.name/path/file.ext&quot;);
  for await (const chunk of stream) {
    console.log({ chunk });
  }
})</code></pre>
<h4 id="3-모듈-패턴">3. 모듈 패턴</h4>
<p>IIFE를 사용하는 주된 이유는 IIFE 내에 선언된 모든 변수는 외부 세계에서 액세스 할 수 없기 때문에 데이터 프라이버시를 확보하는 것입니다. 즉, IIFE에서 변수 액세스하려고 하면 아래와 같은 오류가 발생합니다.</p>
<pre><code class="language-javascript">(function() {
  var message = &quot;IIFE&quot;;
  console.log(message);
})();
console.log(message); // Error: message is not defined</code></pre>
<h4 id="4-es6-이전의-var가-있는-for-루프">4. ES6 이전의 var가 있는 For 루프</h4>
<p>ES6 및 블록 범위에서 let and const문이 도입되기 전에 과거 코드에서 다음과 같은 IIFE 사용을 볼 수 있습니다. var문을 사용하면 함수 범위와 저역 범위만 가지게 됩니다.</p>
<h6 id="의도대로-되지-않은-코드">의도대로 되지 않은 코드</h6>
<pre><code class="language-javascript">for (var i = 0; i &lt; 2; i++) {
  const button = document.createElement(&quot;button&quot;);
  button.innerText = `Button ${i}`;
  button.onclick = function () {
    console.log(i);
  };
  document.body.appendChild(button);
}
console.log(i); // 2</code></pre>
<h6 id="iife로-문제-해결한-코드">IIFE로 문제 해결한 코드</h6>
<pre><code class="language-javascript">for (var i = 0; i &lt; 2; i++) {
  const button = document.createElement(&quot;button&quot;);
  button.innerText = `Button ${i}`;
  button.onclick = (function (copyOfI) {
    return function () {
      console.log(copyOfI);
    };
  })(i);
  document.body.appendChild(button);
}
console.log(i); // 2</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Cookie란?]]></title>
            <link>https://velog.io/@hyunwlee-dev/Cookie%EB%9E%80</link>
            <guid>https://velog.io/@hyunwlee-dev/Cookie%EB%9E%80</guid>
            <pubDate>Sat, 27 Jan 2024 07:48:40 GMT</pubDate>
            <description><![CDATA[<h1 id="면접-쿠키란-무엇입니까">(면접) 쿠키란 무엇입니까?</h1>
<blockquote>
<p>쿠키는 웹사이트를 방문할 때 생성되는 정보를 담은 작은 파일로, 클라이언트의 로컬에 저장됩니다. 쿠키는 사용자가 웹사이트를 방문할 때마다 서버로 전송되어 사용자를 식별하는데 사용됩니다.</p>
</blockquote>
<ul>
<li>예를 들어 아래와 같이 username이라는 쿠키를 만들 수 있습니다.</li>
</ul>
<pre><code class="language-javascript">document.cookie = &quot;username=John&quot;;</code></pre>
<p><img src="https://github.com/sudheerj/javascript-interview-questions/raw/master/images/cookie.png" alt="cookie image by sudheer"></p>
<p>​    </p>
<h2 id="꼬리-질문-쿠키의-사용-목적은-무엇인가요">(꼬리 질문) 쿠키의 사용 목적은 무엇인가요?</h2>
<ul>
<li>사용자를 식별하기 위해 사용됩니다.</li>
<li>사용자의 선호 설정을 저장하기 위해 사용됩니다.</li>
<li>장바구니에 상품을 담거나, 로그인 정보를 저장하기 위해 사용됩니다.</li>
</ul>
<p>​    </p>
<h2 id="꼬리-질문-쿠키의-단점은-무엇인가요">(꼬리 질문) 쿠키의 단점은 무엇인가요?</h2>
<ul>
<li>쿠키는 사용자의 로컬에 저장되기 때문에 보안에 취약합니다.</li>
<li>쿠키는 사용자의 로컬에 저장되기 때문에 사용자의 로컬에 저장된 쿠키를 삭제하지 않는 한 계속해서 서버로 전송됩니다.</li>
<li>쿠키는 사용자의 로컬에 저장되기 때문에 저장할 수 있는 데이터의 크기가 제한적입니다.</li>
</ul>
<h2 id="꼬리-질문-쿠키의-구조는-어떻게-되나요">(꼬리 질문) 쿠키의 구조는 어떻게 되나요?</h2>
<ul>
<li>쿠키는 이름, 값, 만료 날짜, 경로, 도메인, 보안 여부 등의 정보를 담고 있습니다.</li>
<li>쿠키는 <code>name=value; expires=날짜; path=경로; domain=도메인; secure</code>와 같은 형식으로 구성되어 있습니다.</li>
<li>쿠키는 <code>document.cookie</code>를 통해 생성하거나 읽을 수 있습니다.</li>
<li>쿠키는 <code>Set-Cookie</code> 헤더를 통해 생성하거나 읽을 수 있습니다.</li>
</ul>
<h2 id="꼬리-질문-쿠키의-보안을-위한-방법은-무엇인가요">(꼬리 질문) 쿠키의 보안을 위한 방법은 무엇인가요?</h2>
<ul>
<li>쿠키에 중요한 정보를 담지 않는 것이 좋습니다.</li>
<li>쿠키에 보안을 위한 옵션을 설정하는 것이 좋습니다. (secure, httpOnly, SameSite)</li>
<li>쿠키의 만료 날짜를 설정하여 보안을 강화하는 것이 좋습니다.</li>
<li>쿠키를 사용할 때는 HTTPS를 사용하는 것이 좋습니다.</li>
</ul>
<hr>
<h2 id="쿠키">쿠키</h2>
<p>쿠키를 사용할 때 이 두 개 헤더를 쓰게 된다.  </p>
<ul>
<li><code>Set-Cookie</code>: 서버에서 클라이언트로 쿠키 전달(응답)</li>
<li><code>Cookie</code>: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달</li>
</ul>
<h2 id="http-특징">HTTP 특징</h2>
<blockquote>
<p>http는 메시지 전송 다 되고 나면 연결 끊어버린다.  </p>
<ul>
<li>HTTP는 무상태(Stateless) 프로토콜이다.</li>
<li>클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다.</li>
<li>클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다.</li>
<li>클라이언트와 서버는 서로 상태를 유지하지 않는다.</li>
</ul>
</blockquote>
<p>​    </p>
<hr>
<h2 id="쿠키-설명">쿠키 설명</h2>
<p>서버에서 쿠키를 세팅할 때  </p>
<ul>
<li><p>예) set-cookie: <code>sessionId=abcde1234;</code> <code>expires=Sat, 26-Dec-2020 00:00:00 GMT;</code> <code>path=/;</code> <code>domain=.google.com;</code> <code>Secure</code></p>
</li>
<li><p>사용처</p>
<ul>
<li><code>사용자 로그인 세션 관리</code><ul>
<li>사실 <code>user=홍길동</code>은 보안상 취약하여 sessionId를 보내고 데이터베이스에서 user값을 매핑시킴</li>
</ul>
</li>
<li><code>광고 정보 트래킹</code><ul>
<li>이 웹브라우저 사용하는 사람이 이런 걸 자주보는 구나 =&gt; 광고 매칭할 트래킹 용도</li>
</ul>
</li>
</ul>
</li>
<li><p>쿠키 정보는 항상 서버에 전송됨</p>
<ul>
<li>네트워크 트래픽 추가 유발<ul>
<li>최소한의 정보만 사용(세션 id, 인증 토큰)</li>
</ul>
</li>
<li>서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지 (localStorage, sessionStorage) 참고</li>
</ul>
</li>
<li><p>주의!</p>
<ul>
<li>보안에 민감한 데이터는 저장하면 안됨(주민번호, 신용카드 번호 등등)</li>
</ul>
</li>
</ul>
<hr>
<h2 id="쿠키---생명-주기">쿠키 - 생명 주기</h2>
<h6 id="expires-max-age">Expires, max-age</h6>
<ul>
<li>Set-Cookie: <strong>expires</strong>=Sat, 26-Dec-2020 04:39:21 GMT<ul>
<li>만료일이 되면 쿠키 삭제</li>
</ul>
</li>
<li>Set-Cookie: <strong>max-age</strong>=3600 (3600초)<ul>
<li>0이나 음수를 지정하면 쿠키 삭제</li>
</ul>
</li>
<li>세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시 까지만 유지</li>
<li>영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지</li>
</ul>
<hr>
<h2 id="쿠키---도메인">쿠키 - 도메인</h2>
<h6 id="domain">Domain</h6>
<ul>
<li>예) domain=example.org</li>
<li>명시: 명시한 문서 기준 도메인 + 서브 도메인 포함<ul>
<li>domain=example.org를 지정해서 쿠키 생성<ul>
<li>example.org는 물론이고</li>
<li>dev.example.org도 쿠키 접근</li>
</ul>
</li>
</ul>
</li>
<li>생략: 현재 문서 기준 도메인만 적용<ul>
<li>example.org에서 쿠키를 생성하고 domain 지정을 생략<ul>
<li>example.org 에서만 쿠키 접근</li>
<li>dev.example.org는 쿠키 미접근</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="쿠키---경로">쿠키 - 경로</h2>
<h6 id="path">path</h6>
<ul>
<li>예) <code>path=/home</code></li>
<li>이 경로를 포함한 <code>하위 경로 페이지만 쿠키 접근</code></li>
<li>일반적으로 path=/ 루트로 지정<ul>
<li>예)</li>
<li>path=/home  지정</li>
<li>/home -&gt; 가능</li>
<li>/home/level1 -&gt; 가능</li>
<li>/home/level1/level2 -&gt; 가능</li>
<li>/hello -&gt; 불가능</li>
</ul>
</li>
</ul>
<hr>
<h2 id="쿠키---보안">쿠키 - 보안</h2>
<h6 id="secure-httponly-samesite">Secure, HttpOnly, SameSite</h6>
<ul>
<li><code>Secure</code><ul>
<li>쿠키는 http, https를 구분하지 않고 전송</li>
<li>Secure를 적용하면 https인 경우에만 전송</li>
</ul>
</li>
<li><code>HttpOnly</code><ul>
<li>XSS 공격 방지</li>
<li>자바스크립트에서 접근 불가(document.cookie)</li>
<li>HTTP전송에만 사용</li>
</ul>
</li>
<li><code>SameSite</code><ul>
<li>XSRF 공격 방지</li>
<li>요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[MVC? MVVM? in frontend]]></title>
            <link>https://velog.io/@hyunwlee-dev/MVC-MVP-MVVM-in-frontend</link>
            <guid>https://velog.io/@hyunwlee-dev/MVC-MVP-MVVM-in-frontend</guid>
            <pubDate>Fri, 19 Jan 2024 16:29:05 GMT</pubDate>
            <description><![CDATA[<h2 id="1-이야기에-앞서">1. 이야기에 앞서</h2>
<blockquote>
<p>경험: 과제테스트에서 지시 사항과 <strong>테스트와 객체지향 디자인 원칙에 집중해주십시오.</strong>
라는 문구가 등장했다. (UI가 필요한 프로그램이 아닌 console에서 동작하는 프로그램을 작성하도록 요구한다.)  </p>
</blockquote>
<p> 문득, 주어진 개발 환경에 따라 어떤 디자인 패턴을 사용하면 좋을지 궁금해졌다.</p>
<h3 id="어떤-디자인-패턴을">어떤 디자인 패턴을?</h3>
<p>다음 3가지의 경우, 어떤 디자인 패턴을 쓰는 것이 적합한지 알아보고자 한다.</p>
<ol>
<li>cli programming in vanila javascript 과제가 주어졌을 때</li>
<li>event driven programming in vanila javascript 과제가 주어졌을 때</li>
<li>react(component driven development, event driven programming) 과제가 주어졌을 때</li>
</ol>
<h2 id="2-디자인-패턴">2. 디자인 패턴</h2>
<blockquote>
<p>소프트웨어 개발 방법에서 사용되는 디자인 패턴은 프로그램 개발에서 자주 나타나는 과제를 해결하기 위한 방법 중 하나로, 과거의 소프트웨어 개발 과정에서 발견된 설계의 노하우를 축적하여 이름을 붙여, 이후에 재이용하기 좋은 형태로 특정의 규약을 묶어서 정리한 것이다. 알고리즘과 같이 프로그램 코드로 바로 변환될 수 있는 형태는 아니지만, 특정한 상황에서 구조적인 문제를 해결하는 방식을 설명해 준다. 
<a href="https://ko.wikipedia.org/wiki/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4_%EB%94%94%EC%9E%90%EC%9D%B8_%ED%8C%A8%ED%84%B4">위키백과 - 소프트웨어 디자인 패턴</a></p>
</blockquote>
<h2 id="3-mvc-패턴">3. MVC 패턴</h2>
<h3 id="view">View</h3>
<p>UI에서 가장 중요한 것은 역시 화면이죠.
첫번째는 우리가 제일 쉽게 이해할 수 있는 부분! 바로 이 View입니다.
웹 프론트에서는 대개 최종적으로 HTML과 CSS로 만들어지는 결과물을 의미합니다.</p>
<h3 id="model">Model</h3>
<p>소프트웨어가 멈춰있는 화면만 있으면 디자인과 다를 게 없겠죠.
화면에의 어딘가는 실제의 데이터가 반영이 되어 나타나야 합니다.
이러한 데이터를 주관하는 영역을 Model이라고 부릅니다.</p>
<p>javascript의 Object일 수도 있고,
서버의 API로 받는 데이터일수도 있고,
서버에 있는 DB일 수도 있습니다.</p>
<p>어쨌든 화면이 아닌 소프트웨어가 다뤄야할 중요한 데이터 영역입니다.</p>
<h3 id="controller">Controller</h3>
<p>UI 소프트웨어의 본질은 단순합니다. 우선 데이터를 화면에 그립니다. 그리고 우리가 어떤 동작을 취하면 데이터가 바뀝니다. 데이터가 바뀌면 다시 화면이 바뀌겠죠.</p>
<p>이렇게 Model의 데이터를 받아서 화면에 그리고, 화면으로 부터 사용자의 동작을 받아서 Model을 변경합니다. 이러한 Model과 View사이의 중간 역할을 하는 것을 Controller라고 합니다.</p>
<p>MVC가 이렇게 나눠진 이유는,</p>
<p>화면을 다루는 문제와 데이터를 다루는 문제의 성격이 달라서 분리하고 싶고
Model과 View간의 의존관계를 최소화 해서 화면의 수정이 데이터수정에 영향을 미치지 않고 데이터 수정이 화면의 수정에 영향을 미치지 않고자 함입니다.</p>
<h2 id="3-1-초창기-mvc-패턴">3-1. 초창기 MVC 패턴</h2>
<p>웹 프론트엔드라는 개념도 없던 웹 서비스 초창기 시절의 MVC는</p>
<p>데이터베이스를 Model로 취급하고
HTML과 CSS, 그리고 javascript까지 포함한 클라이언트 영역을 View로
그리고 가운데서 라우터를 통해 데이터를 처리하고 새로운 HTML을 만들어서 보여주는 백엔드 영역을 Controller라고 취급했습니다.</p>
<h2 id="3-2-jquery시절의-mvc-아키텍쳐">3-2. jQuery시절의 MVC 아키텍쳐</h2>
<p>그러다가 프론트엔드의 역할이 추가되고 특히 ajax라는 기술이 만들어지면서 이제는 HTML을 서버에서 직접 만들 필요가 없게 되었습니다.</p>
<p>이때부터는 웹 프론트엔드의 MVC의 개념이 조금씩 바뀌게 됩니다</p>
<p>ajax로 부터 받는 데이터를 Model로 취급합니다.
HTML과 CSS로 만들어지는 화면을 View로 취급합니다.
javascript가 중간에서 서버의 데이터를 받아서 화면을 바꾸고 이벤트를 처리해서 서버에 데이터를 전달하는 Controller의 역할을 수행하게 됩니다.
기존의 서버 라우터에서 하던 어떤 역할들이 이제 클라이언트의 자바스크립트가 처리하게 되었고 Database는 백엔드의 역할이며 REST API의 ajax 데이터가 Model이 됩니다.</p>
<p>이 시절 Controller의 가장 주요한 역할을 했던 게 바로 jQuery입니다. 그래서 이 개념을 이해하시고 다시 jQuery를 들여다 보면 jQuery에서 가장 핵심이 되는 기술이</p>
<blockquote>
<ul>
<li>DOM Traversal and Manipulation</li>
</ul>
</blockquote>
<ul>
<li>Event Handling</li>
<li>Ajax</li>
</ul>
<p>였다는 것을 알 수 있습니다.</p>
<p>이 당시 가장 중요한 패러다임은 관점의 분리로서 Model과 View의 종속성을 최대한 분리하는 해야한다는 원칙으로 HTML과 jQuery를 따로 관리하는 것이 주효했습니다.  </p>
<h2 id="4-mvvm-패턴">4. MVVM 패턴</h2>
<p>그 다음 나온 아키텍처가 바로 MVVM이라는 아키텍처입니다.</p>
<p>jQuery로 작업을 하다보니 상당히 불편한 점을 발견하게 됩니다. 데이터를 찾아서 데이터를 바꾸고 데이터를 수정하고 이벤트를 연결하고 이벤트를 수정하는 부분들에서 피곤한 반복적인 패턴이 나타난다는 것을 알게 되었습니다.</p>
<p>서버에서 개발을 할 때에는 html이 전체적으로 렌더링으로 되다보니 {{ }}, <?= ?>, &lt;%= %&gt; 와 같은 치환자로 통해 선언적으로 편하게 개발을 하는 반면 jQuery의 경우 전체 html를 갱신했다가는 번쩍거리는 화면을 맛볼 수 있으니 수정해야 할 부분을 일일히 찾아서 수정을 해줘야 했습니다.</p>
<p>클라이언트 개발도 서버처럼 템플릿과 같은 선언적인 방식</p>
<p>Model이 변하면 View를 수정하고 View에서 이벤트를 받아서 Model를 변경한다는 Controller의 역할은 그대로 인데 이를 구현하는 방식이 jQuery와 같은 DOM 조작에서 템플릿과 바인딩을 통한 선언적인 방법으로 변하게 됩니다.</p>
<p>이제는 코드에서 DOM을 조작하는 코드가 사라지고 이 기능들은 프레임워크가 담당하게 됩니다. 이제 개발자는 화면에 그려져야할 데이터만 만들어서 프레임워크에 전달해주면 프레임워크가 알아서 그려줍니다.</p>
<p>이를 View를 그리는 Model만 다루게 되었다는 의미로 ViewModel이라고 부르며 이 방식을 MVVM이라고 부르게 됩니다.</p>
<p>이후 나오는 프레임워크인 React, Vue, Angular2, Svelte등 어떤 방식의 템플릿과 바인딩 문법을 쓰느냐 방식만 다를 뿐 MVVM이라는 아키텍쳐는 그대로 유지되게 됩니다.</p>
<blockquote>
<ul>
<li>MVC에서 MVVM으로 오면서 달라진 부분<br>컨트롤러의 반복적인 기능이 선언적인 방식으로 개선이 되었다.
Model과 View의 관점을 분리하려 하지 않고 하나의 템플릿으로 관리하려는 방식으로 발전했다. (기존에는 class나 id등으로 간접적으로 HTML에 접근하려고 했다면 이제는 직접적으로 HTML에 접근하는 방법으로 확장이 되었다.)  </li>
</ul>
</blockquote>
<p>MVVM을 얻은 웹 프론트엔드 개발은 그야말로 무시무시한 생산성의 변화를 맞이하게 됩니다. 웹의 DOM API를 잘 다루지 못하더라도 비지니스로직에만 집중한다면 금방 금방 서비스를 만들 수가 있게 되었습니다.  </p>
<hr>
<h2 id="결론">결론</h2>
<h3 id="그동안-frontend-프로그래밍을-하면서-객체지향을-겪어보지-못했을까">그동안 frontend 프로그래밍을 하면서 객체지향을 겪어보지 못했을까?</h3>
<p>경험상 component driven development, event driven programming에서는 프로토타입, class 기반 객체지향 둘 다 쓸일이 없었다.
굳이 class를 사용해본 것이라고는  </p>
<ul>
<li>error boundary 사용을 위한 class형 컴포넌트 사용</li>
<li>http통신시 statful한 class 객체 활용 in 횡단 관심사</li>
</ul>
<p>독특한 상황 뿐이였다.  </p>
<p>특히, React를 함수형 컴포넌트로 개발을 해왔기 때문에 클래스형 컴포넌트의 상태와 생명주기 객체지향을 제대로 겪지 못했다고 생각한다. 함수형 컴포넌트는 객체지향 프로그래밍보다는 함수형 프로그래밍에 가깝다고 한다.  </p>
<h3 id="다음-3가지-경우의-적합한-디자인-패턴-주관적-결론짓기">다음 3가지 경우의 적합한 디자인 패턴 주관적 결론짓기</h3>
<blockquote>
<ol>
<li>cli programming in vanila javascript</li>
<li>event driven programming in vanila javascript</li>
<li>react(component driven development, event driven programming)</li>
</ol>
</blockquote>
<blockquote>
<ol>
<li>cli-programming에서는 고전 mvc패턴을 선택할 것 같다. 
첫번째로는, 몇 안되게 알고있는 패턴중에 MVVM이 있는데 이것은 브라우저 환경이 기본적으로 갖쳐줘야 하기 때문에 소거된다. DOM을 기반으로 데이터를 전달하면 알아서 그려줄 ViewModel 의미를 갖춘 프레임워크이 존재할 수 없다.<br>jQuery 시절의 MVC 패턴도 소거된다. 마찬가지로 브라우저 환경이 아니므로 서버와 클라이언트가 구분져있지 않기 때문에 HTTP통신 자체가 없으며, 특징적으로 자체적 model을 가지게 된다. 따라서 고전의 MVC패턴을 사용하도록 한다.
모든 과제에 단정짓기는 어려우나 일반적으로, cli-programming에서 객체지향 디자인을 원칙을 함께 요구하기에, oop를 중요시하고 Model과 View간의 의존관계를 최소화하여 데이터수정에 영향을 미치지 않도록 mvc패턴을 적용시키도록 하려한다.  </li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li>브라우저 환경에서 web2.0 ajax라는 기술이 존재하기 때문에 cli-programming에는 존재하지 않는 프론트엔드의 역할에 집중하도록 한다. (주로 todo-list나 타이머 과제)</li>
</ol>
</blockquote>
<ul>
<li>Model: 서버의 DB는 REST API와 ajax HTTP 통신을 통해 접근한다.</li>
<li>View: DOM Traversal and Manipluation과 Event Handling이 중요하겠다.  </li>
<li>Controller: 과거의 MVC에서 controller는 라우터의 역할 뿐이였지만, web2.0부터는 사용자로부터 event 감지하는 브라우저 역할이 controller라고 생각한다. </li>
</ul>
<blockquote>
<ol start="3">
<li>react를 사용하면 DOM 조작을 하기 보다는, model을 수정하면 자동으로 view를 수정해주는 방식을 사용하는 ViewModel의 MVVM패턴을 사용하게 된다. 나아가 Page단위가 아닌 컴포넌트 단위인 Component 패턴을 사용하여 컴포넌트를 재사용하는 방식으로 프로그래밍을 진행할 것이다. Component 패턴에서 심화된 Container-Presenter 패턴을 사용하다 Props Driliing이 심하게 되어 필요시 FLUX패턴을 사용하게 될 것 같다.</li>
</ol>
</blockquote>
<hr>
<h2 id="참고">참고</h2>
<p><a href="https://velog.io/@teo/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%97%90%EC%84%9C-MV-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94#observer-observable-pattern">velog/@teo - 프론트엔드에서 MV* 아키텍쳐란 무엇인가요?</a></p>
]]></description>
        </item>
    </channel>
</rss>